import { BMS_STATE_LABELS } from "@/constants/config"; import { BmsState } from "@/constants/types"; import React, { useEffect, useRef, useState } from "react"; import { View, StyleSheet, Text, Animated } from "react-native"; import Svg, { Circle, Defs, LinearGradient, Stop } from "react-native-svg"; import BatteryStatus from "./ChargingStateLabel"; const AnimatedCircle = Animated.createAnimatedComponent(Circle); const CircleProgressBar = ({ progress, status, }: { progress: number | null; status: -1 | 0 | 1 | null; }) => { const radius = 20; const strokeWidth = 5; const viewBoxPadding = 4; const viewBoxSize = (radius + strokeWidth) * 2 + viewBoxPadding; const center = viewBoxSize / 2; const circumference = 2 * Math.PI * radius; const animatedValue = useRef(new Animated.Value(0)).current; const [displayProgress, setDisplayProgress] = useState(0); useEffect(() => { if (progress === undefined) { animatedValue.setValue(0); setDisplayProgress(0); } else { Animated.timing(animatedValue, { toValue: progress ?? 0, duration: 500, useNativeDriver: false, }).start(); } }, [progress]); useEffect(() => { const listenerId = animatedValue.addListener(({ value }) => { setDisplayProgress(Math.round(value)); }); return () => animatedValue.removeListener(listenerId); }, []); const getColor = (progress: number) => { if (progress <= 20) return "#D51D10"; if (progress <= 50) return "#FF7B00"; return "#009E71"; }; const animatedColor = getColor(displayProgress); const dashOffset = animatedValue.interpolate({ inputRange: [0, 100], outputRange: [circumference, circumference - 0.7 * circumference], }); const progressDashArray = `${circumference} ${circumference}`; const backgroundDashArray = `${0.7 * circumference} ${0.3 * circumference}`; return ( {progress ? displayProgress : "---"} {progress == null ? "" : "%"} ); }; // Keep the styles the same as before const styles = StyleSheet.create({ container: { position: "relative", alignItems: "center", }, circleContainer: { transform: [{ rotate: "144deg" }], }, batteryPercent: { position: "absolute", top: 80, justifyContent: "center", alignItems: "baseline", display: "flex", flexDirection: "row", }, batterySoc: { position: "absolute", top: 210, justifyContent: "center", transform: [{ translateX: 0 }], }, batteryStatus: { position: "absolute", top: 300, justifyContent: "center", transform: [{ translateX: 0 }], }, }); export default CircleProgressBar;