Hi everyone. I’m working on the 25+5 project and the tests all of a sudden keep passing/failing at random. Except for the first test from the Audio section. Any insight would be helpful about that error (which I don’t think is an error from my code as the sound does play when the timer reaches 00:00. A screenshot of the failing tests and my code are attached below:
import { useState, useRef, useEffect } from 'react'
import './App.css';
import { ReactComponent as Plus } from './icons/plus-svgrepo-com.svg'
import { ReactComponent as Minus } from './icons/minus-svgrepo-com.svg'
import alarm from './alarm_stop_sound.wav'
function App() {
// STATES
const [status, setStatus] = useState("Pomodoro")
const [sessionLength, setSessionLength] = useState(25)
const [breakLength, setBreakLength] = useState(5)
let time
function timeCorrector(t) {
return t > 9 ? t : "0" + t
}
if(status === "Pomodoro") {
time = timeCorrector(sessionLength)
} else {
time = timeCorrector(breakLength)
}
const [timer, setTimer] = useState(`${time}:00`);
const [currentTime, setCurrentTime] = useState(0)
const [play, setPlay] = useState(false)
const [timerStarted, isTimerStarted] = useState(false)
let timerDone = false
const [firstTime, isFirstTime] = useState(false)
const sessionIncrement = () => {
if(sessionLength < 60) {
if(!play) {
setSessionLength(sessionLength + 1)
if(status === "Pomodoro") {
clearTimer()
setTimer(`${timeCorrector(sessionLength + 1)}:00`)
}
}
}
}
const sessionDecrement = () => {
if(sessionLength > 1) {
if(!play) {
setSessionLength(sessionLength - 1)
if(status === "Pomodoro") {
clearTimer()
setTimer(`${timeCorrector(sessionLength - 1)}:00`)
}
}
}
}
const breakIncrement = () => {
if(breakLength < 60) {
if(!play) {
setBreakLength(breakLength + 1)
if(status === "Break") {
clearTimer()
setTimer(`${timeCorrector(breakLength + 1)}:00`)
}
}
}
}
const breakDecrement = () => {
if(breakLength > 1) {
if(!play) {
setBreakLength(breakLength - 1)
if(status === "Break") {
clearTimer()
setTimer(`${timeCorrector(breakLength - 1)}:00`)
}
}
}
}
const Ref = useRef(null);
const audioRef = useRef(null)
const playAlarm = () => {
let audio = audioRef.current
audio.load()
audio.time = 0
audio.play()
}
const getTimeRemaining = (e) => {
const total = Date.parse(e) - Date.parse(new Date());
const seconds = Math.floor((total / 1000) % 60);
const minutes = Math.floor((total / 1000 / 60) % 60);
return {
total,
minutes,
seconds
};
};
const startTimer = (e) => {
let { total, minutes, seconds } = getTimeRemaining(e);
if (total >= 0) {
setTimer(
(minutes > 9 ? minutes : "0" + minutes) +
":" +
(seconds > 9 ? seconds : "0" + seconds)
);
setCurrentTime(total)
} else {
// playAlarm()
timerDone = true
}
};
const clearTimer = () => {
if (Ref.current) clearInterval(Ref.current);
isTimerStarted(false)
setPlay(false)
}
const resetTimer = () => {
clearTimer()
setSessionLength(25)
setBreakLength(5)
setStatus("Pomodoro")
setTimer("25:00")
audioRef.current.pause()
audioRef.current.currentTime = 0
}
const goTimer = (e) => {
if(play) {
clearInterval(Ref.current)
setPlay(false)
} else {
isTimerStarted(true)
if (Ref.current) clearInterval(Ref.current);
const id = setInterval(() => {
startTimer(e);
if(timerDone) {
playAlarm()
clearTimer()
timerDone = false
status === "Break" ? sessionLabelClick("Pomodoro") : breakLabelClick("Break")
isFirstTime(true)
}
}, 1000);
Ref.current = id;
setPlay(true)
}
};
useEffect(() => { // eslint-disable-line
if(firstTime) {
isFirstTime(false)
goTimer(getDeadTime())
}
})
const getDeadTime = () => {
let deadline = new Date()
if(timerStarted) {
deadline.setSeconds(deadline.getSeconds() + currentTime / 1000);
} else {
deadline.setSeconds(deadline.getSeconds() + time * 60);
}
return deadline;
};
const sessionLabelClick = () => {
clearTimer()
setStatus("Pomodoro")
setTimer(`${timeCorrector(sessionLength)}:00`)
}
const breakLabelClick = () => {
clearTimer()
setStatus("Break")
setTimer(`${timeCorrector(breakLength)}:00`)
}
return (
<div className="app">
<h1 className="title">25 + 5 Clock</h1>
<div className="set-length">
<div className="pomodoro">
<p id="session-label" onClick={sessionLabelClick}
style={{textDecorationLine: status === "Pomodoro" ? 'underline' : ''}}>Pomodoro</p>
<button id="session-decrement" className="minus" onClick={sessionDecrement}>
<Minus />
</button>
<p id="session-length">{sessionLength}</p>
<button id="session-increment" className="plus" onClick={sessionIncrement}>
<Plus />
</button>
<p className="minutes">minutes</p>
</div>
<div className="break">
<p id="break-label" onClick={breakLabelClick}
style={{textDecorationLine: status === "Break" ? 'underline' : ''}}>Break</p>
<button id="break-decrement" className="minus" onClick={breakDecrement}>
<Minus />
</button>
<p id="break-length">{breakLength}</p>
<button id="break-increment" className="plus" onClick={breakIncrement}>
<Plus />
</button>
<p className="minutes">minutes</p>
</div>
</div>
<div className="clock">
<div className="timer-description">
<p id="time-left">{timerStarted ? timer : `${status === "Pomodoro" ? timeCorrector(sessionLength) : timeCorrector(breakLength)}:00`}</p>
<p id="timer-label">{status === "Pomodoro" ? "Time to work!" : "Time to play!"}</p>
</div>
<div className="controls">
<button id="start_stop" onClick={() => goTimer(getDeadTime())}>{play ? "Stop" : "Start"}</button>
<button id="reset" onClick={resetTimer}>Reset</button>
</div>
</div>
<audio id="beep" ref={audioRef} src={alarm} preload="none" />
</div>
);
}
export default App;