diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/Timer/Timer.js | 113 | ||||
-rw-r--r-- | src/components/TimerPage/TimerPage.js | 58 |
2 files changed, 129 insertions, 42 deletions
diff --git a/src/components/Timer/Timer.js b/src/components/Timer/Timer.js index 4712265..99356a5 100644 --- a/src/components/Timer/Timer.js +++ b/src/components/Timer/Timer.js @@ -1,51 +1,60 @@ import React, { useState, useEffect } from 'react'; -import { post } from '../../requests'; +import { Paper, Typography } from '@material-ui/core'; +import { makeStyles } from "@material-ui/core/styles"; -import { Typography } from '@material-ui/core'; +const useStyles = makeStyles(theme => ({ + root: { + textAlign: 'center', + padding: theme.spacing(5), + background: theme.palette.primary.main, + marginTop: theme.spacing(25), + }, +})); + +const Timer = ({ registerResult }) => { + const classes = useStyles(); -const Timer = () => { const SPACE = 32; const maxCountdown = 15000; const [time, setTime] = useState('00:00:00'); - const [isRunning, setIsRunning] = useState(false); - const [timer, setTimer] = useState(0); - const [isCountdown, setIsCountdown] = useState(false); - let startingTime; + const [mode, setMode] = useState('idle'); + const [repeater, setRepeater] = useState(0); - const handleKeyPress = event => { - if (event.keyCode === SPACE && !isRunning ) { - if (!isCountdown) { - startingTime = Date.now(); - setIsCountdown(true); - setTimer(setInterval(() => setTime(() => { - const timeDiff = maxCountdown - (Date.now() - startingTime); - if (timeDiff < 0) { - setIsRunning(true); - setTime('00:00:00'); - clearInterval(timer); - } - return convertTimeToString(timeDiff); - }), 10)); - } + useEffect(()=> { + clearInterval(repeater); + const timestamp = Date.now(); + + if (mode === 'countdown') setRepeater(setInterval(() => { + const timeDelta = maxCountdown - (Date.now() - timestamp); + if (timeDelta <= 0) setMode('over'); + setTime(convertTimeToString(timeDelta)); + }, 10)); + + if (mode === 'running') setRepeater(setInterval(() => { + setTime(convertTimeToString(Date.now() - timestamp)); + }, 10)); + + if (mode === 'over') { + setTime('00:00:00'); } + }, [mode]); + + const handleKeyPress = event => { + event.preventDefault(); + if (event.keyCode === SPACE && mode === 'idle' ) setMode('countdown'); }; const handleKeyUp = event => { + clearInterval(repeater); if (event.keyCode === SPACE) { - clearInterval(timer); - if (!isRunning) { - startingTime = Date.now(); - setIsRunning(true); - setTimer(setInterval(() => setTime(convertTimeToString((Date.now() - startingTime))), 10)); + if (mode === 'running') { + registerResult(time); + setMode('idle'); + } else if (mode === 'over') { + setMode('idle'); } else { - - clearInterval(timer); - setIsRunning(false); - setIsCountdown(false); - startingTime = 0; - post('solutions/', {result: time}); - return false; + setMode('running'); } } }; @@ -60,31 +69,51 @@ const Timer = () => { }; }); + const composeHelperText = () => { + switch (mode) { + case 'running': return '_'; + 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 ( - <Typography variant="h2"> {time} </Typography> + <Paper elevation={3} className={classes.root}> + <Typography variant="h1"> {time} </Typography> + <Typography variant="h5" color={helperColor()}> + {composeHelperText()} + </Typography> + </Paper> ); }; - - -const convertTimeToString = timeDiff => { +const convertTimeToString = timeDelta => { let resultTime = ''; - const minute = Math.floor(timeDiff / 60000); + const minute = Math.floor(timeDelta / 60000); if (minute < 10) resultTime += '0'; resultTime += minute + ':'; - let second = Math.floor(timeDiff / 1000); + let second = Math.floor(timeDelta / 1000); if (second < 10) resultTime += '0'; if (second > 59) second %= 60; resultTime += second + ':'; - const mill = Math.floor((timeDiff % 1000) / 10); + const mill = Math.floor((timeDelta % 1000) / 10); if (mill < 10) resultTime += '0'; resultTime += mill; return resultTime; }; -export default Timer; +export default Timer; diff --git a/src/components/TimerPage/TimerPage.js b/src/components/TimerPage/TimerPage.js new file mode 100644 index 0000000..f304b46 --- /dev/null +++ b/src/components/TimerPage/TimerPage.js @@ -0,0 +1,58 @@ +import React from 'react'; + +import { Grid, Box } from "@material-ui/core"; +import { makeStyles } from "@material-ui/core/styles"; + +import Timer from "../Timer/Timer"; +import SolutionCard from "../SolutionCard/SolutionCard"; + +import { post } from '../../requests'; + + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + justifyContent: 'space-between', + padding: theme.spacing(5, 4, 4, 4), + }, +})); + +const TimerPage = ({ recentSolutions, setRecentSolutions }) => { + const classes = useStyles(); + + const user = { + id: null, + username: 'anonymous', + }; + + const registerResult = result => { + const solution = { author_id: user.id, result }; + post('solutions/', solution).then(response => { + setRecentSolutions([response.data].concat(recentSolutions)); + }); + }; + + const removeSolution = (id) => { + setRecentSolutions(recentSolutions.filter((solution => solution.id !== id))); + }; + + return ( + <Box className={classes.root}> + <Grid container direction="row" justify="space-around" spacing={8}> + <Grid item xs={6}> + <Timer registerResult={registerResult} style={{ position: 'fixed' }}/> + </Grid> + <Grid item xs={4} container direction="column" spacing={5}> + {recentSolutions.slice(0, 3).map(solution => ( + <Grid item key={solution.id}> + <SolutionCard data={solution} removeThisCard={removeSolution}/> + </Grid> + ))} + </Grid> + </Grid> + </Box> + ); +}; + + +export default TimerPage; |