1+ import { parseTimeString } from '@slidev/parser/utils'
12import { useInterval } from '@vueuse/core'
23import { computed , toRef } from 'vue'
4+ import { configs } from '../env'
35import { sharedState } from '../state/shared'
46
57export function useTimer ( ) {
8+ const mode = computed ( ( ) => configs . timer || 'stopwatch' )
9+ const duration = computed ( ( ) => parseTimeString ( configs . duration ) . seconds )
610 const interval = useInterval ( 100 , { controls : true } )
711
8- const state = toRef ( sharedState , 'timerStatus' )
9- const timer = computed ( ( ) => {
10- if ( sharedState . timerStatus === 'stopped' && sharedState . timerStartedAt === 0 )
11- return { h : '' , m : '-' , s : '--' , ms : '-' }
12+ const state = toRef ( sharedState , 'timer' )
13+ const status = computed ( ( ) => state . value ?. status )
14+ const passedMs = computed ( ( ) => {
1215 // eslint-disable-next-line ts/no-unused-expressions
1316 interval . counter . value
14- const passed = ( Date . now ( ) - sharedState . timerStartedAt )
15- let h = Math . floor ( passed / 1000 / 60 / 60 ) . toString ( )
17+ if ( state . value . status === 'stopped' || ! state . value . startedAt )
18+ return 0
19+ return Date . now ( ) - state . value . startedAt
20+ } )
21+ const passed = computed ( ( ) => passedMs . value / 1000 )
22+ const percentage = computed ( ( ) => passed . value / duration . value * 100 )
23+
24+ const timer = computed ( ( ) => {
25+ if ( mode . value === 'stopwatch' ) {
26+ if ( state . value . status === 'stopped' || ! state . value . startedAt )
27+ return { h : '' , m : '-' , s : '--' , ms : '-' }
28+ }
29+
30+ const total = mode . value === 'countdown'
31+ ? duration . value * 1000 - passedMs . value
32+ : passedMs . value
33+
34+ let h = Math . floor ( total / 1000 / 60 / 60 ) . toString ( )
1635 if ( h === '0' )
1736 h = ''
18- let min = Math . floor ( passed / 1000 / 60 % 60 ) . toString ( )
37+ let min = Math . floor ( total / 1000 / 60 % 60 ) . toString ( )
1938 if ( h )
2039 min = min . padStart ( 2 , '0' )
21- const sec = Math . floor ( passed / 1000 % 60 ) . toString ( ) . padStart ( 2 , '0' )
22- const ms = Math . floor ( passed % 1000 / 100 ) . toString ( )
23- return { h, m : min , s : sec , ms }
40+ const sec = Math . floor ( total / 1000 % 60 ) . toString ( ) . padStart ( 2 , '0' )
41+ const ms = Math . floor ( total % 1000 / 100 ) . toString ( )
42+
43+ return {
44+ h,
45+ m : min ,
46+ s : sec ,
47+ ms,
48+ }
2449 } )
2550
2651 function reset ( ) {
2752 interval . pause ( )
28- sharedState . timerStatus = 'stopped'
29- sharedState . timerStartedAt = 0
30- sharedState . timerPausedAt = 0
53+ state . value = {
54+ status : 'stopped' ,
55+ slides : { } ,
56+ startedAt : 0 ,
57+ pausedAt : 0 ,
58+ }
3159 }
3260
3361 function resume ( ) {
34- if ( sharedState . timerStatus === 'stopped' ) {
35- sharedState . timerStatus = 'running'
36- sharedState . timerStartedAt = Date . now ( )
62+ if ( ! state . value )
63+ return
64+ if ( state . value ?. status === 'stopped' ) {
65+ state . value . status = 'running'
66+ state . value . startedAt = Date . now ( )
3767 }
38- else if ( sharedState . timerStatus === 'paused' ) {
39- sharedState . timerStatus = 'running'
40- sharedState . timerStartedAt = Date . now ( ) - ( sharedState . timerPausedAt - sharedState . timerStartedAt )
68+ else if ( state . value . status === 'paused' ) {
69+ state . value . status = 'running'
70+ state . value . startedAt = Date . now ( ) - ( state . value . pausedAt - state . value . startedAt )
4171 }
4272 interval . resume ( )
4373 }
4474
4575 function pause ( ) {
46- sharedState . timerStatus = 'paused'
47- sharedState . timerPausedAt = Date . now ( )
76+ state . value . status = 'paused'
77+ state . value . pausedAt = Date . now ( )
4878 interval . pause ( )
4979 }
5080
5181 function toggle ( ) {
52- if ( sharedState . timerStatus === 'running' ) {
82+ if ( state . value . status === 'running' ) {
5383 pause ( )
5484 }
5585 else {
@@ -59,10 +89,15 @@ export function useTimer() {
5989
6090 return {
6191 state,
92+ status,
6293 timer,
6394 reset,
6495 toggle,
6596 resume,
6697 pause,
98+ passed,
99+ percentage,
100+ duration,
101+ mode,
67102 }
68103}
0 commit comments