A Simple React/Redux/RxJs Timer

(Psssst! The code for this project is here: https://github.com/NerdcoreSteve/SimpleWebTimer, AAAAaaaand.... The actual web application that you can use right now can be found here: https://obscure-temple-46876.herokuapp.com/)

Recently I was tooling around on my computer without the benefit of my phone, which I had left in another room.

I've probably not mentioned this on the blog but I'm a BIG proponent of The Pomodoro Technique. For this I use the timer on my phone.

For those of you not familiar with the technique here's what you do. Pick a task, any task, then do it for 25 minutes. Brook no interruptions, do not check facebook or twitter, do not day dream, just do the thing (whatever it is) for 25 minutes.

After the 25 minutes have passed, take 5, then do another 25 minutes. Make every 4th break 15 to 20 minutes. Keep doing this as long as you like.

But to use this technique I need a phone or some other device that has a timer! So there I was, in a room without my phone, and at the time it would've been pretty inconvenient to leave and get it. But wait! I have a computer. I know how to program. Why not just make a timer?

So I did. Here's what it looks like:

The "Start/Resume" button, as well as the clock above it should be self-explanatory. The text-box below determines the interval for the timer; I've set it to two minutes here.

When I hit that button the timer starts:

The text box is replaced by a paragraph element, the button now says "Pause", and the clock at the top starts ticking.

Most of the UI code is contained in a function; that function contains a single if-else-statement:

if(store.getState().paused) {  

The if block returns the UI for paused mode, the else block returns the UI for non-paused mode, namely the JSX for the timer, button, and text-box or paragraph element (depending).

I use RxJs to create a clock that ticks every second:

timer = Rx.Observable.interval(1000)  
    .pausable(new Rx.Subject())

I plan to blog about it more but the pauseable bit allows me to create a stream that I can pause and resume, which I do using redux-saga.

I could put calls to pause and resume the clock in my redux reducer, but that would make my reducer an impure function, a big no-no.

I figured that since I already use redux-saga to do asynchronous calls, I might as well use it for all side-effects:

    timerSaga = function* (action) {
        if(action.type === 'START_RESUME'
           && store.getState().paused) {
            timer.resume()
            yield put({type: 'STARTED_RESUMED'})
        } else if(action.type === 'PAUSE'
                  && !store.getState().paused) {
            timer.pause()
            yield put({type: 'PAUSED'})
        }
    },

I also have a saga for creating a browser alert, another side effect. (If I keep using and improving this app, I'll eventually use browser notifications instead.)

Like I wrote above, you can look at the full code at https://github.com/NerdcoreSteve/SimpleWebTimer and actually use the app at https://obscure-temple-46876.herokuapp.com/.

Looking for a software developer?