Recollectr 3.16 – Notes Julienne

It’s been a long year, and a long time since the last version of Recollectr was released. The wait is finally over!

Why did this version take so long?

Simply put, quality improvements; both for our users and for ourselves. In this case, the former relied on the latter, so this was an extended release cycle. We spent a lot of time and effort fixing a whole bunch of outstanding issues, with our eye, as always, on the long term.

There was also a change of offices, computer upgrades, a switch from Windows to Linux, and an everlasting global pandemic, which helped to drag out this already long release cycle to almost ludicrous lengths.

Quality improvements, through and through

This update took longer than any before it, in part, because this update touched more aspects of Recollectr than any update before it. Nearly every file in the source code has had some modification or another this time around. That’s meant not only more coding, but more testing too.

The improvements come in two flavors; improvements for ourselves, and improvements for you, our wonderful users.

Improvements for ourselves

Well, it’s not quite correct to call these improvements “for ourselves;” because, of course, everything is for our users in the end. That said, these changes won’t be appreciated for some time. But they’ll help us streamline development further and ensure that future versions have less unexpected issues and regressions. Internally we called this, The Great Refactor, and it’s something that’s been planned for years now.

NOTE: If you don’t care how the sausage is made, so to speak, by all means you can skip ahead. This section is mostly aimed at the developers out there among our users.

Recollectr developed out of a personal project and a number of things were coded with the mindset of, “Can we achieve this specific aim, and if so, how?”

Now that many of those specific aims have been achieved, the driving mindset has to change as well. That mindset is increasingly, “Can we optimize this code for both our users and our future development, and if so, how?” — This is a big pivot towards creating more enjoyable experience – but before we get to what’s new for users, let’s briefly touch on what’s new for us on the development side.

ESLint

ESLint is a tool to help improve code quality by enforcing conventions – sort of like a grammar-checker for coding. We’ve been using it for years now, but for this release we decided to spend some extra time with the tool, getting the most from it that we can. In all we fixed over 4000 ESLint complaints in the codebase, including some 2000 of them by hand. A number of these complaints were existing technical debt – warnings we’d not yet gotten to address – but the vast majority of them were newly applied rules. We meticulously combed over hundreds of rules from different projects, choosing the ones best suited to our work. In all, we added 154 new rules to our 569 existing ones. This was a lot of work, but the payoff has been well worth it. The codebase is now far easier to read, git diffs contain fewer lines, and even some small performance improvements came out of this. This undertaking also uncovered about half a dozen bugs – which of course are all fixed now!

New project structure and removal of circular dependencies

Circular dependencies are bad – but they can enable faster development, until they don’t.

One of the most painful parts of building a robust app is maintaining a thoughtful project structure without getting bogged down by the overhead involved in structuring; it’s that much worse when the app develops out of a personal project. It can grow increasingly difficult to keep moving forward at a steady pace as decisions from the past begin to show their age.

On the other-hand, when restructuring, care has to be taken to avoid falling victim to the second-system effect; becoming too confident that the payoff for the effort will be worth it.

In the end, we believe we’ve walked that fine line successfully. Internally we’ve moved hundreds of files to about a dozen new internal packages, and renamed several packages too. One of the changes we made to improve the project structure was to adopt a modified version of Brad Frost’s Atomic Design.

All of this work combined amounts to a huge cleanup and detangling of legacy code. Below is a before/after visualization of tangled dependencies. You can see they’ve been almost completely resolved, but there’s still a little work left to do. It’s hard to achieve perfect organization from legacy code while also accommodating the cross-platform nature of the codebase, but we’re closer than ever!

Circular Dependencies: Before The Great Refactor
(Less is better)
Circular Dependencies: After The Great Refactor
(Less is better)

Duplicate code

Duplicate code is a code smell. Recollectr’s codebase has been swept over for duplicate code using JSCPD and it’s been deduplicated where reasonable. As of Recollectr 3.15, the portion of duplicate code in the codebase was about 1.45%. As of today that’s down to 0.87%. Not all “duplicate” code is easily deduplicated, or even necessarily duplicate, but we’re endeavoring towards further deduplication for future versions.

Improvements for our users

“We now resume our regularly scheduled programming” – because users shouldn’t have to wait for the fruits of The Great Refactor to start seeing improvements!

The Goto-Box

The first thing you’ll notice, if you’re using the goto-box layout, is that it’s been dramatically improved in a number of small, but important ways.

The goto-box now has a backdrop for better visual clarity – but you can still click straight through to focus the note, or any other element behind it. This feels a lot smoother than the prior implementation that required you to manually close the goto-box while editing a note.

Additionally the animation performance has been dramatically stepped up, with memory usage reductions too! Not only is this the case for the default show/hide animation, but for the omnibox bypass animation too. These changes make a big difference in smoothness – and that smoothness facilitates, you guessed it, flow state. Even better, we were able to achieve huge performance improvements while barely changing the visual appearance of the animations; we see this as an absolute win.

The last notable change here is to the box resizing/positioning logic. Previously there were some quirks and annoyances here – like that dragging to resize the goto-box didn’t resize in the opposite direction as well – and that resizing the window too quickly could result in the goto-box shifting out of position, requiring more user intervention to restore it to the intended position.

Recollectr 3.15: Goto-Box Position; Before/After Extensive Window Resizing
Recollectr 3.16: Goto-Box Position; Before/After Extensive Window Resizing

The Menubar

The menubar, a mainstay of macOS, was pretty barren in 3.15 and below – and many of the hotkeys that did exist were not macOS specific. That’s all changed now, with macOS specific hotkeys for all functions added to the menubar so far.

But what’s more – the menubar will now be populated for Linux users too. Prior to switching our daily driver from Windows to Linux, we hadn’t realized there was even a use case for these menus outside of macOS – but then we met Edna. With that in mind, the menubar is now available on Linux (and even on Windows, just in case we’ve overlooked something like Edna for Windows.)

Improved menubar support on macOS and Linux

High quality icons

This one is pretty self explanatory. The icons always looked alright in the task switcher when we were using Windows as our daily driver – but after switching to Linux it became apparent that the icon quality was subpar, to say the least.

Recollectr 3.15
Recollectr 3.16

Performance and memory usage improvements

Lots of small tweaks add up to big improvements, and nowhere is it more true than with regards to performance.

Recollectr 3.16 uses nearly 13% less memory compared with the previous version in our basic testing – measuring memory usage one minute after startup on Windows 7 with about 800 notes, the memory usage is reduced from 522mb to 458mb – a 64mb drop. This was achieved by careful examination of CSS rules, removal of unnecessary object properties, rewriting legacy code, and removing duplicate code.

In addition to memory improvements, there’s been significant CPU usage improvements – with optimizations to the most CPU-hungry editor functions, the ones that run on every keypress – such as the markdown conversion and auto-linkification. We also squeezed out some tiny improvements via scope-lifting and optimizing regular expressions.

Quality of life improvements

In a small nod to code editors, we’ve repurposed Ctrl+D, which used to be the strike-through hotkey – to instead select the current word much like in Sublime Text or VSCode. Who says the inner-platform effect is all bad?

Ctrl+Click to open an internal link will no longer change the editor’s focus. This seems like a little thing, except Recollectr’s note-history saves your last selection when moving backward/forwards through your notes. If Ctrl+Click affected your selection, then it affected your selection when you returned to the note, so this could be a real pain.

macOS hotkeys have been given some attention, and no longer will macOS users be plagued with Windows/Linux standard shortcuts. Ctrl+Cmd+F for fullscreen, Cmd+G for the next search result, and more have been updated for a more native experience.

Notable bug fixes

This release also fixes some quirks that resulted in confusing or sub-par user experiences. Some things were just inadvisable, like allowing users to try to create hashtags inside of the internal linking syntax of [[]] – which looked like [[#sometag]]. Allowing confusing behavior like that chips away at the flow state Recollectr works so hard to help users maintain.

Other weird behaviors were less likely to be encountered in daily life, but were nonetheless in need of fixing. Things like exported notes using a single ~ to denote strike-through, but Recollectr’s import process would only recognize the double ~~ syntax; and imported files silently failing when the filename was over 120 characters long.

One fix that is particularly appreciated internally here is fixing Alt+Enter inside of title-synced note links. For those of you who don’t know, Alt+Enter will insert a new list item above the current one, which can be really helpful! But when this was used inside of title-synced notes, it would have no effect! We all but live inside of Recollectr checklists here, documenting and managing most aspects of development using them; so this one was a small “big win” for us.

We’ve also fixed some annoying quirks, like that auto-linkification would prevent the conversion of titled markdown links with the [text](url) format.

Markdown conversion is no longer thwarted by auto-linkification

Linked subnotes

But wait, there’s more! This release wasn’t solely about tweaks and fixes.

We finally released our first implementation of the long planned premium feature: subnote creation. This will enable users to quickly slice and dice a note down to a manageable size, splitting it across a number of linked notes all with a just a couple button presses.

Easily split a note by creating linked sub-notes
The original note
The linked sub-note

Find and replace

You’ve met find; now get acquainted with replace! Using Ctrl+H on Windows/Linux the replace box will now appear under the find box for individual notes for far quicker document updates.

Replace/replace all functionality

There are also additional improvements to the find box – most notably, the focused search result will now be the first result following the caret position, rather than starting at the top of the document. This will especially make a difference in longer documents where you’d expect to need a find feature the most – but when the focused result was always the first on the page, that meant you’d be catapulted to the top of the document – not great for maintaining flow!

Mobile

Although we’ve modified nearly every part of the mobile app too, the changes won’t be very apparent here. There are a couple notable fixes and improvements.

As far as performance goes – the notelist should load and update a tad faster now due to an optimization to configure the renderer for the note-texts only once, as opposed to once per note. This won’t be a night and day difference, but for slower devices it could be a significant improvement.

Android users will notice that the longstanding issue of the Return key in the title editor failing to focus the note body has been fixed.

Additionally on Android, another longstanding issue that caused the hover menu to fail to appear for tapped links is now (mostly) resolved. Due to Android quirks, things aren’t perfect still – but the menu should appear now in no more than two taps of the link – whereas in the past there seemed to be no rhyme of reason for when it did or did not appear, and more often it did not.

Check out the Recollectr 3.16 changelog for a full list of changes.