// 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((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, }; }