October 10, 2020

Last month I was doing my weekly “looking up YouTube videos about language learning instead of actually learning a language” routine and I stumbled upon Yoga’s How I Learned Japanese YouTube video series. Although I know Yoga from MIA since I am a follower of that methodology (I talk about it more on my language blog), I have never watched any of his videos. In one of them, he describes how he used timeboxing to really streamline his studying time. Now I have heard of timeboxing before—people like Elon Musk rely on it to manage their time—but Yoga mentioned how he would set his timeboxes to as little as 30 seconds. I don’t know why it never occurred to me that you could set timeboxes to be as small as this, but for some reason that really put timeboxing on the map for me.

Unfortunately, when I went on Google and searched for a timeboxing app, what I got were a few mobile apps that didn’t really suit my needs, and only 2 web apps which in my opinion didn’t look too great and I didn’t trust making an account on.

So since I graduated with a bachelors in computer science straight into the pandemic-induced recession where I can’t find a job (I live in the USA), I found myself with a lot of time and the right experience needed to set out and create my own timeboxing web app.

The Two Things I Wanted

No barrier to entry. Creating an account should not be a requirement. One of the detractors to all of the other timeboxing web apps was that I had to sign up to use it, and there’s no way that I’m going to trust a website with my login info and email if they can’t even display their button fonts correctly (no offense to aspiring web developers with websites like that).

It must be time agnostic. I do not care that a timebox starts at 9 AM and ends at 10 AM. All I care about is that it’s an hour long. If something pops up during that hour, I can just pause the timebox and resume it later. All that matters is that I get the hour of work done. The timebox shouldn’t be my calendar. Now I hear some of you guys saying “but that ruins the point of timeboxing” so to that I will say this: these are systems that you place on yourself. The only one keeping you accountable is you. Pausing a timebox so you can watch YouTube would be the same breach of contract as deleting a timebox off your calendar because you didn’t do your work in that time. At least with my system, I can keep track of how much time in the timebox I still have left to do.

Technical Details

The web app was created using Nuxt. Nuxt is amazing for building applications quickly, which was my original intention. I was not expecting this to take more than a month to build.

There are a few remnants in the code that don’t really make sense due to feature bloat, the most prominent of them is the naming of the VueX stores. timebox.js was originally the main store that would house all the… you know… timeboxes. I wasn’t expecting to need any other stores. It turns out that this was a mistake because now in the naming scheme, a singular timebox now references a list of timeboxes. When I wanted to add the ability to save multiple lists of timeboxes, I couldn’t name the store timeboxes.js because that is confusing and could be mistaken for referencing the list of timeboxes currently loaded with timebox.js references the current timebox the user is at. Because of this, I had to name it savedTimeboxes.js instead, which is less confusing but still a bit jarring.

In terms of implementation, all the timeboxes are implemented in what could be thought of as a pseudo-linked list. I was thinking that using a linked list implementation would be good since each timebox naturally leads to another, but JavaScript doesn’t have a linked list structure, and I think dealing with node references to other nodes would overcomplicated things, especially since I was implementing a draggable feature and can reorder the list whenever.

So what I did was twofold:

  1. Have a global reference to the current node, which is the timebox that is currently active and ticking.
  2. Have a global next function that replaces the current node with the next one in the array. This is different from an actual linked list where each node’s next is a reference to the next node.

Using this, next is always next and I don’t have to do any relinking of linked list nodes when reordering something. If I wanted to make it a true linked list, I would’ve had to hook into the draggable library’s added, move, and delete callbacks and do the node linking within that, but then you would run into the issues if the array changed externally.

The Finished Results* and the Future

*Not finished

Use the web app here

There’s a lot I still want to add, but I need to keep a balance between simplicity and convenience. There’s only two extra things that I personally need: a way to start the timer at a specific timebox (update: done ☑️), and the option to automatically pause the timer every time a timebox finishes so you can manually start it again (update: done ☑️).

I also would like to look into making a mobile app. I thought that I would be able to make this web app work on mobile by having service workers send push notifications when timeboxes are up, but apparently push notifications and mobile notifications are different things so whoops. I probably should’ve coded this in React so I can port it to React Native but too late now ¯\_(ツ)_/¯

Anyways, that’s enough ranting about this project. You can check out the code on GitHub here.

© 2021