Tech Stack
React
Redux
IFrame Player API
Styled Components
Material UI
Sass
Roles
- Design
- Front-end
About
This is a customizable pomodoro timer with a background music built with React and Redux.
The user can set a YouTube link as the background music for each status (Focus, Short Break, Long Break) respectively. I used YouTube IFrame Player API to embed the YouTube video in this app.
For styling, I used Sass, Styled Components, and Material UI.
The user can set time and a BGM for each session respectively.
Custom inputs for both time and the BGM should be filled. The error messages will be shown if they are empty.
Time should be more than 0 sec and less than 1000 min. The error message will be shown if the condition does not meet.
The set button at the bottom of the setting page keeps disabled until all settings are specified.
The user can control (start, pause, resume) the timer by clicking YouTube video's play button or button(s) below the video.
The buttons below the video change according to the status of the timer.
There are the volume control slider and the toggle button for the bell that rings when each session's time is up.
The colour scheme changes on each session.
Notes
I created this app with my very own idea and design. Also, I decided to create it with an API and some new things such as styled-components
or Material UI to challenge myself.
First, I tried to connect to YouTube IFrame Player API following the official documentation. However, the code in there are all written in JavaScript.
I couldn't figure out how to convert those codes to React, so I used react-youtube
package.
There are two parts that I mostly struggled with.
1. The timer
I implement the timer with setInterval
first. It simply counts down time in every one second, which was not very accurate.
In order to make the timer accurate as possible, I switched to use setTimeout
.
Set the following three states: lastUpdatedTime
, elapsedTime
, totalTime
.
In setTimeout
, I created the callback function that calculates lastUpdateTime
which is given by Date.now()
and accumulates elapsedTime
by adding Date.now() - lastUpdateTime
to the previous elapsedTime
. This setTimeout
runs in 100 milliseconds.
Placed this setTimeout
under useEffect
that has lastUpdateTime
as a dependency. Therefore, this setTimeout
keeps running until clearTimeout
gets called. lastUpdateTime
gets updated in very short time, so this timer won't get a time lag as big as we can recognize.
2. Setting events that control YouTube video player
I needed to add events to the button elements to make them control the YouTube video player. Since I used react-youtube
package, I couldn't implement the way that the API's official documentation shows.
In react-youtube
, the target YouTube video player is identified with e.target
. Set the function that gets and sets e.target
as the state with onReady
props in the YouTube
component.