54 lines
2.2 KiB
TypeScript

// Kleine Indikator-Komponenten für den SOS-Header / Chat:
// - ThinkingDots: 3 hüpfende Punkte ("Lyra denkt nach")
// - VoiceBars: animierte Balken für Sprach-Aktivität
import { useEffect, useRef } from 'react';
import { View, Animated, StyleSheet } from 'react-native';
export function ThinkingDots() {
const anim = useRef([new Animated.Value(0), new Animated.Value(0), new Animated.Value(0)]).current;
useEffect(() => {
const animations = anim.map((a, i) =>
Animated.loop(Animated.sequence([
Animated.delay(i * 160),
Animated.timing(a, { toValue: 1, duration: 300, useNativeDriver: true }),
Animated.timing(a, { toValue: 0, duration: 300, useNativeDriver: true }),
])),
);
animations.forEach((a) => a.start());
return () => animations.forEach((a) => a.stop());
}, []);
return (
<View style={st.thinkingRow}>
{anim.map((a, i) => (
<Animated.View key={i} style={[st.thinkingDot, { transform: [{ translateY: a.interpolate({ inputRange: [0, 1], outputRange: [0, -5] }) }] }]} />
))}
</View>
);
}
export function VoiceBars({ count, baseColor }: { count: number; baseColor: string }) {
const anims = useRef(Array.from({ length: count }, () => new Animated.Value(4))).current;
useEffect(() => {
const animations = anims.map((a, i) =>
Animated.loop(Animated.sequence([
Animated.timing(a, { toValue: 4 + Math.random() * 14, duration: 450 + (i % 5) * 80, useNativeDriver: false }),
Animated.timing(a, { toValue: 4, duration: 450 + (i % 5) * 80, useNativeDriver: false }),
])),
);
animations.forEach((a) => a.start());
return () => animations.forEach((a) => a.stop());
}, []);
return (
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 2, height: 20 }}>
{anims.map((a, i) => (
<Animated.View key={i} style={{ width: 2.5, height: a, borderRadius: 2, backgroundColor: baseColor, opacity: 0.75 }} />
))}
</View>
);
}
const st = StyleSheet.create({
thinkingRow: { flexDirection: 'row', gap: 4, paddingHorizontal: 4, paddingVertical: 2, alignItems: 'center' },
thinkingDot: { width: 7, height: 7, borderRadius: 3.5, backgroundColor: '#9ca3af' },
});