feat: added connected chain ad sound into timer
This commit is contained in:
35
client/src/composables/chainTimer.ts
Normal file
35
client/src/composables/chainTimer.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { TypeTimer } from '@/types/timerType';
|
||||
import { getTimer } from '@/db/crud/timerCrud';
|
||||
|
||||
|
||||
/** Фомирует цепочку таймеров */
|
||||
export async function queueTimer(TimerId: number): Promise<TypeTimer[]> {
|
||||
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;
|
||||
}
|
||||
@@ -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<number>(0);
|
||||
const timerNow = ref<TypeTimer | undefined>(timers.shift());
|
||||
|
||||
if (timerNow.value) {
|
||||
totalSeconds.value = timerNow.value.time * 60;
|
||||
}
|
||||
|
||||
/** Реактивное оставшееся время в секундах */
|
||||
const timeLeft = ref<number>(totalSeconds);
|
||||
const timeLeft = ref<number>(totalSeconds.value);
|
||||
|
||||
/** Флаг активного состояния таймера */
|
||||
const isRunning = ref<boolean>(false);
|
||||
|
||||
let interval: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
/** Форматирует оставшееся время в строку ЧЧ:ММ:СС */
|
||||
/** Форматирует оставшееся время в строку ЧЧ:ММ:СС или сообщение о прохождении таймера */
|
||||
const formatted = computed<string>(() => {
|
||||
const hours = Math.floor(timeLeft.value / 3600);
|
||||
const mins = Math.floor((timeLeft.value % 3600) / 60);
|
||||
const secs = timeLeft.value % 60;
|
||||
|
||||
if (timerNow.value) {
|
||||
return `${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
return "Завершён!";
|
||||
});
|
||||
|
||||
/** Вычисляет процент прошедшего времени от общего */
|
||||
const progress = computed<number>(() => {
|
||||
return ((totalSeconds - timeLeft.value) / totalSeconds) * 100;
|
||||
if (totalSeconds.value === 0) return 0;
|
||||
|
||||
return ((totalSeconds.value - timeLeft.value) / totalSeconds.value) * 100;
|
||||
});
|
||||
|
||||
/** Отслеживает завершённость таймера */
|
||||
const isFinished = computed<boolean>(() => {
|
||||
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
|
||||
|
||||
@@ -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<TypeTimer | undefined>;
|
||||
isFinished: ComputedRef<boolean>;
|
||||
}
|
||||
|
||||
/** Тип таймеров */
|
||||
export type TypeTimer = {
|
||||
title: string;
|
||||
time: number;
|
||||
typeTimer: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user