1- let timerStarted = false ;
2- let seconds = 30 ;
3- let minutes = 0 ;
4- let hours = 0 ;
5- let intervalInstance ;
1+ const TimerStatus = {
2+ STOPPED : "STOPPED" ,
3+ PAUSED : "PAUSED" ,
4+ COUNTDOWN : "COUNTDOWN" ,
5+ RUNNING : "RUNNING" ,
6+ EDITING : "EDITING" ,
7+ isRunning : ( status ) => status === TimerStatus . RUNNING ,
8+ isCountdown : ( status ) => status === TimerStatus . COUNTDOWN ,
9+ } ;
10+
11+ const DEFAULT_INTERVAL = 1000 ;
12+ const DEFAULT_SECONDS = 30 ;
13+ let TIMER_STATUS = TimerStatus . STOPPED ;
14+
15+ setInputValues ( DEFAULT_SECONDS ) ;
16+
17+ document . getElementById ( "startBtn" ) . addEventListener ( "click" , start ) ;
18+ document . getElementById ( "pauseBtn" ) . addEventListener ( "click" , pause ) ;
19+ document . getElementById ( "toZeroBtn" ) . addEventListener ( "click" , stop ) ;
20+ document . getElementById ( "restartBtn" ) . addEventListener ( "click" , stop ) ;
21+ document
22+ . querySelector ( ".js-edit-button" )
23+ . addEventListener ( "click" , openEditInput ) ;
24+ document
25+ . querySelector ( ".js-finish-edit-button" )
26+ . addEventListener ( "click" , closeEditInput ) ;
27+ document
28+ . querySelector ( ".js-cancel-button" )
29+ . addEventListener ( "click" , cancelEditInput ) ;
30+ document
31+ . querySelector ( ".js-active-fullscreen" )
32+ . addEventListener ( "click" , handleFullscreen ) ;
33+
34+ document . getElementById ( "hour" ) . addEventListener ( "input" , function ( ) {
35+ validateInput ( this , 99 ) ;
36+ } ) ;
37+ document . getElementById ( "min" ) . addEventListener ( "input" , function ( ) {
38+ validateInput ( this , 59 ) ;
39+ } ) ;
40+ document . getElementById ( "sec" ) . addEventListener ( "input" , function ( ) {
41+ validateInput ( this , 59 ) ;
42+ } ) ;
43+
44+ function timer ( ) {
45+ let seconds = getInputSeconds ( ) ;
46+
47+ setTimeout ( function ( ) {
48+ if (
49+ TimerStatus . isRunning ( TIMER_STATUS ) ||
50+ TimerStatus . isCountdown ( TIMER_STATUS )
51+ ) {
52+ seconds -- ;
653
7- function formatTime ( value ) {
8- return value < 10 ? `0${ value } ` : value . toString ( ) ;
54+ if ( seconds <= 10 ) {
55+ TIMER_STATUS = TimerStatus . COUNTDOWN ;
56+ styleCountdown ( seconds ) ;
57+ }
58+
59+ setInputValues ( seconds ) ;
60+ if ( seconds == 0 ) {
61+ document . body . classList . add ( "zero" ) ;
62+ return ;
63+ } else {
64+ timer ( ) ;
65+ }
66+ }
67+ } , DEFAULT_INTERVAL ) ;
968}
1069
1170function validateInput ( input , maxValue ) {
@@ -14,176 +73,142 @@ function validateInput(input, maxValue) {
1473 if ( value < 0 ) value = 0 ;
1574 if ( value > maxValue ) value = maxValue ;
1675
17- input . value = formatTime ( value ) ;
76+ input . value = formatInput ( value ) ;
1877}
1978
20- document . getElementById ( "hour" ) . disabled = true ;
21- document . getElementById ( "min ") . disabled = true ;
22- document . getElementById ( "sec" ) . disabled = true ;
79+ function formatInput ( value = 0 ) {
80+ return value . toString ( ) . padStart ( 2 , "0 ") . slice ( - 2 ) ;
81+ }
2382
24- document . getElementById ( "hour" ) . value = formatTime ( hours ) ;
25- document . getElementById ( "min" ) . value = formatTime ( minutes ) ;
26- document . getElementById ( "sec" ) . value = formatTime ( seconds ) ;
83+ function getInputSeconds ( ) {
84+ const { seconds, minutes, hours } = getInputValues ( ) ;
2785
28- document . getElementById ( "hour" ) . addEventListener ( "input" , function ( ) {
29- validateInput ( this , 99 ) ;
30- } ) ;
86+ const sumMinutes = hours * 60 + minutes ;
87+ const sumSeconds = sumMinutes * 60 + seconds ;
3188
32- document . getElementById ( "min" ) . addEventListener ( "input" , function ( ) {
33- validateInput ( this , 59 ) ;
34- } ) ;
35-
36- document . getElementById ( "sec" ) . addEventListener ( "input" , function ( ) {
37- validateInput ( this , 59 ) ;
38- } ) ;
89+ return sumSeconds ;
90+ }
3991
40- document . getElementById ( "startBtn" ) . addEventListener ( "click" , function ( ) {
41- if ( ! timerStarted ) {
42- timerStarted = true ;
43- run ( ) ;
44- }
45- } ) ;
92+ function getInputValues ( ) {
93+ const hours = parseInt ( document . getElementById ( "hour" ) . value ) || 0 ;
94+ const minutes = parseInt ( document . getElementById ( "min" ) . value ) || 0 ;
95+ const seconds = parseInt ( document . getElementById ( "sec" ) . value ) || 0 ;
4696
47- document . getElementById ( "pauseBtn" ) . addEventListener ( "click" , function ( ) {
48- pause ( ) ;
49- } ) ;
97+ return { seconds, minutes, hours } ;
98+ }
5099
51- document . getElementById ( "toZeroBtn" ) . addEventListener ( "click" , function ( ) {
52- pause ( ) ;
53- hours = 0 ;
54- minutes = 0 ;
55- seconds = 30 ;
100+ function setInputValues ( fromSeconds = 0 ) {
101+ const hours = Math . floor ( fromSeconds / 3600 ) ;
102+ const minutes = Math . floor ( ( fromSeconds % 3600 ) / 60 ) ;
103+ const seconds = fromSeconds % 60 ;
56104
57- document . getElementById ( "hour" ) . value = formatTime ( hours ) ;
58- document . getElementById ( " min" ) . value = formatTime ( minutes ) ;
59- document . getElementById ( "sec" ) . value = formatTime ( seconds ) ;
60- } ) ;
105+ document . getElementById ( `sec` ) . value = formatInput ( seconds ) ;
106+ document . getElementById ( ` min` ) . value = formatInput ( minutes ) ;
107+ document . getElementById ( `hour` ) . value = formatInput ( hours ) ;
108+ }
61109
62- document
63- . querySelector ( ".js-edit-stopwatch" )
64- . addEventListener ( "click" , function ( ) {
65- document . getElementById ( "hour" ) . disabled = false ;
66- document . getElementById ( "min" ) . disabled = false ;
67- document . getElementById ( "sec" ) . disabled = false ;
68-
69- document . querySelector ( ".js-stopwatch-button" ) . classList . add ( "hide" ) ;
70- document
71- . querySelector ( ".js-edit-container-stopwatch" )
72- . classList . remove ( "hide" ) ;
73- } ) ;
110+ function start ( ) {
111+ TIMER_STATUS = TimerStatus . RUNNING ;
112+ applyStyles ( ) ;
113+ timer ( ) ;
114+ }
74115
75- document
76- . querySelector ( ".js-cancel-button" )
77- . addEventListener ( "click" , function ( ) {
78- document . getElementById ( "hour" ) . value = formatTime ( hours ) ;
79- document . getElementById ( "min" ) . value = formatTime ( minutes ) ;
80- document . getElementById ( "sec" ) . value = formatTime ( seconds ) ;
116+ function pause ( ) {
117+ TIMER_STATUS = TimerStatus . PAUSED ;
118+ applyStyles ( ) ;
119+ }
81120
82- document . getElementById ( "hour" ) . disabled = true ;
83- document . getElementById ( "min" ) . disabled = true ;
84- document . getElementById ( "sec" ) . disabled = true ;
121+ function stop ( ) {
122+ TIMER_STATUS = TimerStatus . STOPPED ;
123+ applyStyles ( ) ;
124+ setInputValues ( DEFAULT_SECONDS ) ;
125+ }
85126
86- document . querySelector ( ".js-stopwatch-button" ) . classList . remove ( "hide" ) ;
87- document
88- . querySelector ( ".js-edit-container-stopwatch" )
89- . classList . add ( "hide" ) ;
90- } ) ;
127+ function handleFullscreen ( ) {
128+ if ( ! document . fullscreenElement ) {
129+ document . documentElement . requestFullscreen ( ) ;
130+ document . querySelector ( ".js-active-fullscreen" ) . style =
131+ "background-color: rgba(255, 255, 255, 0.25)" ;
132+ } else {
133+ document . exitFullscreen ( ) ;
134+ document . querySelector ( ".js-active-fullscreen" ) . style = "" ;
135+ }
136+ }
91137
92- document
93- . querySelector ( ".js-finish-edit-button" )
94- . addEventListener ( "click" , function ( ) {
95- hours = parseInt ( document . getElementById ( "hour" ) . value ) || 0 ;
96- minutes = parseInt ( document . getElementById ( "min" ) . value ) || 0 ;
97- seconds = parseInt ( document . getElementById ( "sec" ) . value ) || 0 ;
138+ let PRE_EDIT_SECONDS = DEFAULT_SECONDS ;
98139
99- document . getElementById ( "hour" ) . disabled = true ;
100- document . getElementById ( "min" ) . disabled = true ;
101- document . getElementById ( "sec" ) . disabled = true ;
140+ function cancelEditInput ( ) {
141+ setInputValues ( PRE_EDIT_SECONDS ) ;
142+ closeEditInput ( ) ;
143+ }
102144
103- document . querySelector ( ".js-stopwatch-button" ) . classList . remove ( "hide" ) ;
104- document
105- . querySelector ( ".js-edit-container-stopwatch" )
106- . classList . add ( "hide" ) ;
107- } ) ;
145+ function openEditInput ( ) {
146+ TIMER_STATUS = TimerStatus . EDITING ;
147+ PRE_EDIT_SECONDS = getInputSeconds ( ) ;
148+ document . getElementById ( "hour" ) . disabled = false ;
149+ document . getElementById ( "min" ) . disabled = false ;
150+ document . getElementById ( "sec" ) . disabled = false ;
151+
152+ document . querySelector ( ".js-stopwatch-button" ) . classList . add ( "hide" ) ;
153+ document
154+ . querySelector ( ".js-edit-container-stopwatch" )
155+ . classList . remove ( "hide" ) ;
156+ }
108157
109- document
110- . querySelector ( ".js-active-fullscreen" )
111- . addEventListener ( "click" , function ( ) {
112- if ( document . documentElement . requestFullscreen ) {
113- document . documentElement . requestFullscreen ( ) ;
114- }
115- } ) ;
158+ function closeEditInput ( ) {
159+ TIMER_STATUS = TimerStatus . PAUSED ;
160+ document . getElementById ( "hour" ) . disabled = true ;
161+ document . getElementById ( "min" ) . disabled = true ;
162+ document . getElementById ( "sec" ) . disabled = true ;
116163
117- document . getElementById ( "restartBtn" ) . addEventListener ( "click" , function ( ) {
118- hours = 0 ;
119- minutes = 0 ;
120- seconds = 30 ;
164+ document . querySelector ( ".js-stopwatch-button" ) . classList . remove ( "hide" ) ;
165+ document . querySelector ( ".js-edit-container-stopwatch" ) . classList . add ( "hide" ) ;
121166
122- document . getElementById ( "hour" ) . value = formatTime ( hours ) ;
123- document . getElementById ( "min" ) . value = formatTime ( minutes ) ;
124- document . getElementById ( "sec" ) . value = formatTime ( seconds ) ;
167+ applyStyles ( ) ;
168+ }
125169
170+ function resetStyles ( ) {
171+ document . querySelector ( ".js-play-button" ) . classList . remove ( "press-start" ) ;
172+ document . querySelector ( ".js-stop-button" ) . classList . remove ( "press-stop" ) ;
173+ document . querySelector ( ".js-pause-button" ) . classList . remove ( "press-pause" ) ;
174+ document . querySelector ( ".js-edit-button" ) . classList . remove ( "press-edit" ) ;
126175 document . querySelector ( ".input-stopwatch" ) . classList . remove ( "hide" ) ;
127176 document . querySelector ( ".js-stopwatch-button" ) . classList . remove ( "hide" ) ;
128177 document . getElementById ( "countdown" ) . classList . add ( "hide" ) ;
129-
130178 document . body . classList . remove ( "zero" ) ;
131- } ) ;
179+ }
132180
133- function run ( ) {
134- hours = parseInt ( document . getElementById ( "hour" ) . value ) || 0 ;
135- minutes = parseInt ( document . getElementById ( "min" ) . value ) || 0 ;
136- seconds = parseInt ( document . getElementById ( "sec" ) . value ) || 0 ;
137-
138- intervalInstance = setInterval ( function ( ) {
139- if ( timerStarted ) {
140- if ( seconds === 0 ) {
141- if ( minutes === 0 ) {
142- if ( hours === 0 ) {
143- timerStarted = false ;
144- clearInterval ( intervalInstance ) ;
145-
146- document . getElementById ( "countdown" ) . classList . remove ( "hide" ) ;
147- document . getElementById ( "countdown-number" ) . textContent = "0" ;
148-
149- document . body . classList . add ( "zero" ) ;
150-
151- document . querySelector ( ".input-stopwatch" ) . classList . add ( "hide" ) ;
152- document
153- . querySelector ( ".js-stopwatch-button" )
154- . classList . add ( "hide" ) ;
155- } else {
156- hours -- ;
157- minutes = 59 ;
158- seconds = 59 ;
159- }
160- } else {
161- minutes -- ;
162- seconds = 59 ;
163- }
164- } else {
165- seconds -- ;
166- }
181+ const styles = {
182+ RUNNING : styleRunning ,
183+ PAUSED : stylePause ,
184+ STOPED : styleStop ,
185+ EDITING : styleEditing ,
186+ } ;
187+
188+ function applyStyles ( ) {
189+ resetStyles ( ) ;
190+ styles [ TIMER_STATUS ] ?. ( ) ;
191+ }
167192
168- if ( hours === 0 && minutes === 0 && seconds <= 10 ) {
169- document . querySelector ( ".input-stopwatch" ) . classList . add ( "hide" ) ;
170- document . querySelector ( ".js-stopwatch-button" ) . classList . add ( "hide" ) ;
193+ function styleCountdown ( seconds = 0 ) {
194+ document . querySelector ( ".input-stopwatch" ) . classList . add ( "hide" ) ;
195+ document . querySelector ( ".js-stopwatch-button" ) . classList . add ( "hide" ) ;
196+ document . getElementById ( "countdown" ) . classList . remove ( "hide" ) ;
197+ document . getElementById ( "countdown-number" ) . textContent = seconds ;
198+ }
171199
172- document . getElementById ( "countdown" ) . classList . remove ( "hide" ) ;
173- document . getElementById ( "countdown-number ") . textContent = seconds ;
174- }
200+ function styleRunning ( ) {
201+ document . querySelector ( ".js-play-button ") . classList . add ( "press-start" ) ;
202+ }
175203
176- document . getElementById ( "sec" ) . value = formatTime ( seconds ) ;
177- document . getElementById ( "min" ) . value = formatTime ( minutes ) ;
178- document . getElementById ( "hour" ) . value = formatTime ( hours ) ;
179- }
180- } , 1000 ) ;
204+ function styleStop ( ) {
205+ document . querySelector ( ".js-stop-button" ) . classList . add ( "press-stop" ) ;
181206}
182207
183- function pause ( ) {
184- timerStarted = false ;
185- if ( intervalInstance ) {
186- clearInterval ( intervalInstance ) ;
187- intervalInstance = null ;
188- }
208+ function stylePause ( ) {
209+ document . querySelector ( ".js-pause-button" ) . classList . add ( "press-pause" ) ;
210+ }
211+
212+ function styleEditing ( ) {
213+ document . querySelector ( ".js-edit-button" ) . classList . add ( "press-edit" ) ;
189214}
0 commit comments