import { useEffect, useState } from 'react'; import { useRoute, useNavigation } from '@react-navigation/native'; import { View } from '@/components/shared/Themed'; import styled from '@emotion/native'; import TimerContent from '@/components/useCases/timer/view/TimerContent'; import FinishContent from '@/components/useCases/timer/view/FinishContent'; import { TimerBgColor } from '@/components/useCases/timer/business/type'; import { Audio } from 'expo-av'; import { Sound } from 'expo-av/build/Audio'; import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake'; import { loadUserSettings } from '@/components/shared/business/AsyncStorage'; import BackgroundTimer from 'react-native-background-timer'; import { useAudio } from '@/components/useCases/timer/business/useAudio'; interface TimerProps { reps: number; restTime: number; workTime: number; } export default function Timer() { const navigation = useNavigation(); const route = useRoute(); const { reps, restTime, workTime } = route.params as TimerProps; const [currentRep, setCurrentRep] = useState(0); const [timeLeft, setTimeLeft] = useState(0); const [isWorkPhase, setIsWorkPhase] = useState(true); const [isRunning, setIsRunning] = useState(false); const [isFinish, setIsFinish] = useState(false); const [soundEnabled, setSoundEnabled] = useState(true); const { playSound } = useAudio(require('../assets/audios/boxingBell.mp3'), soundEnabled); useEffect(() => { const init = async () => { try { const soundEnabledLocal = await loadUserSettings('soundEnabled'); setSoundEnabled(Boolean(Number(soundEnabledLocal))); handleStart(); await activateKeepAwakeAsync(); } catch (error) { throw new Error('Erreur lors du chargement des paramètres utilisateur'); } }; init(); }, []); // when the user exits the screen, desactivate the keepAwake useEffect(() => { const unsubscribe = navigation.addListener('beforeRemove', (_) => { deactivateKeepAwake(); }); return unsubscribe; }, [navigation]); useEffect(() => { let timerId: number | null = null; if (isRunning && timeLeft > 0) { timerId = BackgroundTimer.setInterval(() => { setTimeLeft((prevTime) => prevTime - 1); }, 1000); } else if (isRunning && timeLeft === 0) { nextRep(); } return () => { if (timerId !== null) { BackgroundTimer.clearInterval(timerId); } }; }, [isRunning, timeLeft]); const handleStart = () => { setCurrentRep(1); setIsWorkPhase(true); setTimeLeft(workTime); setIsRunning(true); setIsFinish(false); }; const nextRep = () => { if (currentRep < reps) { if (isWorkPhase) { playSound(); setIsWorkPhase(false); setTimeLeft(restTime); } else { playSound(); setIsWorkPhase(true); setTimeLeft(workTime); setCurrentRep((prevRep) => prevRep + 1); } } else { playSound(); setIsFinish(true); setIsRunning(false); } }; const previousRep = () => { if (isWorkPhase) { if (currentRep > 1) { setIsWorkPhase(false); setTimeLeft(restTime); setCurrentRep((prevRep) => prevRep - 1); } } else { setIsWorkPhase(true); setTimeLeft(workTime); } }; const handleContine = () => { setIsRunning(true); }; const handleStop = () => { setIsRunning(false); }; const renderBgColor: () => TimerBgColor = () => { if (isFinish) return 'black'; if (isWorkPhase) return 'red'; return 'green'; } return ( {isFinish && ( )} {!isFinish && ( )} ); } const Container = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColor }) => ({ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: theme.colors[bgColor] }));