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,
}),
])
}