Files
binome/src/hooks/useTimer.ts
Julien Calixte 8887cdbf88 chore: upgrade tooling stack
- TypeScript 3.9 -> 5.8
- ESLint 6 -> 9 (flat config)
- Prettier 1 -> 3
- eslint-plugin-vue 6 -> 9
- Add vue-tsc for type checking
- Migrate Sass @import to @use syntax
- Fix Pinia persistence config for v4
- Add Spotify type declarations
- Remove unused registerServiceWorker.ts
2026-01-24 21:36:43 +01:00

117 lines
2.9 KiB
TypeScript

import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { StopwatchState } from '@/types/StopwatchState'
import { notify } from '@/utils/notification'
import { useInterval } from './useInterval'
import { useWakeLock } from './useWakeLock'
import i18n from '@/i18n'
import { useMainStore } from '@/store'
const toggleSound = new Audio('/sound/toggle.mp3')
const format = (num: number) => {
return num.toString().padStart(2, '0')
}
const formatSeconds = (seconds: number) => {
const minutes = Math.floor(seconds / 60)
const secs = seconds % 60
return `${format(minutes)}:${format(secs)}`
}
export const useTimer = () => {
const { askWakeLockPermission, releaseWakeLock } = useWakeLock()
const store = useMainStore()
const timeState = ref<StopwatchState>('stopped')
const seconds = ref(0)
const { interval } = useInterval()
const sessionSeconds = ref(interval.value * 60)
const isDev1Turn = ref(true)
const time = computed(() => formatSeconds(seconds.value))
const session = computed(() => formatSeconds(sessionSeconds.value))
const intervalSeconds = computed(() => interval.value * 60)
let stopwatchId: ReturnType<typeof setInterval> | null = null
let stopWatchSessionId: ReturnType<typeof setInterval> | null = null
watch(interval, () => {
sessionSeconds.value = interval.value * 60
})
const start = () => {
askWakeLockPermission()
timeState.value = 'started'
stopwatchId = setInterval(() => {
seconds.value++
const isTimeToChange = seconds.value % intervalSeconds.value === 0
if (isTimeToChange) {
sessionSeconds.value = intervalSeconds.value
isDev1Turn.value = !isDev1Turn.value
const dev = isDev1Turn.value ? store.dev1 : store.dev2
toggleSound.play()
notify(i18n.global.t('notification.change.title'), {
body: i18n.global.t('notification.change.body', { dev })
})
}
}, 1000)
stopWatchSessionId = setInterval(() => {
sessionSeconds.value--
}, 1000)
}
const pause = () => {
releaseWakeLock()
timeState.value = 'stopped'
if (stopwatchId) {
clearInterval(stopwatchId)
stopwatchId = null
}
if (stopWatchSessionId) {
clearInterval(stopWatchSessionId)
stopWatchSessionId = null
}
}
const clear = () => {
pause()
seconds.value = 0
sessionSeconds.value = intervalSeconds.value
isDev1Turn.value = true
}
const handleSpacebar = (event: KeyboardEvent) => {
if (event.target !== document.body) {
return
}
if (event.charCode === 32) {
timeState.value === 'started' ? pause() : start()
}
}
onMounted(() => {
window.addEventListener('keypress', handleSpacebar)
})
onUnmounted(() => {
window.removeEventListener('keypress', handleSpacebar)
})
return {
interval,
start,
pause,
clear,
timeState,
time,
session,
isDev1Turn
}
}