fix: Inverted FlatList - newest messages always visible at bottom
- No more scrollToEnd/scrollToIndex needed - FlatList inverted=true with reversed data - New messages appear at bottom automatically - User scrolls up to see history (natural chat behavior) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cff421bc53
commit
f80fe1df93
|
|
@ -5,7 +5,7 @@
|
|||
* Datei- und Kamera-Upload.
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
|
|
@ -369,42 +369,8 @@ const ChatScreen: React.FC = () => {
|
|||
return () => { if (saveTimer.current) clearTimeout(saveTimer.current); };
|
||||
}, [messages]);
|
||||
|
||||
// Auto-Scroll: immer zur letzten Nachricht springen
|
||||
const shouldAutoScroll = useRef(true);
|
||||
const lastMessageCount = useRef(0);
|
||||
|
||||
// Bei neuen Nachrichten oder App-Start: nach unten springen
|
||||
useEffect(() => {
|
||||
if (messages.length > 0 && shouldAutoScroll.current) {
|
||||
const isInitial = lastMessageCount.current === 0;
|
||||
const scrollToBottom = () => {
|
||||
try {
|
||||
flatListRef.current?.scrollToIndex({
|
||||
index: messages.length - 1,
|
||||
animated: !isInitial,
|
||||
viewPosition: 1, // 1 = Item am unteren Rand
|
||||
});
|
||||
} catch {
|
||||
// Fallback wenn Index nicht berechnet werden kann
|
||||
flatListRef.current?.scrollToEnd({ animated: !isInitial });
|
||||
}
|
||||
};
|
||||
const delays = isInitial ? [200, 500, 1000] : [150];
|
||||
for (const delay of delays) {
|
||||
setTimeout(scrollToBottom, delay);
|
||||
}
|
||||
}
|
||||
lastMessageCount.current = messages.length;
|
||||
}, [messages]);
|
||||
|
||||
const handleScrollBeginDrag = useCallback(() => {
|
||||
shouldAutoScroll.current = false;
|
||||
}, []);
|
||||
const handleScrollEndDrag = useCallback((e: any) => {
|
||||
const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
|
||||
const isAtBottom = contentOffset.y + layoutMeasurement.height >= contentSize.height - 50;
|
||||
shouldAutoScroll.current = isAtBottom;
|
||||
}, []);
|
||||
// Inverted FlatList: neueste Nachrichten unten, kein manuelles Scrollen noetig
|
||||
const invertedMessages = useMemo(() => [...messages].reverse(), [messages]);
|
||||
|
||||
// GPS-Position holen (optional)
|
||||
const getCurrentLocation = useCallback((): Promise<{ lat: number; lon: number } | null> => {
|
||||
|
|
@ -693,18 +659,12 @@ const ChatScreen: React.FC = () => {
|
|||
{/* Nachrichtenliste */}
|
||||
<FlatList
|
||||
ref={flatListRef}
|
||||
data={searchQuery ? messages.filter(m => m.text.toLowerCase().includes(searchQuery.toLowerCase())) : messages}
|
||||
inverted
|
||||
data={searchQuery ? messages.filter(m => m.text.toLowerCase().includes(searchQuery.toLowerCase())).reverse() : invertedMessages}
|
||||
keyExtractor={item => item.id}
|
||||
renderItem={renderMessage}
|
||||
contentContainerStyle={styles.messageList}
|
||||
showsVerticalScrollIndicator={false}
|
||||
onScrollBeginDrag={handleScrollBeginDrag}
|
||||
onScrollEndDrag={handleScrollEndDrag}
|
||||
onScrollToIndexFailed={(info) => {
|
||||
setTimeout(() => {
|
||||
flatListRef.current?.scrollToEnd({ animated: false });
|
||||
}, 200);
|
||||
}}
|
||||
ListEmptyComponent={
|
||||
<View style={styles.emptyContainer}>
|
||||
<Text style={styles.emptyIcon}>{'\uD83E\uDD16'}</Text>
|
||||
|
|
|
|||
Loading…
Reference in New Issue