A React Native app for the ultimate thinking partner.
1import React, { useEffect, useRef } from 'react';
2import { View, Text, Animated, StyleSheet } from 'react-native';
3import { darkTheme, lightTheme } from '../theme';
4
5interface LiveStatusIndicatorProps {
6 status: string; // e.g., "thinking", "searching the web", "saying", "thought"
7 isDark?: boolean;
8}
9
10const LiveStatusIndicator: React.FC<LiveStatusIndicatorProps> = ({ status, isDark = true }) => {
11 const theme = isDark ? darkTheme : lightTheme;
12 const rainbowAnimValue = useRef(new Animated.Value(0)).current;
13
14 // Animate rainbow gradient
15 useEffect(() => {
16 rainbowAnimValue.setValue(0);
17 const animation = Animated.loop(
18 Animated.timing(rainbowAnimValue, {
19 toValue: 1,
20 duration: 3000,
21 useNativeDriver: false,
22 })
23 );
24 animation.start();
25 return () => animation.stop();
26 }, []);
27
28 // Special cases for past tense verbs (don't use "is")
29 const isPastTense = status === 'thought';
30 const displayText = isPastTense ? status : `is ${status}`;
31
32 return (
33 <View style={styles.container}>
34 <Text style={[styles.text, { color: theme.colors.text.primary }]}>(</Text>
35 <Animated.Text
36 style={[
37 styles.coText,
38 {
39 color: rainbowAnimValue.interpolate({
40 inputRange: [0, 0.2, 0.4, 0.6, 0.8, 1],
41 outputRange: ['#FF6B6B', '#FFD93D', '#6BCF7F', '#4D96FF', '#9D4EDD', '#FF6B6B']
42 })
43 }
44 ]}
45 >
46 co
47 </Animated.Text>
48 <Text style={[styles.text, { color: theme.colors.text.primary }]}> {displayText})</Text>
49 </View>
50 );
51};
52
53const styles = StyleSheet.create({
54 container: {
55 flexDirection: 'row',
56 alignItems: 'baseline',
57 paddingVertical: 4,
58 marginBottom: 12,
59 },
60 text: {
61 fontSize: 24,
62 fontFamily: 'Lexend_400Regular',
63 },
64 coText: {
65 fontSize: 24,
66 fontFamily: 'Lexend_700Bold',
67 },
68});
69
70export default React.memo(LiveStatusIndicator);