- 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
117 lines
2.9 KiB
TypeScript
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
|
|
}
|
|
}
|