aboutsummaryrefslogtreecommitdiff
path: root/src/components/Timer.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/Timer.tsx')
-rw-r--r--src/components/Timer.tsx90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/components/Timer.tsx b/src/components/Timer.tsx
new file mode 100644
index 0000000..c9d7adf
--- /dev/null
+++ b/src/components/Timer.tsx
@@ -0,0 +1,90 @@
+import React, { useState, useEffect } from 'react';
+import convertTimeToString from '../utils/convertTimeToString';
+
+enum Mode {
+ 'idle',
+ 'countdown',
+ 'running' ,
+ 'over',
+};
+
+const helperText = {
+ [Mode.idle]: 'Hold SPACE to start countdown',
+ [Mode.countdown]: 'Release SPACE to begin',
+ [Mode.running]: 'Go fast!',
+ [Mode.over]: 'You are too late!',
+};
+
+// TODO: add to props
+const registerResult = (result: string): void => {
+ console.log(result)
+};
+
+const Timer: React.FC = () => {
+ const KEY_CODE = 32; // Space key
+ const maxCountdown = 15000;
+
+ const [mode, setMode] = useState<Mode>(Mode.idle);
+ const [displayTime, setDisplayTime] = useState<string>('00:00:00');
+
+ useEffect(() => {
+ const timestamp = Date.now();
+
+ if (mode === Mode.countdown) {
+ const repeater = setInterval(() => {
+ const timeDelta = maxCountdown - (Date.now() - timestamp);
+ if (timeDelta <= 0) setMode(Mode.over);
+ setDisplayTime(convertTimeToString(timeDelta));
+ }, 10);
+ return (): void => clearInterval(repeater);
+ }
+
+ if (mode === Mode.running) {
+ const repeater = setInterval(() => {
+ setDisplayTime(convertTimeToString(Date.now() - timestamp));
+ }, 10);
+ return (): void => clearInterval(repeater);
+ }
+
+ if (mode === Mode.over) {
+ setDisplayTime('00:00:00');
+ }
+ }, [mode]);
+
+ const handleKeyPress = (event: KeyboardEvent): void => {
+ event.preventDefault();
+ if (event.keyCode === KEY_CODE && mode === Mode.idle) setMode(Mode.countdown);
+ };
+
+ const handleKeyUp = (event: KeyboardEvent): void => {
+ if (event.keyCode === KEY_CODE) {
+ if (mode === Mode.running) {
+ registerResult(displayTime);
+ setMode(Mode.idle);
+ } else if (mode === Mode.over) {
+ setMode(Mode.idle);
+ } else {
+ setMode(Mode.running);
+ }
+ }
+ };
+
+ useEffect(() => {
+ window.addEventListener('keyup', handleKeyUp);
+ window.addEventListener('keypress', handleKeyPress);
+
+ return () => {
+ window.removeEventListener('keyup', handleKeyUp);
+ window.removeEventListener('keypress', handleKeyPress);
+ };
+ });
+
+ return (
+ <>
+ <span>{ displayTime }</span>
+ <p>{ helperText[mode] }</p>
+ </>
+ );
+};
+
+export default Timer;