Juno

Juno is a full-stack mobile & web hybrid time tracking application that empowers users to keep track of where they spend each minute of their time. They can add activities and then log intervals of time that they spent on those activities.

A good user interface that provides a good user experience was a priority for me when developing this app. Navigating the app is a breeze as it allows the users to log their activities with merely a single tap or click.

juno_header

Stack and Explanation

I chose Flutter for its multi-platform support and excellent developer experience and Node.js and Express for their quick and frictionless development time.

The database is SQLite because of the convenience that it provides in deployments and backups. I went with an ORM because of the ease with which I could switch to a database more robust than SQLite, if I ever end up deploying this for a sizeable user-base.

Why I Chose this Project?

I believe that time is the most valuable asset that we are blessed with. Regrettably a non-trivial part of lives slips away to social media, streaming platforms, procrastination, unproductive commutes, excessive personal chores, and gaming.

It's imperative that we reclaim control over our time, and this journey commences with a clear understanding of where exactly are we spending it. That is what Juno does. It empowers people by offering a methodical dissection of their time distribution – a tool for introspection into where exactly their moments are being invested.

juno_2

Problems Faced and Thought Process

Like any project this one also came with some hurdles and challenges. I have shared a few below.

Routing with go_router

I used the package go_router for route management in this app as it is recommended by Flutter docs. Figuring out how to properly disallow routes based on auth status, and saving route state like scroll position on navigating away was a challenging task because of my unfamiliarity with routing concepts at the time.

It required meticulous combing of go_router documentation and some experimentation with the package in a new empty Flutter project to figure everything out.

Migration from HTTP to Sockets

When testing the app on my device with the server deployed, making a log was awfully slow. I had to wait 2-4 seconds for a log to be made. Moreover there was no sync of state between an instance of Juno running on my laptop and another one on my phone without a full refresh/restart.

After some research I found out that moving to a socket based architecture would solve these problems. I had never worked with sockets before so it was a great learning opportunity too.

However, except for no real-time sync between devices and being slow, the app was already in a working condition and I had been personally using it for more than a month at the time. So this was a major refactor, but thankfully it was not a particularly hard or tedious one because I had been using the dependency injection design pattern.

I had an ActivitiesRepository, which I just slotted out for a newly written RealtimeActivitesRepository that used Socket.IO. I did the same for other data repositories that the app depended on and it was a painless experience.

On the server side the migration was extremely simple, I just put in socket handlers in addition to my express middlewares.

I also did not just switch over everything to sockets. For instance, I kept the user authentication repositories based on HTTP because I did not think that sockets provided any advantage over HTTP calls for auth.

Lessons Learned

This project helped my solidify my understanding of authentication, authorization, page routing concepts, socket programming, SQL, and dependency injection. I also learned how to integrate an HTTP and Socket.IO server with a Flutter app.

Next Steps

Juno is being used by myself and a couple of friends who are helping in testing it out for more than two months now. Before I release Juno to the public I want to add some more functionality. Specifically, I have offline-first capabilities and end-to-end encryption in the works.

After that I plan to release the app on app stores.

Links