|
|
|
@@ -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,29 +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: sofort nach unten
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (messages.length > lastMessageCount.current && shouldAutoScroll.current) {
|
|
|
|
|
// Kurzer Delay damit FlatList rendern kann
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
flatListRef.current?.scrollToEnd({ animated: messages.length > lastMessageCount.current + 1 ? false : true });
|
|
|
|
|
}, 150);
|
|
|
|
|
}
|
|
|
|
|
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> => {
|
|
|
|
@@ -680,13 +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}
|
|
|
|
|
ListEmptyComponent={
|
|
|
|
|
<View style={styles.emptyContainer}>
|
|
|
|
|
<Text style={styles.emptyIcon}>{'\uD83E\uDD16'}</Text>
|
|
|
|
|