DEV Community

Cassidy Williams
Cassidy Williams

Posted on

Building todometer: a meter-based to-do list

After a bunch of on and off development, I finally finished a side project I've been wanting to do for years.

screenshot

In general, I love completing things. If I am playing a phone game where each level gives you X number of stars, I will make sure I get every single one. If I'm working on a project using test-driven development, I am not happy until every single test passes and I see that awesome green "all tests pass". I wanted a to-do list that gave me that same level of satisfaction.

Thus, todometer was born! It's a meter-based to-do list. As you complete your tasks, you fill a progress bar. If you are putting off a task, it still fills the progress bar, just in a different color. All about positive reinforcement. ;)

Building todometer was a LONG process. I've started and stopped development for at least 2 years now. Finally, enough was enough and I got down to it.

Before building anything, I sketched up what I wanted the app to look like. After getting a general idea in my notebook, I opened up Sketch (which I'm still learning, but hey, practice!) and kept messing with color schemes and sizes and fonts until I got what I wanted.

sketch

Yes, that's right, I designed this back in January. It's been a long trip.

Anyway. One thing I do want to point out is that I don't normally design things first (I just kind of wing it), but I definitely will be from now on. Having rules to follow helps a TON when coding up the CSS.

I knew I wanted it to be a desktop app, and my main language I use regularly is JavaScript. So, the obvious choice for me was Electron. Setting that up was easy enough, thanks to its demo projects online.

My favorite framework is React, so I got to building. I used Moment.js for the date info, react-progressbar.js for the progress bars (these involved an annoying amount of math because of how the library works, but I'm not going to get into it for my own sanity), and just regular React components for the list of items, and for each item. I did the styling with LESS, mostly for the nesting and variables.

After working on this and getting everything mostly functional in React, I realized that the app would work best if I could make the app "reset" when the day ended (moving the paused items to the uncompleted list, and resetting the progress bar). But, because the date and the list components were unrelated, I had a decision to make: Do I restructure the app so that the state is in the parent component, and everything changed is passed via props, OR do I add Redux to the app to have a global store I can keep track of?

I chose Redux. Mostly because I didn't know Redux.

Guess what? Redux is hard. But, with the help of my redux-pro friend Dan Park, I was able to wrap my mind around the mythical concepts of actions and reducers. The app was COMPLETELY restructured (seriously, if you go stalk the commit history, you'll see some crazy things at that point), and honestly it worked much better. Adding Redux also made persisting app state with local storage super easy too (literally only took two functions, it's beautiful). That "reset" function I wanted was an easy call with it, and the app reset on a new date. It was perfect. Except: the app didn't do it automatically. I had to manually refresh it to make that work.

The automatic resetting on the new date was hard. I couldn't figure out how to make a date tracker "live" within React. I could set a timer until midnight, but would it live in componentWillMount, or componentDidMount, or somewhere in Redux? That's when I had a eureka moment: I would have Electron keep track of it at the desktop-level, and refresh the body at midnight!

It worked.

I cried.

Not kidding.

Anyway, after tweaking Electron details to make the app stay open when you close it, and having the proper metadata for installation, it was time to release.

I whipped up a quick "marketing" site, and today, I released it into the wind metaphorically.

And now, I look to you. Check it out! File an issue! Star the repo! Give me opinions! Or not, I'm not your mother!

https://cassidoo.github.io/todometer

<3

Top comments (20)

Collapse
 
ben profile image
Ben Halpern

I just downloaded it and am using it. Having fun already, also have spotted an opportunity to make a pull request, which I'm excited about because I have not used Electron at all and just needed an excuse. Such awesome stuff Cassidy. Great post!

Collapse
 
peter profile image
Peter Kim Frank

Looks great, thank you for sharing!!

I've been using todometer all day and have been enjoying it so far.

I had a few small comments / requests, for you, or anyone who wants to submit a pull request.

  • I enjoy tabbing / shift-tabbing, to keep things keyboard-only. The animation feedback that indicates where the "focus" is currently at is definitely helpful, but it also disappears rather quickly. It might be helpful to extend that indicator slightly -- just so you don't get "lost" as you alt-tab around.

  • It's nice to push items down to "do later," and I recognize that you can "reset progress" and send everything back up at once. Ideally, it would be possible to send an individual item back to the main queue; like a "reverse" on the main functionality. So, basically, having the yellow "pause button" visible on the "Do Later" items that sends them back up.

Also, one quick observation / feedback:

  • I had attempted to use the cmd+Q hotkey to close the app and noticed that it didn't work. To my knowledge, this was my first time I'd seen that on a desktop app for Mac. I'm curious if Electron provides any feedback/guidance on which global hotkeys developers are supposed to enable on their apps.

Again, GREAT job and thank you for sharing. I look forward to using todometer and hopefully contributing one day :)

Collapse
 
mpjme profile image
Mattias P Johansson

Whenever I need to deal with time in redux, I generally set up an Action that uses setInterval to dispatch another action every 100ms or to Redux with the current time, which updates the reducer state with the current time. That way, time becomes completely reactive and declarative and updates work fine. The action is started from componentDidMount.

Collapse
 
cassidoo profile image
Cassidy Williams

That's a good idea to have it live in the action.

That being said, I didn't want to just check for the time every second (or so), I wanted to just set a countdown to midnight and let the app refresh from there.

That being said, thank you, that'll be really helpful for when I do something like that outside of Electron!

Collapse
 
guitarkat profile image
Kat

Looks good! :) I need positive reinforcement to finish my tasks. Mobile is totally a great idea (read some comments) and if you want some positive constructed feedback on anything, I'd be happy to. I'm seriously in need of a UX change to my current how-to-get-things-done sort of thing and this makes me reflect.

Soon you'll have bug fixes and features on your too haha :)

PS: Probably stupid question but bear with me how do you guys get both your github and your twitter recognized by this thing?

Collapse
 
engineercoding profile image
Wesley Ameling

This really seems like something I want to be using short term. The UI looks nice and really want to try out the positive reinforcement thing, maybe that will help me finishing projects faster ;)

Collapse
 
thomsch profile image
Thomas Schweizer

It looks really cool ! I'll definitely give it a try when it's out for Windows !

Collapse
 
cassidoo profile image
Cassidy Williams

Just launched it for Windows!!

Collapse
 
thomsch profile image
Thomas Schweizer

Nice ! I'll try it today at work :)

Collapse
 
artistwhocodes profile image
Pamela Alvarez

Awesome! Looks great! You inspire me to redo my to-do-list.

Collapse
 
jess profile image
Jess Lee

Ahh, congrats on finishing a side project -- especially since it's been on your TO DO list for so long! 😉

What resources did you use to pick up Electron?

Collapse
 
cassidoo profile image
Cassidy Williams

Hahaha thank you!

Honestly it was just a LOT of googling whenever I wanted to do a specific thing. One of the things that took the longest was making sure the application windows stayed open (just hidden) when you hit the Close button. A bunch of people had different solutions for their specific apps, and it was a lot of trial and error to figure out how to make it work for me.

Collapse
 
kaylacohn_ profile image
Kayla Cohn 👩🏽‍💻

Congrats on your release - it looks super slick! Im in the design process for my electron app that I plan on building with react and redux. Will def be looking into your source! Congrats again!

Collapse
 
nechitagabriel profile image
Gabriel

Any idea when you can launch it for windows? Looks cool. Can't wait to test it.

Collapse
 
cassidoo profile image
Cassidy Williams

Just did!! Go ahead and check it out!!

Collapse
 
cfurrow profile image
Carl Furrow

Really great work! Love the look and feel.

Collapse
 
hackingbeauty profile image
Mark M. Muskardin

Hey good job! :)

Collapse
 
bhermans profile image
Bart Hermans

Will this run on mobile?

Collapse
 
cassidoo profile image
Cassidy Williams

It's a desktop app right now, but thinking about mobile next!

Collapse
 
bhermans profile image
Bart Hermans

Cool. Patiently waiting for the Windows version to try it out.