import { useEffect, useRef } from 'react'; import { View, Animated, Easing, StyleSheet } from 'react-native'; import { UserAvatar } from '../UserAvatar'; import { useColors } from '../../lib/theme'; import { useThemeStore } from '../../stores/theme'; /** * In-Thread Typing-Indicator (Instagram-Style): Partner-Avatar links + graue * Bubble mit drei wellenartig auf-/abspringenden Punkten. Erscheint als * ListFooter unter der letzten Nachricht, solange der Partner tippt. * * Bubble-Styling spiegelt die eingehende ChatBubble (cleanBg): hellgrau im * Light-Mode (#EFEFF1), dunkel im Dark-Mode (#2c2c2e). */ function WaveDots({ color }: { color: string }) { const dots = useRef([new Animated.Value(0), new Animated.Value(0), new Animated.Value(0)]).current; useEffect(() => { const loops = dots.map((d, i) => Animated.loop( Animated.sequence([ Animated.delay(i * 140), Animated.timing(d, { toValue: 1, duration: 300, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), Animated.timing(d, { toValue: 0, duration: 300, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), Animated.delay((dots.length - 1 - i) * 140), ]), ), ); loops.forEach((l) => l.start()); return () => loops.forEach((l) => l.stop()); }, [dots]); return ( {dots.map((d, i) => ( ))} ); } export function TypingBubble({ userId, avatar, nickname, }: { userId: string | null; avatar: string | null; nickname: string; }) { const colors = useColors(); const colorScheme = useThemeStore((s) => s.colorScheme); const bubbleBg = colorScheme === 'dark' ? '#2c2c2e' : '#EFEFF1'; return ( ); } const styles = StyleSheet.create({ row: { flexDirection: 'row', paddingHorizontal: 10, marginTop: 8, alignItems: 'flex-end', }, avatarSlot: { width: 32, marginRight: 6, justifyContent: 'flex-end', }, bubble: { paddingHorizontal: 14, height: 34, justifyContent: 'center', borderTopLeftRadius: 14, borderTopRightRadius: 14, borderBottomLeftRadius: 4, borderBottomRightRadius: 14, shadowColor: '#000', shadowOpacity: 0.08, shadowRadius: 3, shadowOffset: { width: 0, height: 1 }, elevation: 1, }, bubbleBorder: { borderWidth: StyleSheet.hairlineWidth, borderColor: 'rgba(0,0,0,0.06)', }, dotsRow: { flexDirection: 'row', alignItems: 'center', gap: 4, }, dot: { width: 7, height: 7, borderRadius: 3.5, }, });