A week of dev #2

User Interface

Since the first post in this category, I’ve been fixing some UI annoyances.

I began with the document details panels. It was crippled with bad implementations of the « Open » and « Mark as read » buttons.

The « Open » button was using an old API I’ve been using instead of the « main » event bus, so its behaviour was incorrect, and didn’t work at all for multiple documents.

When you clicked on the « Mark as read » button with a document being selected within the « Unread items » folder, the document was still displayed in that folder despite not having unread feed items anymore. That was also fixed.

There is some code in these files which allows a folder to be selected from within the details panel, even if there’s no link between the UI and the implementation – yet. This code was also using an old API, which have been fixed now. In a near future, it will be used to display a list of folders in which you have a bookmark pointing to the same document as the one in the details panel (a duplicate), and you would be able to click on one of them to navigate to it.

These three fixes also allowed me to cleanup the code in corresponding files. It’s nothing huge, but after doing it, I had that feeling, like when you’ve cleaned up a single room in the whole house: you enjoy this tiny satisfaction because you know there’s a lot more to come !

After these changes, I decided to try improving UI performances by changing my mind about how it responds to user interactions. I thought doing this differently would be good, but it turned out my first thought was the right one in terms of performances: each user action that sends a request to the server should be answered with appropriate content. For instance, renaming a folder would be responded with updated folder data in one request, instead of waiting the server to confirm the update, then send another query to get updated data. It may sounds dumb this way, but I thought it would allow me to improve decoupling in Vuex store, but it definitely created more problems than it solved.

I’ve updated every Vue components and back-end controllers with that idea in mind and I’m very satisfied with UI reactivity. It also allowed me to reduce and simplify the JS code, and fix some bugs that were lying around. This needed a lot of time and debugging, a lot of code has been rewritten, but this update paved the way to an easier maintenance.

Another big upgrade, also related to the « Mark as read » feature: after clicking the button, Cyca automatically select next unread feed item. It caused me some headaches because the next available feed item to read depends on what you marked as read: a whole folder, a document or simply a feed item. And what should we do once all feed items in a document are marked as read ?

So I came out with this algorithm, when you press the « Mark as read » button:

  • You are in a folder
    • Most straightforward situation: just mark everything as read in that folder, and do nothing more
  • You are in a document
    • Mark read all feed items attached to that document
    • List documents in the same folder
    • Select first document in that list that’s not the document you marked as read
    • Select first feed item in the new list
  • Your are reading a feed item
    • If there are more feed items
      • Select first feed item that’s not the feed item you were reading
    • If it was the last one in current list
      • List documents in the same folder
      • Select first document in that list that’s not the document to which the feed item was attached
      • Select first feed item in the new list

It was more difficult than I thought, but once you put your ideas on a whiteboard, it goes a bit easier ! And, while it seems to work, more can be done on that to make to code easier to read.

The « Authentication update » (see below) allowed me to bring some changes in the account interface. Since this commit, locale can be set on a per user basis. Cyca goes multi-lingual now !

Docker

As I’ve mentioned in my previous post, one of my top priorities for this week was to put Cyca on Docker’s Hub. First step: create an account on docker. Pretty straightforward, hu ? Well, not quite. I’m still waiting for the email confirmation link… It wouldn’t be right to complain about it, as Cyca’s email confirmation doesn’t work either yet 😅 (see below to crush the suspense…)

I’ve tried three different email addresses, I thought it was because it has a dot in it, then because it has the « docker » word in it. Both addresses are actually aliases to my main email account. After failing to get the email verification link to these addresses, I created a brand new email account, and, voilà, I get my verification link.

To this day, I don’t know if it has something to do with my aliases (which would be a first-timer) or if Docker can actually know if an address is an alias. But what’s important is that now, I can publish a container for Cyca to the Hub, \o/

Authentication

Laravel Fortify is the new authentication backend for Cyca. It is mainly supposed to work together with Jetstream, but something tells me it will soon be the default for Laravel, so I decided to make a bet and use it right now (without the whole Jetstream stack). I was hoping it could allow me to fix that annoying bug on email verification. As it turned out, the authentication was not the problem. After some research, I found that it was because I forced HTTPS scheme in Laravel (which I really shouldn’t) and because I should have allowed proxies in the TrustProxies middleware.

Moving to Fortify wasn’t really easy because a) I’m not creating a new project and b) using Jetstream would have done all the hard work for me, but I’m not sure yet I want to use Jetstream for various reasons, at least, right now.

Consequently, it was a rather big update, but it totally worth it as now everything about authentication, email validation, password change and password lost work perfectly. One thing less to worry about ! Oh and, by the way, this update triggered the release of Cyca v0.2.0, the « Authentication update« , the biggest (in importance) to date.

Tiny bits

I forgot two strings written in French in the account page, and feeds and feed items titles are now properly trimmed.

I’ve removed moment.js from the project. While it was an excellent library to work with dates and time in javascript, it’s now considered done by its authors. I’ve been using it in countless projects, but its use in Cyca doesn’t justify keeping it. In fact, it was responsible for almost half of final size of compiled javascript (which included locales), for just three calls that have been easily replaced.

I’ve also removed the axios library. Again, it’s an excellent library to deal with modern Ajax queries, but the web standards evolve, so should we. As such, I’ve replaced all calls to axios to the native fetch implementation. Without axios, the final javascript weight 384KB, which is still too big to suit me but it’s a huge improvement compared to the 678 KB that file weighted at the beginning of my work on Cyca. And I’m not done cutting dependencies, but that’s going to be for next week… In the mean time, I’m happy with the performance gain by dropping these libraries. My target is to make it as reactive as possible, and we’ll see if I can do it by next week…

What’s next ?

It was a very busy week, of course. I don’t complain: I love to learn new things, I love dev, and I love how Cyca has evolved in just one week. And I don’t expect this situation to be any different any time soon ! So, I already have a lot of plans, and some of them will hopefully be fulfilled next week.

Now that I created my Docker Hub account, I will detach everything related to Docker from the main repository and move it to a dedicated one, and automate building containers.

I’d like to keep on cleaning and making the javascript lighter, and fix last big UI issues. First step will be to upgrade Vue 2 to Vue 3. I really want to shrink down the current 350KB+ compiled javascript.

In the same spirit of making things lighter, I’d like to start cleaning up the CSS. And, maybe, in the end, getting rid of Tailwind, depending on how far the cleaning will go. Again, I want to shrink down the current 90KB compiled CSS to something much lighter. I don’t know how small the javascript could be, but the CSS certainly can be a lot smaller than that.