From 9e2132cd54e5f5e6b85c7d949ac982cb95566027 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 21 Mar 2020 16:04:26 +0300 Subject: chore: migrate Timer page to Typescript :label: --- src/pages/Timer/TimerButton.tsx | 130 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/pages/Timer/TimerButton.tsx (limited to 'src/pages/Timer/TimerButton.tsx') diff --git a/src/pages/Timer/TimerButton.tsx b/src/pages/Timer/TimerButton.tsx new file mode 100644 index 0000000..86bbf76 --- /dev/null +++ b/src/pages/Timer/TimerButton.tsx @@ -0,0 +1,130 @@ +import React, { useState, useEffect } from 'react'; + +import { Paper, Typography } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles(theme => ({ + root: { + textAlign: 'center', + padding: theme.spacing(5), + background: theme.palette.background.elevation3, + marginTop: theme.spacing(10), + }, +})); + + +interface PropTypes { + registerResult: (result: string) => void; +} + +type Mode = 'idle' | 'countdown' | 'running' | 'over'; + + +const TimerButton: React.FC = ({ registerResult }) => { + const classes = useStyles(); + + const SPACE = 32; + const maxCountdown = 15000; + const [time, setTime] = useState('00:00:00'); + const [mode, setMode] = useState('idle'); + + useEffect(()=> { + const timestamp = Date.now(); + + if (mode === 'countdown') { + const repeater = setInterval(() => { + const timeDelta = maxCountdown - (Date.now() - timestamp); + if (timeDelta <= 0) setMode('over'); + setTime(convertTimeToString(timeDelta)); + }, 10); + return () => clearInterval(repeater); + } + + if (mode === 'running') { + const repeater = setInterval(() => { + setTime(convertTimeToString(Date.now() - timestamp)); + }, 10); + return () => clearInterval(repeater); + } + + if (mode === 'over') { + setTime('00:00:00'); + } + }, [mode]); + + const handleKeyPress = (event: KeyboardEvent): void => { + event.preventDefault(); + if (event.keyCode === SPACE && mode === 'idle' ) setMode('countdown'); + }; + + const handleKeyUp = (event: KeyboardEvent): void => { + if (event.keyCode === SPACE) { + if (mode === 'running') { + registerResult(time); + setMode('idle'); + } else if (mode === 'over') { + setMode('idle'); + } else { + setMode('running'); + } + } + }; + + useEffect(() => { + window.addEventListener('keyup', handleKeyUp); + window.addEventListener('keypress', handleKeyPress); + + return () => { + window.removeEventListener('keyup', handleKeyUp); + window.removeEventListener('keypress', handleKeyPress); + }; + }); + + const composeHelperText = () => { + switch (mode) { + case 'running': return 'Go fast!'; + case 'countdown': return 'Release SPACE to begin'; + case 'over': return 'You are too late!'; + default: return 'Hold SPACE to start countdown'; + } + }; + + const helperColor = () => { + switch (mode) { + case 'running': return 'primary'; + case 'over': return 'secondary'; + default: return 'textSecondary'; + } + }; + + return ( + + {time} + + {composeHelperText()} + + + ); +}; + +const convertTimeToString = (timeDelta: number): string => { + let resultTime = ''; + + const minute = Math.floor(timeDelta / 60000); + if (minute < 10) resultTime += '0'; + resultTime += minute + ':'; + + let second = Math.floor(timeDelta / 1000); + if (second > 59) second %= 60; + if (second < 10) resultTime += '0'; + resultTime += second + ':'; + + const mill = Math.floor((timeDelta % 1000) / 10); + if (mill < 10) resultTime += '0'; + resultTime += mill; + + return resultTime; +}; + + +export default TimerButton; -- cgit v1.2.3 From 0f6c4e7e4d44314707535e2d7e3aba7b638cd2dd Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 21 Mar 2020 16:11:31 +0300 Subject: fix: add more missing types :ok_hand: --- src/pages/Timer/TimerButton.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/pages/Timer/TimerButton.tsx') diff --git a/src/pages/Timer/TimerButton.tsx b/src/pages/Timer/TimerButton.tsx index 86bbf76..0a3bf38 100644 --- a/src/pages/Timer/TimerButton.tsx +++ b/src/pages/Timer/TimerButton.tsx @@ -37,14 +37,14 @@ const TimerButton: React.FC = ({ registerResult }) => { if (timeDelta <= 0) setMode('over'); setTime(convertTimeToString(timeDelta)); }, 10); - return () => clearInterval(repeater); + return (): void => clearInterval(repeater); } if (mode === 'running') { const repeater = setInterval(() => { setTime(convertTimeToString(Date.now() - timestamp)); }, 10); - return () => clearInterval(repeater); + return (): void => clearInterval(repeater); } if (mode === 'over') { @@ -74,13 +74,13 @@ const TimerButton: React.FC = ({ registerResult }) => { window.addEventListener('keyup', handleKeyUp); window.addEventListener('keypress', handleKeyPress); - return () => { + return (): void => { window.removeEventListener('keyup', handleKeyUp); window.removeEventListener('keypress', handleKeyPress); }; }); - const composeHelperText = () => { + const composeHelperText = (): string => { switch (mode) { case 'running': return 'Go fast!'; case 'countdown': return 'Release SPACE to begin'; @@ -89,7 +89,7 @@ const TimerButton: React.FC = ({ registerResult }) => { } }; - const helperColor = () => { + const helperColor = (): 'primary' | 'secondary' | 'textSecondary' => { switch (mode) { case 'running': return 'primary'; case 'over': return 'secondary'; -- cgit v1.2.3