diff --git a/client/src/composables/chainTimer.ts b/client/src/composables/chainTimer.ts new file mode 100644 index 0000000..c883f4b --- /dev/null +++ b/client/src/composables/chainTimer.ts @@ -0,0 +1,35 @@ +import { TypeTimer } from '@/types/timerType'; +import { getTimer } from '@/db/crud/timerCrud'; + + +/** Фомирует цепочку таймеров */ +export async function queueTimer(TimerId: number): Promise { + let timers: TypeTimer[] = []; + + const result = await getTimer(TimerId); + const timerData = Array.isArray(result) ? result[0] : result; + + for (let i = 0; i < timerData.count_pomodoro; i++) { + timers.push({ + title: timerData.title, + time: timerData.pomodoro_time, + typeTimer: "Помидор" + }); + + if (i === timerData.count_pomodoro - 1) { + timers.push({ + title: timerData.title, + time: timerData.break_long_time, + typeTimer: "Перерывище" + }); + } else { + timers.push({ + title: timerData.title, + time: timerData.break_time, + typeTimer: "Перерыв" + }); + } + } + + return timers; +} diff --git a/client/src/composables/useTimer.ts b/client/src/composables/useTimer.ts index f373c03..8ca8484 100644 --- a/client/src/composables/useTimer.ts +++ b/client/src/composables/useTimer.ts @@ -1,31 +1,74 @@ import { ref, computed } from 'vue'; import { CountdownOptions, CountdownReturn } from '@/types/timerType'; +import { stopSound } from '@/composables/useAudio'; +import { TypeTimer } from '@/types/timerType'; + /** Composable для управления обратным отсчётом времени */ -export function useCountdown({ seconds, onFinish }: CountdownOptions): CountdownReturn { - const totalSeconds = seconds * 60; +export function useCountdown({ timers, onFinish }: CountdownOptions): CountdownReturn { + const totalSeconds = ref(0); + const timerNow = ref(timers.shift()); + + if (timerNow.value) { + totalSeconds.value = timerNow.value.time * 60; + } /** Реактивное оставшееся время в секундах */ - const timeLeft = ref(totalSeconds); + const timeLeft = ref(totalSeconds.value); /** Флаг активного состояния таймера */ const isRunning = ref(false); let interval: ReturnType | null = null; - /** Форматирует оставшееся время в строку ЧЧ:ММ:СС */ + /** Форматирует оставшееся время в строку ЧЧ:ММ:СС или сообщение о прохождении таймера */ const formatted = computed(() => { const hours = Math.floor(timeLeft.value / 3600); const mins = Math.floor((timeLeft.value % 3600) / 60); const secs = timeLeft.value % 60; - return `${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`; + + if (timerNow.value) { + return `${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`; + } + + return "Завершён!"; }); /** Вычисляет процент прошедшего времени от общего */ const progress = computed(() => { - return ((totalSeconds - timeLeft.value) / totalSeconds) * 100; + if (totalSeconds.value === 0) return 0; + + return ((totalSeconds.value - timeLeft.value) / totalSeconds.value) * 100; }); + /** Отслеживает завершённость таймера */ + const isFinished = computed(() => { + return !timerNow.value || timeLeft.value <= 0; + }); + + /** Задаёт следующий таймер */ + const setNextTimer = (): void => { + timerNow.value = timers.shift(); + + if (timerNow.value) { + totalSeconds.value = timerNow.value.time * 60; + timeLeft.value = totalSeconds.value; + } + }; + + //** Заканчивает таймер */ + const finish = (): void => { + if (interval) { + clearInterval(interval); + interval = null; + } + + isRunning.value = false; + timeLeft.value = 0; + + onFinish?.(); + }; + /** Запускает таймер */ const start = (): void => { if (isRunning.value) return @@ -35,20 +78,22 @@ export function useCountdown({ seconds, onFinish }: CountdownOptions): Countdown if (timeLeft.value > 0) { timeLeft.value--; } else { - stop(); - onFinish?.(); + finish(); } }, 1000); } - /** Останавливает таймер и сбрасывает время до начального */ + /** Останавливает таймер и сбрасывает время до следующего таймера */ const stop = (): void => { if (interval) { clearInterval(interval); interval = null; } + isRunning.value = false; - timeLeft.value = totalSeconds; + + stopSound(); + setNextTimer() } /** Приостанавливает таймер без сброса оставшегося времени */ @@ -64,8 +109,10 @@ export function useCountdown({ seconds, onFinish }: CountdownOptions): Countdown return { timeLeft, isRunning, + isFinished, formatted, progress, + timerNow, start, stop, pause diff --git a/client/src/types/timerType.ts b/client/src/types/timerType.ts index 9b8a5f9..151dec2 100644 --- a/client/src/types/timerType.ts +++ b/client/src/types/timerType.ts @@ -23,7 +23,7 @@ export type TimerRow = { /** Параметры инициализации обратного отсчёта */ export type CountdownOptions = { - seconds: number; + timers: TypeTimer[]; onFinish?: () => void; } @@ -36,4 +36,13 @@ export type CountdownReturn = { start: () => void; stop: () => void; pause: () => void; + timerNow: Ref; + isFinished: ComputedRef; +} + +/** Тип таймеров */ +export type TypeTimer = { + title: string; + time: number; + typeTimer: string; }