123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- import { useState, useEffect, useRef } from 'react'
- import { TTraining } from '../../training/types'
- import { getExerciseList, getTrainingTime, getPosition } from '../utils'
- import Countdown from './Countdown'
- import AudioPlayer from './AudioPlayer'
- import { IExerciseItem } from '../types'
- import { useTimer } from '../hooks/useTimer'
- import { useVoice } from '../hooks/useVoice'
- import { useVideo } from '../hooks/useVideo'
- import theme from '../../styles/theme'
- const Timer = ({ training }: { training: TTraining }) => {
- const [time, timer] = useTimer({ tickPeriod: 100 })
- const voice = useVoice('rosie')
- const [state, setState] = useState({
- exerciseList: [] as IExerciseItem[],
- totalTime: 0
- })
- useEffect(() => {
- voice.play('ttt')
- const exerciseList = getExerciseList(training.blocks)
- const totalTime = getTrainingTime(exerciseList)
- setState({ ...state, exerciseList, totalTime })
- }, [training])
- const {
- currentExercise,
- previousExercise,
- nextExercise,
- exerciseTime
- } = getPosition(state.exerciseList, timer.time)
- const videoSrc =
- (currentExercise && currentExercise.video) || '/media/block0.mp4'
- const [videoRef, videoPlayer] = useVideo(videoSrc)
- useEffect(() => {
- if (time > state.totalTime) stopTimer()
- const countdown = currentExercise
- ? currentExercise.duration + currentExercise.offset - timer.intTime + 1
- : 0
- if (timer.running && voice && !voice.playing()) {
- if (exerciseTime < 1) {
- if (currentExercise && currentExercise.exercise !== 'Rest')
- voice.play('go')
- else voice.play('rest')
- } else if (countdown === 90) voice.play('ninety')
- else if (countdown === 60) voice.play('sixty')
- else if (countdown === 30) voice.play('thirty')
- else if (countdown === 5) voice.play('five')
- else if (countdown === 4) voice.play('four')
- else if (countdown === 3) voice.play('three')
- else if (countdown === 2) voice.play('two')
- else if (countdown === 1) voice.play('one')
- }
- }, [time, timer.running])
- function startTimer() {
- if (time >= state.totalTime) return
- timer.start()
- if (videoPlayer) videoPlayer.play()
- //if (audio.current) audio.current.play();
- }
- function stopTimer() {
- timer.stop()
- if (videoPlayer) videoPlayer.pause()
- //if (audio.current) audio.current.pause();
- }
- function forward() {
- if (nextExercise) {
- timer.setTime(nextExercise.offset)
- }
- }
- function back() {
- if (previousExercise) {
- timer.setTime(previousExercise.offset)
- }
- }
- return (
- <p id='timer'>
- <h1>{(currentExercise && currentExercise.toplevelBlock) || 'Torture'}</h1>
- <div id='flow'>
- <Countdown
- seconds={
- currentExercise ? currentExercise.duration - exerciseTime : 0
- }
- totalPercent={timer.time / state.totalTime}
- exercisePercent={
- exerciseTime / (currentExercise ? currentExercise.duration : 1)
- }
- onClick={timer.running ? stopTimer : startTimer}
- />
- <div id='controls'>
- {/*<label htmlFor="rest">Rest</label>
- <input type="number" min="25" max="60" step="5" defaultValue="25" />*/}
- <button onClick={back} disabled={timer.running}>
- back
- </button>
- <button onClick={timer.running ? stopTimer : startTimer}>
- {timer.running ? 'stop' : 'start'}
- </button>
- <button onClick={forward} disabled={timer.running}>
- forward
- </button>
- </div>
- <h2>current exercise</h2>
- <p className='exercise'>
- {currentExercise ? currentExercise.exercise : '😎'}
- </p>
- <h2>next up</h2>
- <p className='exercise'>
- {nextExercise ? nextExercise.exercise : '😎'}
- </p>
- </div>
- <p id='description'>
- <div data-vjs-player>
- <video ref={videoRef} className='video-js vjs-16-9' />
- </div>
- <p className='description'>
- {currentExercise && currentExercise.description}
- </p>
- </p>
- <style jsx>{`
- #timer {
- text-align: center;
- }
- #timer h1 {
- margin: 0 auto 0.8rem auto;
- }
- #flow h2 {
- margin-top: 0.4em;
- font-size: 90%;
- font-weight: 300;
- text-transform: uppercase;
- margin: auto;
- }
- #flow p {
- font-size: 110%;
- font-weight: 900;
- margin: 0 auto 0.8em auto;
- }
- #controls {
- margin-bottom: 0.4rem;
- }
- button {
- margin: 0.3rem;
- padding: 0.3rem;
- min-width: 6rem;
- border: none;
- background-color: ${theme.colors.darkblue};
- color: ${theme.colors.offWhite};
- cursor: pointer;
- }
- @media (min-width: 768px) {
- #timer {
- display: grid;
- grid-template-columns: 1fr 1fr;
- }
- h1 {
- margin: 0 auto 1.4rem auto;
- grid-column: 1/3;
- }
- #flow h2 {
- margin-bottom: 0.6rem;
- }
- #controls,
- #flow p {
- margin-bottom: 1.4rem;
- }
- button {
- padding: 0.6rem;
- margin: 0.6rem;
- }
- .header,
- .exercise {
- grid-column: 1/2;
- }
- .description {
- grid-column: 2/3;
- }
- }
- `}</style>
- </p>
- )
- }
- export default Timer
|