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.


