Ben Crowder

Blog: #electron

3 posts :: tag feed :: about the blog :: archive

Lector intro

Yet another entry in the ignominious series talking about my personal productivity tools.

Lector is a reading app for macOS. It’s an Electron app for now. The name comes from the Latin (for someone who reads), with a homophonic hat tip to Hannibal. It came about from wanting a minimalist app that would let me read PDFs and scanned books in dark mode and keep track of my spot across multiple books.

Overview

A Lector book is just a directory full of images. (PDFs have to be split up into image files first, so I have a small script to do that.) When the app starts up, it looks at the book list directory to see what books are available. It also has a JSON file to track where I’m at on each book (which page and which part of the page), what size the window is, which book I last had open, etc.

The app itself looks like this, on an empty desktop to show how I usually use it:

lector.png

No title bar, since I find that distracting. And the page images are scaled by default to fit the window width.

Hitting g / brings up a brief panel showing the books that are in the system, with alphabetized keys to get to them (so g a to go to the first, g b for the second, etc.). When I’m done reading a book, I delete its directory, so these mappings change fairly regularly.

j and f and double-clicking all go to the next page; k and d both go back to the previous page. J and K move up and down the page (in larger jumps), and the mouse can also be used to scroll. (I find that I mostly use the mouse for scrolling and f/d for page navigation, but every once in a while I’ll use the other keys.)

As you can see in the screenshot, it defaults to dark mode, with slightly lowered contrast for easier reading. i inverts the colors and s toggles the higher contrast view.

How I use Lector

I use it when I want to read a book I’ve scanned (usually with Scanbook). I haven’t used it as often lately, but I fully expect that to change soon. (It’s been very handy for reading textbooks.)

I’ve found that I prefer the window size shown in the screenshot, wide (so that the text is large enough) with just enough vertical room for a paragraph or so (since reading in smaller chunks is easier).

The future

I’d like to move off Electron at some point, probably to a native Swift app. Having it support PDFs directly (or splitting them up itself) would be nice, and having a way within the app to remove books would also be good.

Finally, I’d love to add EPUB support at some point. (I haven’t yet found a desktop EPUB reader I like. Marvin’s great on iOS, though.)


Reply via email or via office hours

Quill intro

Another entry in the eternally long series talking about my personal productivity tools.

Quill is a quick entry app for macOS and is effectively a desktop version of Gate. It’s an Electron app for now. The name comes from quills being used to write.

Overview

Not much to show here, actually. It looks like this (and the minimalism is very much intended):

quill.png

There’s a textbox for writing and a word counter at top.

Once a payload is written, all the subsequent functionality is controlled via keyboard shortcuts: an app-wide prefix (ctrl+l — that’s an L) followed by the destination. v goes to Vinci, l goes to Liszt, j goes to my journal in Vinci, and b goes to my blog in Slash. (On my laptop, I prefer this to the buttons I used in Gate.)

The payload and action are then sent to an API in Gate, which does the actual sending to the destination systems.

How I use Quill

I leave it open all the time and use a global keyboard shortcut (configured in Hammerspoon) to bring it to the front.

Beyond the integration with my other systems, I often use Quill as a temporary scratchpad for drafting documents — emails, Slack chats, etc. — usually because the type size is larger. I also use it as a scratchpad for copy-pasting rich text into plain text.

The future

I’d like to move off Electron at some point, probably to a native Swift app.


Reply via email or via office hours

Liszt intro

First in the series introducing my personal productivity tools. Buckle up, this is going to be nerdy. And long.

Liszt is my to-do list app. Named after the composer, though I regret it a little since I butcher his name by pronouncing it lisht to differentiate it from the ordinary list. Heresy. The next version will have a better name, though. It’s a Python app running on Django.

Disclaimer: I don’t think this app is perfect. (Or any of the other tools I’ll talk about, for that matter.) I’ll describe things as they are, acknowledging here that there’s a lot of room for improvement.

Overview

This is what the dashboard looks like, populated with some dummy data:

liszt-1.png

And on mobile, where the controls move to the bottom for easier access:

liszt-1mobile.png

The top bit is my stats panel, with the data pulled in from my other tools’ APIs. Daily writing counts, daily words left, total words written on the novel (all three from Storybook), daily pages left (from Bookshelf), and daily goals left (from Momentum). I’ll cover those tools later.

There’s also a slide-in menu on the side, with my most commonly used top-level lists:

liszt-2.png

Double-clicking on a list item opens up an edit panel, which also allows me to move the item to another list with some commonly used lists included as buttons (this whole panel is kind of clunky and needs improvement):

liszt-7.png

Payload syntax

The basic idea behind Liszt (and this is common to many of my apps) is the text-based payload, which enables some nice cross-app integrations (more on this when I cover Gate and Quill). Adding items looks like this:

liszt-3.png

A Liszt payload (the text entered into the add tray) has one item per line, with optional blank lines and optional list specifiers. If there’s no specifier, it’ll assume the current list if there is one, otherwise it’ll default to ::inbox. (I use the double-colon prefix to mark lists, with a slash to specify sublists.) Here’s a fuller example of the syntax, again with dummy data:

Process email :5
Review the merge requests :10

::work/notifications
Read up on Python futures ::: https://docs.python.org/3/library/concurrent.futures.html
Refactor [::work/notifications/refactor]
Write up the design doc

The first two items (which have belt-mode durations, I’ll explain those in a minute) would go into the ::today list (which is the dashboard list). The last three items would go into the ::work/notifications list, as pictured here:

liszt-3b.png

Of these, the first line sets a subtitle by putting it after the triple-colon marker. I use this all the time.

The second line is a symlink of sorts, pulling in the top item from the linked list (different meaning here) and showing it in place, with the Refactor text shown as the subtitle. I used to use this more often but haven’t as much lately.

You can also see that this list has a child list (::work/notifications/refactor).

Belt mode

liszt-4.png

If an item has a duration marker included, that triggers belt mode (ala conveyer belts), as evidenced by the new bar at the top of the screen in the image above.

Brief backstory: I initially wrote an Electron app called Belt that did the same sort of thing, then a few months ago ported it to Go as a menubar app. Shortly after I finished that, I realized it would make much more sense in Liszt and brought the functionality in.

And what is that functionality? It’s just an easy way to time tasks from the list. When I hit Start, it switches into belt mode (also changing the favicon so I can tell that it’s running and turning on focus mode so I can only see the task I’m actively working on):

liszt-5.png

When the timer runs out, it plays a sound and brings up a panel allowing me to continue on to the next item in the list, stop belt mode, or add more time to the timer. (There are also keyboard shortcuts for all of this.)

liszt-6.png

How I use Liszt

On my laptop, I have Liszt open in Firefox as a pinned tab. On my phone, I have it saved to my homescreen as a PWA.

Every morning I go through the main lists and move the items I’m going to work on to the today list. I then work out of the today list the rest of the day, opening it often.

I use belt mode most days, primarily to help me stop avoiding tasks I don’t really want to work on (but that still need to be done).

The future

Lately I’ve grown enamored of the idea of storing data as plain text files in directories, rather than using an actual database like Postgres or Mongo. There are plenty of apps where this doesn’t make sense, but for personal, small tools, it works nicely, so I’m planning to migrate Liszt off SQLite to plain text, and I am very excited about it. Yes, I am that kind of a person.

While Django is fine (we use it at work and I love it), I’m planning to move to FastAPI, which I’m already using for Ditto and Arc. It’s a bit faster and feels more lightweight. I think in my mind I mostly use Django because of the ORM and admin; once I’ve given that up, the baby goes out with the bathwater.

I’m also looking forward to simplifying things, removing vestigial functionality, and sanding down as many of the friction points as I can.


Reply via email or via office hours