diff --git a/apps/mobile/app/(main)/chat/[id].tsx b/apps/mobile/app/(main)/chat/[id].tsx index 57ea1f5..b42b239 100644 --- a/apps/mobile/app/(main)/chat/[id].tsx +++ b/apps/mobile/app/(main)/chat/[id].tsx @@ -14,7 +14,6 @@ import { AppText, Icon, FullScreenSearchModal, - AppKeyboardControllerView, IconButton, } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; import { @@ -65,50 +64,48 @@ export default function ChatScreen(): ReactElement { ); return ( - - - ) - } - onGoBack={handleGoBackPress} - accessoryRight={ - { - if (!chat) return; - chatActionsSheetRef.current?.present(chat); - }} + - } - /> - } - scrollDisabled> - - - - - + ) + } + onGoBack={handleGoBackPress} + accessoryRight={ + { + if (!chat) return; + chatActionsSheetRef.current?.present(chat); + }} + /> + } + /> + } + scrollDisabled> + + + + ); } diff --git a/apps/mobile/package.json b/apps/mobile/package.json index a994a1a..dda6470 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -71,7 +71,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-mmkv": "^3.2.0", "react-native-modal": "^14.0.0-rc.1", "react-native-reanimated": "~4.1.1", diff --git a/libs/mobile/chat/features/chat/src/lib/component.tsx b/libs/mobile/chat/features/chat/src/lib/component.tsx index 1813a60..1c885f5 100644 --- a/libs/mobile/chat/features/chat/src/lib/component.tsx +++ b/libs/mobile/chat/features/chat/src/lib/component.tsx @@ -1,5 +1,4 @@ import { useSelector } from '@legendapp/state/react'; -import { useKeyboard } from '@react-native-community/hooks'; import { useTranslation } from '@ronas-it/react-native-common-modules/i18n'; import dayjs from 'dayjs'; import { delay } from 'lodash-es'; @@ -14,9 +13,8 @@ import { useSendMessage } from '@open-webui-react-native/mobile/chat/features/us import { useSuggestChange } from '@open-webui-react-native/mobile/chat/features/use-suggest-change'; import { useAttachedFiles } from '@open-webui-react-native/mobile/shared/features/use-attached-files'; import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; -import { AppSpinner, View } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; +import { AppKeyboardStickyView, AppSpinner, View } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; import { FormValues } from '@open-webui-react-native/mobile/shared/utils/form'; -import { useBottomInset } from '@open-webui-react-native/mobile/shared/utils/use-bottom-inset'; import { chatApi, ChatGenerationOption, chatQueriesKeys } from '@open-webui-react-native/shared/data-access/api'; import { Role } from '@open-webui-react-native/shared/data-access/common'; import { useSubscribeToQueryCache } from '@open-webui-react-native/shared/data-access/query-client'; @@ -38,8 +36,6 @@ interface ChatProps { export function Chat({ chatId, selectedModelId, isNewChat, resetToChatsList }: ChatProps): ReactElement { const translate = useTranslation('CHAT.CHAT'); const translateRegeneratePrompt = useTranslation('CHAT.AI_MESSAGE_ACTIONS.REGENERATE_MESSAGE_ACTION_SHEET'); - const bottomInset = useBottomInset(); - const { keyboardShown } = useKeyboard(); const [isInputFocusing, setIsInputFocusing] = useState(false); //NOTE: Needs to avoid ChatBottomButton jumping when auto-scrolling after focus @@ -225,47 +221,47 @@ export function Chat({ chatId, selectedModelId, isNewChat, resetToChatsList }: C /> )} - - {activeInputMode === ActiveInputMode.EDIT && editingMessageId ? ( - - ) : activeInputMode === ActiveInputMode.SUGGEST && suggestingMessageId ? ( - - ) : ( - - )} - + + + {activeInputMode === ActiveInputMode.EDIT && editingMessageId ? ( + + ) : activeInputMode === ActiveInputMode.SUGGEST && suggestingMessageId ? ( + + ) : ( + + )} + + ); } diff --git a/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx b/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx index 2ff66de..b3b71d9 100644 --- a/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx +++ b/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx @@ -13,7 +13,7 @@ export default function ChatBottomButton({ isVisible, onPress }: ChatBottomButto })); return ( - + , []); + const handleContentSizeChange = (): void => { //NOTE: Needs to wait until the initial scroll to the bottom or content generation finished and not show the ChatBottomButton before isScrollToBottomAvailable.current = false; @@ -89,11 +91,7 @@ export default function ChatMessagesList({ if (!isMessagesListLoaded && listRef.current && messages?.length > 0) { delay(() => { - listRef.current?.scrollToIndex({ - index: messages.length - 1, - animated: false, - viewPosition: 1, - }); + listRef.current?.scrollToEnd({ animated: false }); delay(onLayout, 125); }, 125); } @@ -261,7 +259,7 @@ export default function ChatMessagesList({ ref={listRef} - contentContainerClassName='pb-16 px-16' + contentContainerClassName='pb-[135] px-16' showsVerticalScrollIndicator={false} drawDistance={1500} //NOTE: Needs to avoid image jumping (while rerendering) when scrolling keyExtractor={(item) => item.id} @@ -272,6 +270,7 @@ export default function ChatMessagesList({ maintainVisibleContentPosition={{ startRenderingFromBottom: true, }} + renderScrollComponent={renderScrollComponent} onContentSizeChange={handleContentSizeChange} onScroll={handleScroll} onTouchStart={handleTouchStart} diff --git a/libs/mobile/shared/ui/ui-kit/src/index.ts b/libs/mobile/shared/ui/ui-kit/src/index.ts index 0e4305f..79bf826 100644 --- a/libs/mobile/shared/ui/ui-kit/src/index.ts +++ b/libs/mobile/shared/ui/ui-kit/src/index.ts @@ -39,6 +39,8 @@ export * from './header'; export * from './full-screen-modal'; export * from './sheet-header'; export * from './keyboard-aware-scroll-view'; +export * from './keyboard-chat-scroll-view'; +export * from './keyboard-sticky-view'; export * from './pressable-search-input'; export * from './full-screen-search-modal'; export * from './gesture-pressable-icon-button'; diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx new file mode 100644 index 0000000..37ae2b7 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx @@ -0,0 +1,34 @@ +import { cssInterop } from 'nativewind'; +import { ReactElement } from 'react'; +import { KeyboardChatScrollView, KeyboardChatScrollViewProps } from 'react-native-keyboard-controller'; +import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; + +const CustomizedKeyboardChatScrollView = cssInterop(KeyboardChatScrollView, { + className: 'style', + contentContainerClassName: 'contentContainerStyle', +}); + +type AppKeyboardChatScrollViewProps = KeyboardChatScrollViewProps & { + className?: string; + contentContainerClassName?: string; +}; + +export function AppKeyboardChatScrollView({ + className, + contentContainerClassName, + offset = 20, + automaticallyAdjustContentInsets = false, + contentInsetAdjustmentBehavior = 'never', + ...restProps +}: AppKeyboardChatScrollViewProps): ReactElement { + return ( + + ); +} diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts new file mode 100644 index 0000000..bb82484 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts @@ -0,0 +1 @@ +export * from './component'; diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx new file mode 100644 index 0000000..c5a2860 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx @@ -0,0 +1,30 @@ +import { AppSafeAreaView } from '@ronas-it/react-native-common-modules/safe-area-view'; +import { PropsWithChildren, ReactElement } from 'react'; +import { KeyboardStickyView, KeyboardStickyViewProps } from 'react-native-keyboard-controller'; +import { Edge } from 'react-native-safe-area-context'; +import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; + +type AppKeyboardStickyViewProps = PropsWithChildren< + KeyboardStickyViewProps & { + className?: string; + safeAreaEdges?: Array; + } +>; + +export function AppKeyboardStickyView({ + className, + offset = { opened: 20, closed: 0 }, + style, + children, + safeAreaEdges = ['bottom'], + ...restProps +}: AppKeyboardStickyViewProps): ReactElement { + return ( + + {children} + + ); +} diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts new file mode 100644 index 0000000..bb82484 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts @@ -0,0 +1 @@ +export * from './component'; diff --git a/package-lock.json b/package-lock.json index bfdd980..bacde44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,7 +80,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-markdown-display": "^7.0.2", "react-native-mathjax-svg": "^0.9.9", "react-native-mmkv": "^3.2.0", @@ -208,7 +208,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-mmkv": "^3.2.0", "react-native-modal": "^14.0.0-rc.1", "react-native-reanimated": "~4.1.1", @@ -27309,9 +27309,9 @@ } }, "node_modules/react-native-keyboard-controller": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/react-native-keyboard-controller/-/react-native-keyboard-controller-1.18.5.tgz", - "integrity": "sha512-wbYN6Tcu3G5a05dhRYBgjgd74KqoYWuUmroLpigRg9cXy5uYo7prTMIvMgvLtARQtUF7BOtFggUnzgoBOgk0TQ==", + "version": "1.21.8", + "resolved": "https://registry.npmjs.org/react-native-keyboard-controller/-/react-native-keyboard-controller-1.21.8.tgz", + "integrity": "sha512-fPpRb1DkG0mgjNdsVvwKTeEqbTdUymZ7ZEqe5kXPEhEjnvo+3BX3p4CBhg3dEzfonL/hGGSS1dBDMDjiQbAkBQ==", "license": "MIT", "dependencies": { "react-native-is-edge-to-edge": "^1.2.1" diff --git a/package.json b/package.json index ce71fd6..a5b795e 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-markdown-display": "^7.0.2", "react-native-mathjax-svg": "^0.9.9", "react-native-mmkv": "^3.2.0",