import { useEffect, useRef } from 'react'; import { Text, View, Animated, Easing } from 'react-native'; import { useTranslation } from 'react-i18next'; import { useOnlineUsers } from '../../hooks/useOnlineUsers'; import { useLastSeenBatch } from '../../hooks/useLastSeenBatch'; type Props = { userId: string; /** Partner tippt gerade → überschreibt Online/Last-Seen mit „schreibt …". */ typing?: boolean; }; const STATUS_COLOR = '#a3a3a3'; function formatLastSeen(ts: string, t: (key: string, opts?: Record) => string): string { const diff = Date.now() - new Date(ts).getTime(); if (diff < 60_000) return t('presence.just_now'); if (diff < 3_600_000) return t('presence.minutes_ago', { minutes: Math.floor(diff / 60_000) }); if (diff < 86_400_000) return t('presence.hours_ago', { hours: Math.floor(diff / 3_600_000) }); return t('presence.days_ago', { days: Math.floor(diff / 86_400_000) }); } /** Drei pulsierende Punkte (WA/Insta-Style) neben dem „schreibt"-Text. */ function TypingDots() { const dots = useRef([new Animated.Value(0.3), new Animated.Value(0.3), new Animated.Value(0.3)]).current; useEffect(() => { const loops = dots.map((d, i) => Animated.loop( Animated.sequence([ Animated.delay(i * 160), Animated.timing(d, { toValue: 1, duration: 320, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), Animated.timing(d, { toValue: 0.3, duration: 320, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), Animated.delay((dots.length - 1 - i) * 160), ]), ), ); loops.forEach((l) => l.start()); return () => loops.forEach((l) => l.stop()); }, [dots]); return ( {dots.map((d, i) => ( ))} ); } export function ChatHeaderStatus({ userId, typing }: Props) { const { t } = useTranslation(); // DM-Header zeigt den ECHTEN Presence-Status des Partners (wie WhatsApp) — // NICHT die following-gated `isOnline`-Variante aus dem Feed/Profil. Wer dir // schreibt, sieht ohnehin via Typing-Indicator dass du da bist. `onlineUserIds` // ist der rohe Presence-Set → updatet live über den Presence-Sync-Channel. const { onlineUserIds } = useOnlineUsers(); const online = onlineUserIds.has(userId); const lastSeenMap = useLastSeenBatch(online ? [] : [userId]); if (typing) { return ( {t('presence.typing')} ); } if (online) { // User-Wunsch: „Online"-Text zeigen, aber NICHT grün (Dot im Avatar reicht // als Farb-Signal). Neutraler `textMuted`-Grau-Ton. return ( {t('presence.online')} ); } const lastSeen = lastSeenMap[userId]; if (!lastSeen) return null; return ( {formatLastSeen(lastSeen, t)} ); }