You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.7 KiB
63 lines
1.7 KiB
import React, { useEffect, useRef, useState } from "react";
|
|
import { Animated, Text, TouchableOpacity, View } from "react-native";
|
|
|
|
export default function LinearProgressBar({ duration = 10 }) {
|
|
const [timeLeft, setTimeLeft] = useState(duration);
|
|
const [isRunning, setIsRunning] = useState(false);
|
|
const progress = useRef(new Animated.Value(0)).current;
|
|
const intervalRef = useRef(null);
|
|
|
|
const startAnimation = () => {
|
|
setIsRunning(true);
|
|
progress.setValue(0);
|
|
setTimeLeft(duration);
|
|
|
|
Animated.timing(progress, {
|
|
toValue: 1,
|
|
duration: duration * 1000,
|
|
useNativeDriver: false,
|
|
}).start(() => setIsRunning(false));
|
|
|
|
//@ts-ignore
|
|
intervalRef.current = setInterval(() => {
|
|
setTimeLeft((prev) => (prev > 0 ? prev - 1 : 0));
|
|
}, 1000);
|
|
};
|
|
|
|
useEffect(() => {
|
|
//@ts-ignore
|
|
return () => clearInterval(intervalRef.current);
|
|
}, []);
|
|
|
|
const progressWidth = progress.interpolate({
|
|
inputRange: [0, 1],
|
|
outputRange: ["0%", "100%"],
|
|
});
|
|
|
|
return (
|
|
<View className="w-full p-4 items-center">
|
|
<Text className="text-center mb-2 color-white font-extrabold">
|
|
Temps restant : {timeLeft}s
|
|
</Text>
|
|
<View className="w-full h-4 bg-gray-200 rounded-full overflow-hidden mb-4">
|
|
<Animated.View
|
|
style={{ width: progressWidth }}
|
|
className="h-full bg-orange-400"
|
|
/>
|
|
</View>
|
|
|
|
<TouchableOpacity
|
|
onPress={startAnimation}
|
|
disabled={isRunning}
|
|
className={`px-4 py-2 rounded-full ${
|
|
isRunning ? "bg-orange-400" : "bg-orange-400"
|
|
}`}
|
|
>
|
|
<Text className="text-white font-bold">
|
|
{isRunning ? "En cours..." : "Play"}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
}
|