Hi there! I'm very excited to send out the first newsletter about creating Lotus! In case you forgot, Lotus is a Mac app for managing GitHub notifications in a calm way and I'm going to share how I'm building it in these emails.
As I started diving much deeper into the details of how this app should work, I ran into some issues and limitations of GitHub API that made me rethink some decisions and figure out some alternative paths to deliver on the promised features. Surprisingly, this resulted in a positive outcome for Lotus, making it a simpler and more efficient app for dealing with GitHub notifications.
I'm obviously using Lotus constantly through the development and it quickly became clear that there needs to be an easy way to view what each notification thread is about. So I thought, ok, I'm going to pull the list of thread comments from GitHub's API and render it in a separate view. There turned out to be multiple problems with this approach:
Not only there are multiple significant issues, it would probably set me back weeks and I would spend my time on solving the wrong problem. I dropped that idea for now and started thinking about other ways to display notification threads.
Next possible solution is opening the notification URL in the browser (redirecting the user to GitHub's website). Sure, it's easy to build, but it doesn't result in a great user experience. First, it would be annoying to go back and forth between Lotus and your browser. Second, there's a much bigger issue with just opening GitHub - it automatically marks the notification as read or "done". This is a deal breaker for an app that promises to put you back in charge of your GitHub notifications. Maybe it's just time, but most of the time I'm just going through notifications and seeing which ones I have time right now to deal with. It would be convenient if I didn't have to "Mark as unread" each notification I'm opening on GitHub's website.
Then I thought that a mix of these ideas would result in an optimal user experience with an adequate investment of my time. I decided to embed a GitHub website using a <webview>
tag, but with a few cool adjustments:
It looks like this:
I can always go back to custom rendering of notification contents, but I think this is a good middle ground for now. It gets the job done and it gives me time to work on the core app functionality.
Even though GitHub's notifications UI supports the following functionality, there's no way to access the same information via their API:
The API for fetching notifications also seems to return data in some random order, not sorted in any way and there's no option to do that. You can also fetch 100 notifications per request, so I implemented it to keep fetching notifications page by page, until there aren't any left. Now since I had access to all notifications, I could manipulate that data in any way to fit nicely into the app. The problem is, there are people like Sindre who have hundreds or thousands of unread notifications. It would take a long time to fetch all of them when app launches. It becomes even more troublesome when you think about refreshing that data to get new notifications that may have appeared since you last viewed the list.
So what can I do without having full access to the API? I can try to change how I'm approaching the problem. I can try to adapt and make the app simpler and still try to hit my goal of having a productive and efficient app to manage notifications.
I decided I'm not going to show all notifications, I'm going to show only 20 notifications instead.
Notifications are essentially to-do items. And from the experience of building my other side project - Linkjar, which solves somewhat similar problems, it's much more motivating to see a 20-item to-do list in front of you, than a to-do list that has hundreds of items I need to take care of.
Now that there are only 20 notifications to fetch, I can also implement one of the coolest features I promised I would build - filtering out spam. Maintainers constantly receive Dependabot pull requests and pointless "+1" or "is there any update on this issue?" comments. With just 20 notifications, I can fetch the contents of each of them and see if that notification is even worth showing.
After user completes the current batch of 20 notifications, they see some confetti being thrown with an option to pull the next batch of notifications. It's manageable, delightful and stress-free.
Just like the solution to viewing a notification in the web view, this way is simple and much more lightweight in terms of implementation. Moreover, it makes the product stand out by taking a different approach for tackling your notifications. Don't attempt to manage all of them at once, take it a step at a time and feel good about your progress.
HEY has been a huge inspiration for me on how to get back in control of information that is sent my way every day. I've been using it since the day they opened the sign ups and I really feel much less stressed with my email inbox. I want to apply similar techniques to GitHub notifications and I truly believe it will improve maintainers' online and offline well being.
I have to admit, while these challenges are certainly fun and exciting, I'm looking forward to a smoother sailing going forward 😄
It was interesting to brainstorm and learn how to treat limitations outside of my control as challenges and opportunities to solutions I may have not thought about before. If GitHub API would have more endpoints and parameters, I'd most likely end up with a bloated and complicated app with some custom way of managing those endless notifications.
Instead, it strips the unnecessary and lets you focus on making progress. I'm quite happy with how it's turning out and I'm super curious what's next for Lotus.
Thank you for reading that far, stay tuned for next week!
P.S. Replies to this email aren't currently working, but feel free to talk to me directly at vadimdemedes@hey.com.
I'm building Lotus in the open and I'm sending out progress updates just like this one every Sunday.
I won't send spam and you can unsubscribe anytime.