Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
a9c721d
chore: update to Expo SDK 54
Dec 12, 2025
0d97195
fix: use expo legacy filesystem
Dec 12, 2025
6770436
fix: upsert folder sheet crash fix, reanimated version fix, type erro…
Dec 16, 2025
0e9afa5
fix: bottom sheet paddings and types fix
Dec 16, 2025
104a456
fix: types fix
Dec 16, 2025
4b0b253
fix: metro version fix
Dec 16, 2025
a5d1ba2
fix: added missing dependency
Dec 16, 2025
60638ca
fix: android padding fixes
Dec 16, 2025
46cc35b
fix: reset chat list scroll position when refresh completes
Dec 22, 2025
8771fbc
fix: reset scroll position only after auto refresh
Dec 24, 2025
8d5fbdf
fix: limit AI message socket-updates to once per frame
Dec 24, 2025
37d54e2
fix: trigger loading indicator only when screen is focused
Dec 25, 2025
2b4a271
Merge pull request #22 from RonasIT/PRD-2113-chat-completion-event-op…
veliseev93 Dec 26, 2025
7f7bab4
chore: replaced useFocusEffect with useIsFocused
Dec 26, 2025
bbebc0f
fix: edge-to-edge, 3-button-navigation bar bottom paddings fix
Dec 26, 2025
867e64f
fix: ios paddings fix
Dec 26, 2025
99741f7
fix: unnecessary fadeIn 50ms animation removed
Dec 28, 2025
5d963b9
Merge pull request #18 from RonasIT/PRD-2109-chat-list-loading-indica…
veliseev93 Dec 29, 2025
b001ab9
Merge pull request #25 from RonasIT/PRD-2126-create-chat-crash-fix
veliseev93 Dec 29, 2025
d58daf5
Merge pull request #24 from RonasIT/PRD-2110-Android-layout-fix
veliseev93 Dec 29, 2025
f30aeec
feat: follow up messages functionality
Dec 29, 2025
e6dbce5
Merge branch 'development' into PRD-2080-Expo-SDK-54
Dec 29, 2025
4235062
fix: image modal layout fix
Jan 6, 2026
ccdf8e7
Merge pull request #27 from RonasIT/PRD-2110-android-image-modal-layo…
veliseev93 Jan 7, 2026
e24fea2
fix: push instead of replace during chat create navigation
Jan 7, 2026
e910e62
Merge pull request #28 from RonasIT/PRD-2126-chat-creation-navigation…
veliseev93 Jan 8, 2026
34c3153
fix: clear stored api url and remove persisting storage on logout
Jan 8, 2026
1e1a1bb
chore: removed unnecessary api url storage deletion on logout
Jan 8, 2026
9ae69c6
fix: normalize url
Jan 8, 2026
3ece87c
Merge pull request #30 from RonasIT/PRD-2137-API-URL-trailing-slash-fix
veliseev93 Jan 8, 2026
1d8978f
Merge pull request #29 from RonasIT/PRD-2136-app-crashes-on-API-URL-c…
veliseev93 Jan 8, 2026
1f97954
fix: followUpGeneration enabled in backgroundTasksConfig
Jan 8, 2026
54f4763
fix: ui fixes
Jan 8, 2026
fbb8594
Merge pull request #11 from RonasIT/PRD-2080-Expo-SDK-54
veliseev93 Jan 9, 2026
e875e25
fix: horizontal padding added
Jan 9, 2026
6ad2a6b
chore: replaced @pietile-native-kit/keyboard-aware-scrollview with re…
Jan 9, 2026
2968076
Merge pull request #26 from RonasIT/PRD-2120-follow-up-messages
veliseev93 Jan 10, 2026
ba67f7f
feat: added a chat actions sheet to the chat screen
Jan 15, 2026
2ee3557
fix: added extra origin header for websocket
Jan 15, 2026
8352092
Merge pull request #33 from RonasIT/PRD-2143-add-websocket-extra-headers
veliseev93 Jan 15, 2026
fa0b498
Merge branch 'development' into PRD-2141-add-chat-actions-to-chat-screen
Jan 15, 2026
f2ec752
fix: isInChat prop usage fix
Jan 15, 2026
d97eec5
Merge branch 'development' into PRD-2132-keyboard-controllers-refacto…
Jan 15, 2026
ae300f0
fix: create, sign-in screens safe area edges fix
Jan 15, 2026
574e132
fix: knowledge sheet paddings fixed
Jan 15, 2026
47fc01a
fix: get knowledge response handling fix
Jan 15, 2026
4d0c136
Merge pull request #31 from RonasIT/PRD-2132-keyboard-controllers-ref…
veliseev93 Jan 16, 2026
609ee2c
Merge pull request #32 from RonasIT/PRD-2141-add-chat-actions-to-chat…
veliseev93 Jan 16, 2026
8d73f11
Merge pull request #34 from RonasIT/PRD-2154-knowledge-sheet-styling-fix
veliseev93 Jan 16, 2026
626cd98
fix: CodeBlock background color fix
Jan 16, 2026
0fd57ee
fix: removed AppMarkDownView restProps spread to prevent key leakage
Jan 18, 2026
866192e
fix: loading condition fix
Jan 18, 2026
7d6327e
Merge pull request #36 from RonasIT/PRD-2141-add-chat-actions-to-chat…
veliseev93 Jan 19, 2026
1912e26
fix: use GestureAppPressable instead of AppPressable for modals IconB…
Jan 22, 2026
056d58d
fix: created a separate component for GesturePressableIconButton
Jan 22, 2026
58e9622
fix: use platform specific icon button components
Jan 22, 2026
23bc296
Merge pull request #37 from RonasIT/PRD-2157-modal-close-button-behav…
veliseev93 Jan 23, 2026
684f960
fix: props fix, a key prop is being spread into JSX error fix
Jan 23, 2026
b9a85f8
Merge branch 'development' into PRD-2152-incorrect-chat-block-color-fix
Jan 23, 2026
c823612
fix: chat branches siblings ordering fix
Jan 23, 2026
cb4f617
Merge pull request #38 from RonasIT/PRD-2156-chat-branches-ordering-fix
veliseev93 Jan 26, 2026
d65d74b
Merge pull request #35 from RonasIT/PRD-2152-incorrect-chat-block-col…
veliseev93 Jan 26, 2026
76d4b49
chore: release v1.2.0
Jan 29, 2026
463b841
chore: dev build number updated
Jan 29, 2026
5a732f5
chore: dev build number updated
Jan 29, 2026
df9613c
Merge pull request #40 from RonasIT/release-1.2.0
veliseev93 Feb 2, 2026
323eff6
Merge pull request #42 from RonasIT/development
veliseev93 Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ExpoConfig } from '@expo/config';
import { EASConfig } from 'expo-constants/build/Constants.types';
import { EASConfig } from 'expo-manifests';
import { AppEnv } from '../../libs/shared/utils/app-env/src/env';
import { AppEnvName } from '../../libs/shared/utils/app-env/src/app-env';
import { compact } from 'lodash-es';
Expand Down Expand Up @@ -27,10 +27,10 @@ const createConfig = (): Omit<ExpoConfig, 'extra'> & { extra: { eas: EASConfig }
slug: process.env.EXPO_PUBLIC_APP_SLUG as string,
scheme: process.env.EXPO_PUBLIC_APP_SCHEME as string,
owner: process.env.EXPO_PUBLIC_APP_OWNER as string,
version: '1.1.0',
version: '1.2.0',
orientation: 'portrait',
icon: './assets/icon.png',
runtimeVersion: '1.1.0',
runtimeVersion: '1.2.0',
experiments: {
reactCompiler: true,
},
Expand All @@ -41,8 +41,8 @@ const createConfig = (): Omit<ExpoConfig, 'extra'> & { extra: { eas: EASConfig }
bundleIdentifier: appId,
supportsTablet: false,
buildNumber: appEnv.select({
default: '13',
production: '7',
default: '18',
production: '8',
}),
config: {
usesNonExemptEncryption: false,
Expand All @@ -51,8 +51,8 @@ const createConfig = (): Omit<ExpoConfig, 'extra'> & { extra: { eas: EASConfig }
android: {
package: appId,
versionCode: appEnv.select({
default: 13,
production: 7,
default: 15,
production: 8,
}),
adaptiveIcon: {
foregroundImage: './assets/adaptive-icon.png',
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/app/(auth)/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function SignInScreen(): ReactElement {
const isOfflineMode = useSelector(appState$.isOfflineMode);

return (
<ScreenWrapper isKeyboardAvoiding>
<ScreenWrapper isKeyboardAvoiding safeAreaProps={{ edges: ['top'] }}>
<NoConnectionBanner isVisible={isOfflineMode} />
<SignIn onSuccess={resetToCreateChatScreen} />
</ScreenWrapper>
Expand Down
97 changes: 65 additions & 32 deletions apps/mobile/app/(main)/chat/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { useSelector } from '@legendapp/state/react';
import { Chat } from '@open-webui-react-native/mobile/chat/features/chat';
import {
ChatActionsMenuSheet,
ChatActionsMenuSheetMethods,
} from '@open-webui-react-native/mobile/shared/features/chat-actions-menu-sheet';
import { useSetSelectedModel } from '@open-webui-react-native/mobile/shared/features/use-set-selected-model';
import { NoConnectionBanner } from '@open-webui-react-native/mobile/shared/ui/no-connection-banner';
import { cn } from '@open-webui-react-native/mobile/shared/ui/styles';
Expand All @@ -10,28 +14,41 @@ import {
AppText,
Icon,
FullScreenSearchModal,
AppKeyboardControllerView,
IconButton,
} from '@open-webui-react-native/mobile/shared/ui/ui-kit';
import { ChatScreenParams, useInitialNavigation } from '@open-webui-react-native/mobile/shared/utils/navigation';
import { modelsApi } from '@open-webui-react-native/shared/data-access/api';
import {
ChatScreenParams,
navigationConfig,
useInitialNavigation,
} from '@open-webui-react-native/mobile/shared/utils/navigation';
import { chatApi, modelsApi } from '@open-webui-react-native/shared/data-access/api';
import { appState$ } from '@open-webui-react-native/shared/data-access/app-state';
import { useNavigateOnce } from '@open-webui-react-native/shared/utils/navigation';
import { useTranslation } from '@ronas-it/react-native-common-modules/i18n';
import { useNavigationContainerRef, usePathname, useLocalSearchParams, router } from 'expo-router';
import { ReactElement, useCallback } from 'react';
import { ReactElement, useCallback, useRef } from 'react';

export default function ChatScreen(): ReactElement {
const translate = useTranslation('CHAT.CHAT_SCREEN');
const path = usePathname();
const rootNavigation = useNavigationContainerRef();
const { id, isNewChat }: ChatScreenParams = useLocalSearchParams();
const { resetToChatsListScreen } = useInitialNavigation();
const navigateOnce = useNavigateOnce();
const chatActionsSheetRef = useRef<ChatActionsMenuSheetMethods>(null);
const navigateToClonedChat = (id: string): void => navigateOnce(navigationConfig.main.chat.view({ id }));

const isOfflineMode = useSelector(appState$.isOfflineMode);

const { data: models, isLoading } = modelsApi.useGetModels();
const { data: models, isLoading: isModelsLoading } = modelsApi.useGetModels();
const { data: chat, isLoading: isChatLoading } = chatApi.useGet(id);
const { modelId, modelName, onSelectModel } = useSetSelectedModel(id);

const handleGoBackPress = (): void => router.back();

const isLoading = isChatLoading || isModelsLoading;

const handleResetToChatsList = useCallback((): void => {
if (path.includes(id)) {
resetToChatsListScreen();
Expand All @@ -48,34 +65,50 @@ export default function ChatScreen(): ReactElement {
);

return (
<AppScreen
className={cn(isOfflineMode && 'pt-20')}
noOutsideSpacing
header={
<AppHeader
title={
modelId || isLoading ? (
<FullScreenSearchModal
data={models || []}
renderTrigger={renderTrigger}
selectedItemId={modelId}
onSelectItem={onSelectModel}
searchPlaceholder={translate('TEXT_SELECT_A_MODEL')}
<AppKeyboardControllerView className='bg-background-primary'>
<AppScreen
className={cn(isOfflineMode && 'pt-20')}
noOutsideSpacing
header={
<AppHeader
title={
isLoading && !modelId ? (
translate('TEXT_LOADING')
) : (
<FullScreenSearchModal
data={models || []}
renderTrigger={renderTrigger}
selectedItemId={modelId}
onSelectItem={onSelectModel}
searchPlaceholder={translate('TEXT_SELECT_A_MODEL')}
/>
)
}
onGoBack={handleGoBackPress}
accessoryRight={
<IconButton
className='p-0'
iconName='moreDots'
onPress={() => {
if (!chat) return;
chatActionsSheetRef.current?.present(chat);
}}
/>
) : (
translate('TEXT_LOADING')
)
}
onGoBack={handleGoBackPress}
/>
}
scrollDisabled>
<NoConnectionBanner isVisible={isOfflineMode} />
<Chat
chatId={id}
isNewChat={!!isNewChat}
selectedModelId={modelId}
resetToChatsList={handleResetToChatsList} />
</AppScreen>
}
/>
}
scrollDisabled>
<NoConnectionBanner isVisible={isOfflineMode} />
<Chat
chatId={id}
isNewChat={!!isNewChat}
selectedModelId={modelId}
resetToChatsList={handleResetToChatsList} />
<ChatActionsMenuSheet
ref={chatActionsSheetRef}
goToChat={navigateToClonedChat}
isInChat />
</AppScreen>
</AppKeyboardControllerView>
);
}
2 changes: 1 addition & 1 deletion apps/mobile/app/(main)/chat/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function ChatLayout(): ReactElement {
close: async () => await voiceModeModalRef.current?.close(),
};

const handleChatCreated = (id: string): void => router.replace(navigationConfig.main.chat.view({ id }));
const handleChatCreated = (id: string): void => router.push(navigationConfig.main.chat.view({ id }));

return (
<VoiceModeModalContext.Provider value={contextValue}>
Expand Down
11 changes: 8 additions & 3 deletions apps/mobile/app/(main)/chat/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ import { appState$ } from '@open-webui-react-native/shared/data-access/app-state
import { useTranslation } from '@ronas-it/react-native-common-modules/i18n';
import { router } from 'expo-router';
import { ReactElement, useRef } from 'react';
import { Keyboard, InteractionManager } from 'react-native';

export default function CreateChatScreen(): ReactElement {
const translate = useTranslation('CHAT.CREATE_CHAT');
const upsertFolderSheetRef = useRef<UpsertFolderSheetMethods>(null);

const handleChatCreated = (id: string): void =>
router.replace(navigationConfig.main.chat.view({ id, isNewChat: 'true' }));
const handleChatCreated = (id: string): void => {
Keyboard.dismiss();
InteractionManager.runAfterInteractions(() => {
router.push(navigationConfig.main.chat.view({ id, isNewChat: 'true' }));
});
};

const openCreateFolderModal = (): void => upsertFolderSheetRef.current?.present();

Expand All @@ -41,7 +46,7 @@ export default function CreateChatScreen(): ReactElement {
className: 'pt-0',
header: <AppHeader title={translate('TEXT_NEW_CHAT')} onGoBack={handleBackPress} />,
}}
safeAreaProps={{ edges: ['bottom'] }}
safeAreaProps={{ edges: [] }}
keyBoardAvoidingProps={{ enabled: !isBottomSheetInputFocused }}>
<NoConnectionBanner isVisible={isOfflineMode} />
<CreateChat
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/app/(main)/chat/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function ChatListScreen(): ReactElement {

return (
<ScreenWrapper safeAreaProps={{ edges: [] }} screenProps={{ noOutsideSpacing: true, scrollDisabled: true }}>
<View className='flex-1 bg-background-primary mt-safe'>
<View className='flex-1 bg-background-primary ios:mt-safe'>
<AppHeader
className='mt-0'
title={translate('TEXT_CHATS')}
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function App(): ReactElement | null {

return (
<View className='bg-background-primary flex-1'>
<StatusBar className='bg-background-primary' />
<StatusBar className='bg-background-primary' translucent />
<Stack>
<Stack.Screen name='index' options={{ headerShown: false, contentStyle: { backgroundColor: 'transparent' } }} />
<Stack.Screen name={navigationConfig.auth.root} options={{ headerShown: false }} />
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ module.exports = function (api) {
'nativewind/babel',
],
plugins: [
'react-native-reanimated/plugin',
[
'module-resolver',
{
Expand All @@ -23,6 +22,7 @@ module.exports = function (api) {
},
},
],
'react-native-worklets/plugin',
],
};
};
71 changes: 34 additions & 37 deletions apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,58 +29,55 @@
"@react-native-community/netinfo": "11.4.1",
"@react-native-cookies/cookies": "^6.2.1",
"@react-native-google-signin/google-signin": "^15.0.0",
"@react-navigation/drawer": "^7.4.1",
"@react-navigation/drawer": "^7.3.9",
"@ronas-it/react-native-common-modules": "^1.1.0",
"@ronas-it/rtkq-entity-api": "^0.4.10",
"@shopify/flash-list": "^2.0.0-rc.11",
"@shopify/flash-list": "2.0.2",
"@tanstack/react-query": "^5.80.6",
"@tanstack/react-query-persist-client": "^5.87.4",
"@testing-library/jest-native": "*",
"@testing-library/react-native": "*",
"babel-plugin-module-resolver": "^5.0.2",
"clsx": "^2.1.1",
"expo": "53.0.11",
"expo-asset": "~11.1.7",
"expo-audio": "~0.4.9",
"expo-clipboard": "~7.1.5",
"expo-constants": "~17.1.6",
"expo-crypto": "~14.1.5",
"expo-dev-client": "^5.0.6",
"expo-document-picker": "~13.1.6",
"expo-file-system": "~18.1.11",
"expo-haptics": "~14.1.4",
"expo-image": "~2.4.0",
"expo-image-picker": "~16.1.4",
"expo-insights": "~0.9.3",
"expo-linear-gradient": "~14.1.5",
"expo-linking": "~7.1.5",
"expo-localization": "~16.1.5",
"expo-media-library": "~17.1.7",
"expo-router": "~5.0.7",
"expo-sharing": "~13.1.5",
"expo-speech": "~13.1.7",
"expo-splash-screen": "~0.30.10",
"expo-status-bar": "^2.0.0",
"expo-updates": "~0.28.13",
"expo": "^54.0.0",
"expo-asset": "~12.0.11",
"expo-audio": "~1.1.0",
"expo-clipboard": "~8.0.8",
"expo-constants": "~18.0.12",
"expo-crypto": "~15.0.8",
"expo-dev-client": "~6.0.20",
"expo-document-picker": "~14.0.8",
"expo-file-system": "~19.0.21",
"expo-haptics": "~15.0.8",
"expo-image": "~3.0.11",
"expo-image-picker": "~17.0.10",
"expo-insights": "~0.10.8",
"expo-linear-gradient": "~15.0.8",
"expo-linking": "~8.0.10",
"expo-localization": "~17.0.8",
"expo-media-library": "~18.2.1",
"expo-router": "~6.0.19",
"expo-sharing": "~14.0.8",
"expo-speech": "~14.0.8",
"expo-splash-screen": "~31.0.12",
"expo-status-bar": "~3.0.9",
"expo-updates": "~29.0.15",
"immer": "^10.1.1",
"lodash-es": "^4.17.21",
"luxon": "^3.6.1",
"metro-config": "*",
"nativewind": "^4.1.23",
"react": "19.0.0",
"react": "19.1.0",
"react-hook-form": "^7.57.0",
"react-native": "*",
"react-native": "0.81.5",
"react-native-compressor": "^1.12.0",
"react-native-extended-stylesheet": "^0.12.0",
"react-native-gesture-handler": "~2.24.0",
"react-native-keyboard-controller": "^1.17.5",
"react-native-gesture-handler": "~2.28.0",
"react-native-keyboard-controller": "1.18.5",
"react-native-mmkv": "^3.2.0",
"react-native-modal": "^14.0.0-rc.1",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.10.0",
"react-native-svg": "*",
"react-native-web": "*",
"react-native-reanimated": "~4.1.1",
"react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.16.0",
"react-native-svg": "15.12.1",
"react-native-web": "^0.21.0",
"reflect-metadata": "^0.2.2",
"tailwind-merge": "^3.3.0",
"tailwindcss": "^3.4.17",
Expand Down
3 changes: 3 additions & 0 deletions i18n/mobile/chat/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@
"TEXT_LISTENING": "Listening...",
"TEXT_THINKING": "Thinking...",
"TEXT_TALKING": "Talking..."
},
"MESSAGE_FOLLOW_UPS": {
"TEXT_FOLLOW_UP": "Follow up"
}
}
}
1 change: 1 addition & 0 deletions i18n/mobile/folder/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"TEXT_UNSUPPORTED_TYPE": "Unsupported type."
},
"SELECT_KNOWLEDGE_SHEET": {
"TEXT_SEARCH_KNOWLEDGE": "Search knowledge",
"TEXT_SELECT_KNOWLEDGE": "Select Knowledge",
"TEXT_NO_KNOWLEDGE": "There is no knowledge."
}
Expand Down
Loading
Loading