Skip to content

Commit e91293d

Browse files
author
tfomkin
committed
fix: improved auto scroll behavior while response is generating
1 parent 2a9bca9 commit e91293d

1 file changed

Lines changed: 23 additions & 5 deletions

File tree

  • libs/mobile/chat/features/chat/src/lib/components/messages-list

libs/mobile/chat/features/chat/src/lib/components/messages-list/component.tsx

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { FlashList } from '@shopify/flash-list';
22
import { useLocalSearchParams } from 'expo-router';
33
import { delay } from 'lodash-es';
44
import React, { ReactElement, useCallback, useRef } from 'react';
5-
import { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
5+
import { GestureResponderEvent, NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
66
import { useSharedValue, withTiming } from 'react-native-reanimated';
77
import { AiMessageActions } from '@open-webui-react-native/mobile/chat/features/ai-message-actions';
88
import { useManageMessageSiblings } from '@open-webui-react-native/mobile/chat/features/use-manage-messages-siblings';
@@ -62,7 +62,8 @@ 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 isNearBottomRef = useRef(true);
65+
const shouldAutoscrollToBottomRef = useRef(true);
66+
const previousTouchY = useRef(0);
6667

6768
const { showPreviousSibling, showNextSibling, getSiblingsInfo } = useManageMessageSiblings(chatId, history);
6869
const { mutate: completeChat } = chatApi.useCompleteChat();
@@ -80,7 +81,7 @@ export default function ChatMessagesList({
8081
isScrollToBottomAvailable.current = true;
8182
}, 500);
8283

83-
if (isNearBottomRef.current && listRef.current && messages?.length > 0) {
84+
if (shouldAutoscrollToBottomRef.current) {
8485
requestAnimationFrame(() => {
8586
listRef.current?.scrollToEnd({ animated: true });
8687
});
@@ -114,7 +115,6 @@ export default function ChatMessagesList({
114115
//NOTE: The indent of 100 is needed to display the button not immediately when we start scrolling,
115116
//but when a small distance has been scrolled.
116117
const isNearBottom = scrollY + containerHeight >= contentHeight - 100;
117-
isNearBottomRef.current = isNearBottom;
118118

119119
if (isNearBottom || isScrollingUp) {
120120
animateScrollToBottom(0);
@@ -127,7 +127,6 @@ export default function ChatMessagesList({
127127
//NOTE: Needs to hide scroll to bottom button to avoid its jumping while scrolling to bottom
128128
animateScrollToBottom(0);
129129
isScrollToBottomAvailable.current = false;
130-
isNearBottomRef.current = true;
131130

132131
delay(() => {
133132
isScrollToBottomAvailable.current = true;
@@ -176,6 +175,23 @@ export default function ChatMessagesList({
176175
onFollowUpPress(text);
177176
};
178177

178+
const handleTouchStart = (e: GestureResponderEvent): void => {
179+
if (!isResponseGenerating) return;
180+
181+
shouldAutoscrollToBottomRef.current = false;
182+
previousTouchY.current = e.nativeEvent.pageY;
183+
};
184+
185+
const handleTouchMove = (e: GestureResponderEvent): void => {
186+
if (!isResponseGenerating) return;
187+
188+
const { pageY } = e.nativeEvent;
189+
const deltaY = pageY - previousTouchY.current;
190+
191+
previousTouchY.current = pageY;
192+
shouldAutoscrollToBottomRef.current = deltaY < 0;
193+
};
194+
179195
const renderItem = useCallback(
180196
({ item, index }: { item: Message; index: number }) => {
181197
const message = history?.messages[item.id];
@@ -253,6 +269,8 @@ export default function ChatMessagesList({
253269
}}
254270
onContentSizeChange={handleContentSizeChange}
255271
onScroll={handleScroll}
272+
onTouchStart={handleTouchStart}
273+
onTouchMove={handleTouchMove}
256274
scrollEventThrottle={16}
257275
/>
258276
<ChatBottomButton isVisible={isScrollToBottomVisible} onPress={scrollToBottom} />

0 commit comments

Comments
 (0)