109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
// src/composables/useTimer.ts
|
|
import { ref } from 'vue';
|
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
|
|
|
export function useTimer(audioUrl: string = '/resource/notification.mp3') {
|
|
const timerMinutes = ref(25);
|
|
const timerSeconds = ref(0);
|
|
const remainingTime = ref(25 * 60 * 1000);
|
|
const timerRunning = ref(false);
|
|
const timerIsOver = ref(false);
|
|
const audioActivated = ref(false);
|
|
|
|
let timerInterval: number;
|
|
const audio = new Audio(audioUrl);
|
|
|
|
const clear = () => {
|
|
clearInterval(timerInterval);
|
|
timerRunning.value = false;
|
|
};
|
|
|
|
const syncDisplay = (durationMs: number) => {
|
|
const safeDuration = Math.max(durationMs, 0);
|
|
remainingTime.value = safeDuration;
|
|
timerMinutes.value = Math.floor(safeDuration / 1000 / 60);
|
|
timerSeconds.value = Math.floor((safeDuration / 1000) % 60);
|
|
timerIsOver.value = safeDuration === 0;
|
|
};
|
|
|
|
const handleCountdownComplete = () => {
|
|
audio.loop = true;
|
|
audio.play();
|
|
ElMessageBox.alert('本次番茄钟结束!请点击“休息”按钮开始休息倒计时', '提醒', {
|
|
confirmButtonText: '关闭铃声',
|
|
callback: () => {
|
|
audio.pause();
|
|
audio.currentTime = 0;
|
|
ElMessage.success('铃声已关闭');
|
|
},
|
|
});
|
|
};
|
|
|
|
const runCountdown = (durationMs: number, onComplete: () => void = handleCountdownComplete) => {
|
|
clearInterval(timerInterval);
|
|
const endTimeStamp = Date.now() + durationMs;
|
|
remainingTime.value = durationMs;
|
|
timerIsOver.value = false;
|
|
timerRunning.value = true;
|
|
|
|
timerInterval = window.setInterval(() => {
|
|
const now = Date.now();
|
|
remainingTime.value = Math.max(endTimeStamp - now, 0);
|
|
timerMinutes.value = Math.floor(remainingTime.value / 1000 / 60);
|
|
timerSeconds.value = Math.floor((remainingTime.value / 1000) % 60);
|
|
|
|
if (remainingTime.value === 0 && !timerIsOver.value) {
|
|
timerIsOver.value = true;
|
|
timerRunning.value = false;
|
|
onComplete();
|
|
}
|
|
}, 1000);
|
|
};
|
|
|
|
const checkAudioPermission = async () => {
|
|
try {
|
|
await audio.play();
|
|
audio.pause();
|
|
audio.currentTime = 0;
|
|
audioActivated.value = true;
|
|
return true;
|
|
} catch {
|
|
audioActivated.value = false;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
const requestAudioPermission = () => {
|
|
return new Promise<boolean>((resolve) => {
|
|
ElMessageBox.alert('点击确认激活提示音权限。', '权限激活', {
|
|
confirmButtonText: '确认',
|
|
callback: async () => {
|
|
try {
|
|
await audio.play();
|
|
audio.pause();
|
|
audio.currentTime = 0;
|
|
audioActivated.value = true;
|
|
resolve(true);
|
|
} catch {
|
|
resolve(false);
|
|
}
|
|
},
|
|
});
|
|
});
|
|
};
|
|
|
|
return {
|
|
timerMinutes,
|
|
timerSeconds,
|
|
remainingTime,
|
|
timerRunning,
|
|
timerIsOver,
|
|
runCountdown,
|
|
syncDisplay,
|
|
clear,
|
|
checkAudioPermission,
|
|
requestAudioPermission,
|
|
audioActivated,
|
|
};
|
|
}
|