import { useEffect, useRef } from "react"; import { Animated, Easing, type StyleProp, type ViewStyle } from "react-native"; import { useReduceMotion } from "../lib/reduce-motion"; export interface HeartbeatDotProps { size?: number; color?: string; style?: StyleProp; } // Q-4:未讀/推播提示紅點=小心跳,對應 apps/web 的 `.heartbeat-dot`(1.2s 循環的 opacity+scale 脈動)。 export function HeartbeatDot({ size = 10, color = "#FF7E9D", style }: HeartbeatDotProps) { const reduceMotion = useReduceMotion(); const t = useRef(new Animated.Value(0)).current; useEffect(() => { if (reduceMotion) { t.setValue(0); return; } const loop = Animated.loop( Animated.sequence([ Animated.timing(t, { toValue: 1, duration: 600, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), Animated.timing(t, { toValue: 0, duration: 600, easing: Easing.inOut(Easing.ease), useNativeDriver: true }), ]), ); loop.start(); return () => loop.stop(); }, [reduceMotion, t]); const scale = t.interpolate({ inputRange: [0, 1], outputRange: [1, 1.3] }); const opacity = t.interpolate({ inputRange: [0, 1], outputRange: [1, 0.7] }); return ( ); }