11import { FlashList } from '@shopify/flash-list' ;
22import { useLocalSearchParams } from 'expo-router' ;
33import { delay } from 'lodash-es' ;
4- import React , { ReactElement , useCallback , useRef , useState } from 'react' ;
4+ import React , { ReactElement , useCallback , useRef } from 'react' ;
55import { NativeScrollEvent , NativeSyntheticEvent } from 'react-native' ;
66import { useSharedValue , withTiming } from 'react-native-reanimated' ;
77import { AiMessageActions } from '@open-webui-react-native/mobile/chat/features/ai-message-actions' ;
@@ -62,7 +62,7 @@ export default function ChatMessagesList({
6262 const isScrollToBottomAvailableTimeout = useRef < NodeJS . Timeout | null | number > ( null ) ; //NOTE: number needs to fix pipeline lint error
6363 const isScrollToBottomVisible = useSharedValue ( 0 ) ;
6464 const previousScrollY = useRef ( 0 ) ;
65- const [ autoscrollToBottomThreshold , setAutoscrollToBottomThreshold ] = useState < number | undefined > ( 1 ) ;
65+ const isNearBottomRef = useRef ( true ) ;
6666
6767 const { showPreviousSibling, showNextSibling, getSiblingsInfo } = useManageMessageSiblings ( chatId , history ) ;
6868 const { mutate : completeChat } = chatApi . useCompleteChat ( ) ;
@@ -80,6 +80,12 @@ export default function ChatMessagesList({
8080 isScrollToBottomAvailable . current = true ;
8181 } , 500 ) ;
8282
83+ if ( isNearBottomRef . current && listRef . current && messages ?. length > 0 ) {
84+ requestAnimationFrame ( ( ) => {
85+ listRef . current ?. scrollToEnd ( { animated : true } ) ;
86+ } ) ;
87+ }
88+
8389 if ( ! isMessagesListLoaded && listRef . current && messages ?. length > 0 ) {
8490 delay ( ( ) => {
8591 listRef . current ?. scrollToIndex ( {
@@ -108,6 +114,7 @@ export default function ChatMessagesList({
108114 //NOTE: The indent of 100 is needed to display the button not immediately when we start scrolling,
109115 //but when a small distance has been scrolled.
110116 const isNearBottom = scrollY + containerHeight >= contentHeight - 100 ;
117+ isNearBottomRef . current = isNearBottom ;
111118
112119 if ( isNearBottom || isScrollingUp ) {
113120 animateScrollToBottom ( 0 ) ;
@@ -120,6 +127,8 @@ export default function ChatMessagesList({
120127 //NOTE: Needs to hide scroll to bottom button to avoid its jumping while scrolling to bottom
121128 animateScrollToBottom ( 0 ) ;
122129 isScrollToBottomAvailable . current = false ;
130+ isNearBottomRef . current = true ;
131+
123132 delay ( ( ) => {
124133 isScrollToBottomAvailable . current = true ;
125134 } , 1000 ) ;
@@ -128,7 +137,6 @@ export default function ChatMessagesList({
128137 } ;
129138
130139 const handleEditPress = ( index : number , messageId : string , content : string ) : void => {
131- setAutoscrollToBottomThreshold ( undefined ) ;
132140 onEditPress ( messageId , content ) ;
133141 delay ( ( ) => {
134142 listRef . current ?. scrollToIndex ( {
@@ -137,9 +145,6 @@ export default function ChatMessagesList({
137145 animated : true ,
138146 } ) ;
139147 } , 500 ) ;
140- delay ( ( ) => {
141- setAutoscrollToBottomThreshold ( 1 ) ;
142- } , 1000 ) ;
143148 } ;
144149
145150 const handleContinueResponsePress = ( messageId : string ) : void => {
@@ -243,12 +248,6 @@ export default function ChatMessagesList({
243248 ItemSeparatorComponent = { ( ) => < View className = 'h-20' /> }
244249 data = { messages }
245250 renderItem = { renderItem }
246- // TODO: Add autoscrollToBottom logic when it implemented in lib
247- maintainVisibleContentPosition = { {
248- startRenderingFromBottom : true ,
249- animateAutoScrollToBottom : true ,
250- autoscrollToBottomThreshold,
251- } }
252251 onContentSizeChange = { handleContentSizeChange }
253252 onScroll = { handleScroll }
254253 scrollEventThrottle = { 16 }
0 commit comments