import React, { useEffect } from 'react' import { StyleSheet, View, Animated } from 'react-native' import { useTheme } from '../../hooks' import { useTypingIndicators, getTypingIndicatorText } from '../../hooks/use_typing_indicators' import { Text } from '../display' /** * Animated dots to indicate typing */ const TypingDots = () => { const styles = useStyles() // Create animated values for each dot const dot1Opacity = React.useRef(new Animated.Value(0.3)).current const dot2Opacity = React.useRef(new Animated.Value(0.3)).current const dot3Opacity = React.useRef(new Animated.Value(0.3)).current // Animation sequence for dots useEffect(() => { Animated.loop( Animated.parallel([ animateDot(dot1Opacity, 0), animateDot(dot2Opacity, 200), animateDot(dot3Opacity, 400), ]) ).start() return () => { dot1Opacity.stopAnimation() dot2Opacity.stopAnimation() dot3Opacity.stopAnimation() } }, [dot1Opacity, dot2Opacity, dot3Opacity]) return ( ) } /** * Component to display typing indicators in a conversation * Shows "X is typing..." with animated dots */ export const TypingIndicator = () => { const typingPeople = useTypingIndicators() const styles = useStyles() const enabled = typingPeople.length > 0 if (!typingPeople.length) return null return ( {enabled && } {getTypingIndicatorText(typingPeople)} ) } const useStyles = () => { const { colors } = useTheme() return StyleSheet.create({ relativeWrapper: { position: 'relative', }, container: { flexDirection: 'row', alignItems: 'center', padding: 8, backgroundColor: colors.fillColorNeutral090, position: 'absolute', bottom: 0, left: 0, right: 0, zIndex: 10, }, dotsContainer: { flexDirection: 'row', alignItems: 'center', marginRight: 8, }, dots: { width: 4, height: 4, borderRadius: 2, backgroundColor: colors.textColorDefaultSecondary, marginHorizontal: 2, }, text: { color: colors.textColorDefaultSecondary, }, }) } function animateDot(dot: Animated.Value, delay: number) { return Animated.sequence([ Animated.timing(dot, { toValue: 1, duration: 400, delay, useNativeDriver: true, }), Animated.timing(dot, { toValue: 0.3, duration: 400, useNativeDriver: true, }), ]) }