refactor: rewrite timer logic

This commit is contained in:
MAZE 2024-04-30 16:53:49 +03:30
parent dc139e41e6
commit 7c57fb686b

View file

@ -1,4 +1,4 @@
import { useEffect, useState, useCallback, useRef } from 'react'; import { useEffect, useState, useRef, useMemo } from 'react';
import { Modal } from '@/components/modal'; import { Modal } from '@/components/modal';
import { Timer } from '@/components/timer'; import { Timer } from '@/components/timer';
@ -13,57 +13,59 @@ interface SleepTimerModalProps {
} }
export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) { export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) {
const [running, setRunning] = useState(false);
const [hours, setHours] = useState<string>('0'); const [hours, setHours] = useState<string>('0');
const [minutes, setMinutes] = useState<string>('10'); const [minutes, setMinutes] = useState<string>('10');
const [running, setRunning] = useState(false);
const [timeLeft, setTimeLeft] = useState(0);
const timerId = useRef<NodeJS.Timeout>(); const totalSeconds = useMemo(
() =>
(hours === '' ? 0 : parseInt(hours)) * 3600 +
(minutes === '' ? 0 : parseInt(minutes)) * 60,
[hours, minutes],
);
const [timeSpent, setTimeSpent] = useState(0);
const timeLeft = useMemo(
() => totalSeconds - timeSpent,
[totalSeconds, timeSpent],
);
const timerId = useRef<ReturnType<typeof setInterval>>();
const isPlaying = useSoundStore(state => state.isPlaying); const isPlaying = useSoundStore(state => state.isPlaying);
const play = useSoundStore(state => state.play); const play = useSoundStore(state => state.play);
const pause = useSoundStore(state => state.pause); const pause = useSoundStore(state => state.pause);
const calculateTotalSeconds = useCallback((): number => {
return (
(hours === '' ? 0 : parseInt(hours)) * 3600 +
(minutes === '' ? 0 : parseInt(minutes)) * 60
);
}, [minutes, hours]);
useEffect(() => {
setTimeLeft(calculateTotalSeconds());
}, [calculateTotalSeconds]);
const handleStart = () => { const handleStart = () => {
if (timerId.current) clearInterval(timerId.current); if (timerId.current) clearInterval(timerId.current);
if (!isPlaying) play(); if (!isPlaying) play();
setTimeLeft(calculateTotalSeconds); if (totalSeconds > 0) {
if (timeLeft > 0) {
setRunning(true); setRunning(true);
const newTimerId = setInterval(() => { const newTimerId = setInterval(() => {
setTimeLeft(prevTimeLeft => { setTimeSpent(prev => prev + 1);
const newTimeLeft = prevTimeLeft - 1;
if (newTimeLeft <= 0) {
clearInterval(newTimerId);
pause();
setRunning(false);
return 0;
}
return newTimeLeft;
});
}, 1000); }, 1000);
timerId.current = newTimerId; timerId.current = newTimerId;
} }
}; };
useEffect(() => {
if (timeLeft === 0) {
setRunning(false);
pause();
setTimeSpent(0);
if (timerId.current) clearInterval(timerId.current);
}
}, [timeLeft, pause]);
const handleReset = () => { const handleReset = () => {
if (timerId.current) clearInterval(timerId.current); if (timerId.current) clearInterval(timerId.current);
setTimeLeft(0); setTimeSpent(0);
setHours('0'); setHours('0');
setMinutes('10'); setMinutes('10');
setRunning(false); setRunning(false);
@ -114,7 +116,7 @@ export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) {
className={cn(styles.button, styles.primary)} className={cn(styles.button, styles.primary)}
type="submit" type="submit"
> >
Save Start
</button> </button>
)} )}
</div> </div>