71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import React from "react";
|
|
import { Animated, StyleSheet, Text, View } from "react-native";
|
|
import { useEffect, useRef } from "react";
|
|
|
|
import { Colors } from "@/constants/colors";
|
|
import type { ConnectionStatus } from "@/context/TimmyContext";
|
|
|
|
const C = Colors.dark;
|
|
|
|
const STATUS_CONFIG: Record<ConnectionStatus, { color: string; label: string }> = {
|
|
connecting: { color: "#F59E0B", label: "Connecting" },
|
|
connected: { color: "#10B981", label: "Live" },
|
|
disconnected: { color: "#6B7280", label: "Offline" },
|
|
reconnecting: { color: "#F59E0B", label: "Reconnecting" },
|
|
error: { color: "#EF4444", label: "Error" },
|
|
};
|
|
|
|
export function ConnectionBadge({ status }: { status: ConnectionStatus }) {
|
|
const pulseAnim = useRef(new Animated.Value(1)).current;
|
|
|
|
useEffect(() => {
|
|
if (status === "connecting" || status === "reconnecting") {
|
|
const pulse = Animated.loop(
|
|
Animated.sequence([
|
|
Animated.timing(pulseAnim, { toValue: 0.3, duration: 600, useNativeDriver: true }),
|
|
Animated.timing(pulseAnim, { toValue: 1, duration: 600, useNativeDriver: true }),
|
|
])
|
|
);
|
|
pulse.start();
|
|
return () => pulse.stop();
|
|
} else {
|
|
pulseAnim.setValue(1);
|
|
}
|
|
}, [status]);
|
|
|
|
const config = STATUS_CONFIG[status];
|
|
|
|
return (
|
|
<View style={styles.badge}>
|
|
<Animated.View
|
|
style={[styles.dot, { backgroundColor: config.color, opacity: pulseAnim }]}
|
|
/>
|
|
<Text style={[styles.label, { color: config.color }]}>{config.label}</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
badge: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
gap: 5,
|
|
backgroundColor: C.surface,
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 4,
|
|
borderRadius: 20,
|
|
borderWidth: 1,
|
|
borderColor: C.border,
|
|
},
|
|
dot: {
|
|
width: 6,
|
|
height: 6,
|
|
borderRadius: 3,
|
|
},
|
|
label: {
|
|
fontSize: 11,
|
|
fontFamily: "Inter_500Medium",
|
|
letterSpacing: 0.5,
|
|
},
|
|
});
|