fix: Correct chat scroll behavior for both sort modes

Add scrollToLatestMessage helper that respects sortNewestFirst setting:
- When newest first: scroll to top (offset 0)
- When oldest first: scroll to end

Applied to keyboard show, voice messages, and content size changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Sergei 2026-01-24 20:57:23 -08:00
parent 45ac102157
commit fa5d4ffb23

View File

@ -476,18 +476,29 @@ export default function ChatScreen() {
autoSelect(); autoSelect();
}, []); }, []);
// Scroll to end when keyboard shows // Helper function to scroll to the latest message based on sort mode
const scrollToLatestMessage = useCallback((animated = true) => {
if (sortNewestFirst) {
// When newest first, latest messages are at top (index 0)
flatListRef.current?.scrollToOffset({ offset: 0, animated });
} else {
// When oldest first, latest messages are at bottom
flatListRef.current?.scrollToEnd({ animated });
}
}, [sortNewestFirst]);
// Scroll to latest when keyboard shows
useEffect(() => { useEffect(() => {
const keyboardShowListener = Keyboard.addListener( const keyboardShowListener = Keyboard.addListener(
Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow', Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow',
() => { () => {
setTimeout(() => { setTimeout(() => {
flatListRef.current?.scrollToEnd({ animated: true }); scrollToLatestMessage(true);
}, 100); }, 100);
} }
); );
return () => keyboardShowListener.remove(); return () => keyboardShowListener.remove();
}, []); }, [scrollToLatestMessage]);
const openBeneficiaryPicker = useCallback(() => { const openBeneficiaryPicker = useCallback(() => {
setShowBeneficiaryPicker(true); setShowBeneficiaryPicker(true);
@ -588,14 +599,14 @@ export default function ChatScreen() {
setMessages(prev => [...prev, voiceMessage]); setMessages(prev => [...prev, voiceMessage]);
// Scroll to bottom // Scroll to latest message (respects sort mode)
setTimeout(() => { setTimeout(() => {
flatListRef.current?.scrollToEnd({ animated: true }); scrollToLatestMessage(true);
}, 100); }, 100);
// Also store in transcript context for persistence // Also store in transcript context for persistence
addTranscriptEntry(role, text); addTranscriptEntry(role, text);
}, [hasShownVoiceSeparator, addTranscriptEntry]); }, [hasShownVoiceSeparator, addTranscriptEntry, scrollToLatestMessage]);
// Cached API token for WellNuo // Cached API token for WellNuo
const apiTokenRef = useRef<string | null>(null); const apiTokenRef = useRef<string | null>(null);
@ -887,9 +898,7 @@ export default function ChatScreen() {
contentContainerStyle={styles.messagesList} contentContainerStyle={styles.messagesList}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
onContentSizeChange={() => { onContentSizeChange={() => {
if (!sortNewestFirst) { scrollToLatestMessage(true);
flatListRef.current?.scrollToEnd({ animated: true });
}
}} }}
/> />