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