Building todometer: a meter-based to-do list
Cassidy Williams May 1 '17
After a bunch of on and off development, I finally finished a side project I've been wanting to do for years.
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.
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.
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
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!
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!