import React, { useState, useEffect } from 'react';
import convertTimeToString from '../utils/convertTimeToString';
interface PropTypes {
registerResult: (result: string) => void;
maxCountdown?: number;
}
enum Mode {
'idle',
'countdown',
'running' ,
'over',
};
const helperTextMap = {
[Mode.idle]: (
<>
Hold
SPACE
to start countdown
>
),
[Mode.countdown]: (
<>
Release
SPACE
to begin
>
),
[Mode.running]: 'Go fast!',
[Mode.over]: 'You are too late!',
};
const KEY_CODE = 32; // Space key
const Timer: React.FC = ({ registerResult, maxCountdown = 15000 }) => {
const [mode, setMode] = useState(Mode.idle);
const [displayTime, setDisplayTime] = useState('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, maxCountdown]);
const handleKeyPress = (event: KeyboardEvent): void => {
if (event.keyCode === KEY_CODE && mode === Mode.idle) {
event.preventDefault();
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 (
<>
{ displayTime }
{ helperTextMap[mode] }
>
);
};
export default Timer;