Short updates

Hardware I use


  • Audient iD4 MK I: It’s a robust product, the guy that sold it to me said, I’m going to thank him if I see him on the street in a couple of years. That has not happened yet, but I’m very happy with this thing, I runs flawlessly under Linux. The only gripe I have is that it only runs with the original usb cable, what’s up with that?

Portable Eletronics

  • Fairphone 4 Bought in 2022.
  • PineTime Bought in 2022.
  • Huawei FreeBuds 4i Pretty recent buy. They are fine, with more than a days worth of music for my usage and the sound quality is alright.

History of smartphones I owned.


  • Synology Diskstation DS218: I got this one for half the price, it is my main storage device. The software is nice, I mostly use the Synology Drive + Tailscale for remote access.

I did a few bike repairs yesterday:

  • Fastened one handle which suddenly went loose
  • Replaced one valve cap
  • Replaced my break pads

The breakpad replacment was pretty straightforward after getting a rough grasp from a video. For next time, I need to remember that:

  • before starting the repair, switch to the highest gear to get the chain in a favourable position for removing the tires
  • there is an easy way to get the tires out if you push back the chain holder on the back tire
  • on the front wheel, be sure to remove the cable of the dynamo by removing the cap on the wires
  • before putting the new brake pads in, push the cylinders inside the casing in to make space for the pads. Otherwise it will be hard to get them in.
  • don’t use the brake while repearing to avoid getting the cylinders stuck

Installing greetd on MNT Reform

Install Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Install greetd

# Clone the code
git clone https://git.sr.ht/~kennylevinsen/greetd

# Compile greetd and agreety.
cargo build --release

# Put things into place
sudo cp target/release/{greetd,agreety} /usr/local/bin/
sudo cp greetd.service /etc/systemd/system/greetd.service
mkdir /etc/greetd
cp config.toml /etc/greetd/config.toml

# Create the greeter user
sudo useradd -M -G video greeter
sudo chmod -R go+r /etc/greetd/

At this point you should be able to logout and back in, then start greetd with:

sudo systemctl start greetd

This should give you the same login screen, since agreety looks similar to the normal login - agetty configuration.

Install gtkgreet

# Install dependencies
sudo apt install libjson-c-dev libgtk-3-dev gtk-layer-shell-dev

# Clone the code
git clone https://git.sr.ht/~kennylevinsen/gtkgreet

# Compile
meson build
ninja -C build
meson install

Configure gtkgreet

Create /etc/greetd/environments:


Create /etc/greetd/sway-config:

exec "gtkgreet -l; swaymsg exit"

bindsym Mod4+shift+e exec swaynag \
	-t warning \
	-m 'What do you want to do?' \
	-b 'Poweroff' 'systemctl poweroff' \
	-b 'Reboot' 'systemctl reboot'

include /etc/sway/config.d/*

Edit /etc/greetd/config.toml:

# sway
command = "sway --config /etc/greetd/sway-config"


Universal Paperclips

Notes on the incremental clicker game.

  • Keeping the Processor/RAM ratio at 1:3 seems to be most efficient right now.

    • You’ll easily get needed ops by means of the Quantum Computing Module later.
    • Max ops is more important, especially since you get Kolmogorov’s Boundary which considerably increases your processing power (+500%).
  • Getting to -10000 ops with the Quantum Computing Module allows you to reset the current game.

After struggling a bit with a CSRF issue, migrating to paperless-ngx has really been as easy as changing the referenced image in the docker-compose.yml, so now I’m running that an am really happy with the results and confident of running a supported and actively developed paperless.

As for someone who has not had a lot of experience with OCR (despite my job), the quality has been superb for me.

I’m going through my folders of paychecks, rent contracts and things of that nature and scanning everything that seems important/worthy of archiving.

I would like to move on to purchase receipts and the scanner includes a template for scanning these kinds of small, non standard documents, but it has not been so far. So that’s for another day.

Yesterday I got my scanner set up in a way that I can work with it. I’m using simple-scan now which has a straight-forward interface while also providing me with almost all options that I would like to have right now.

Duplex scanning works now, paperless-ng is running and I’m in the process of migrating to paperless-ngx, which is a successor fork.

The importing of the scanned pdfs into paperless is manual work for now, but for the time being that’s fine.

For a while now, I wanted to digitalize my paper documents. I’ve been working in a company specializing in that and over the years, I’ve grown tired of these big folders in my shelf.

I got a brother ADS-2100e off ebay-kleinanzeigen and been trying to get it to scan (which it does) duplex (not yet), ideally to a folder or something (also no dice yet), so I can feed the scanned files to a fresh Paperless NG instance.

@preloads [
  tags: [
      |> where_published()
      |> order_by(desc: :updated_at),
      |> where_unpublished()
      |> order_by(desc: :updated_at)

Is this a normal preload? Looks a bit.. funny.

I have considerably improved the posting experience on mirage. The title is auto-generated and defaults to a unix-timestamp. If I set the default list to my microblog list, I can easily post a note like this. Big step forward.

Firefox seems to have exchanged the loading spinner for tabs for.. a static hourglass. It does not move. It just sits there. And I wonder every time: Did it stop loading? Did it crash? Why is this here? 🤷‍♂️

I would like to know how easy/hard it is on any given site to delete your account (BEFORE signing up). Of course, I can only know that once I’ve signed up. Has it always been like this that most sites don’t even let you delete your account with a simple “DELETE YOUR ACCOUNT” button?

I used to be a tech enthusiast, I guess I still am, but my focus has shifted away from “new & shiny” to “how can I make this last longer?”

Still a long way to go, but my intention has changed a lot, and that’s a good thing.

My development todo list for the near future:

Because of my depression, I spend a lot of my youth without partying, getting drunk. Now i’m 30, and so fucking glad I missed all that stuff. Let them label me as a weirdo, as boring, I don’t care.

It’s not a sign of sanity to fit into an insane world.

Ich versuche, mich beim Fahrrad fahren möglichst allen respektvoll gegenüber zu verhalten und die Verkehrsregeln zu beachten, außer vielleicht, wenn die Autophase an der Ampel wieder unmöglich länger ist als die Menschen/Fahrradphase. Da rutscht mir auch mal die Pedale aus. 😁

I feel like I never too the time to look at my CSS and think, “How could this be organized?” Styles always felt.. different when it came to organizing them, as if it was not that important to organize them.

Today I looked around and quickly found a thing called 7-1 pattern. It is a way of structuring your css in a folder-based way.

Seven folders are recommended plus a main.css that’s only importing the other files. The 1-part is about putting exactly one logical piece in one file. So, in layout, you might have header.css, footer.css, wrapper.css in layouts and in components button.css and post-list.css.

I won’t go into more detail but what struck me is that this is the kind of structured and opinionated structure that I enjoy so much about Phoenix. Most of the time, you don’t need to think where something will go, because there is a place for it already and all its friends are there, too.

Theme Selector on Mirage

I added a cool little theme selector to mirage! In the upper right corner you can click the colorful circles to change the theme. It gets persisted in localstorage and loaded flickerfree (unlike previous attempts with tailwind). I need my site to look different from time to time and with my current css structure that builds heavily on css vars, it’s sooo easy to build new themes!

Today I submitted a question to the Caddy Community Forum to ask about the problem that I had with my static files and only a few hours later, not one but two people submitted suggestions on how to solve it.

In the end, it was mostly me not understanding how permissions work in linux. Anyway, I learned a few things about linux and also started to really appreciate the simplicity of configuring caddy.

This is what I ended up with:

# Mirage, PostgreSQL
inhji.de {
  # handle_path will cut out the path is handling to avoid duplicate upload folders in the resulting path
  handle_path /uploads/* {
    root * /var/www/mirage/uploads

  handle {
    reverse_proxy * localhost:9100

  import security_headers

I also moved my static files to /var/www and set proper permissions.

Now my migration of mirage is complete and I can turn off the old VPS. Next up would be getting my gitea setup in order..

Okay, my move to a smaller VPS is almost done. I scrapped my public gitea instance and will be using the one on my raspi (or my diskstation). I moved mirage over, and gave Caddy a try. Everything working fine (a lot less configuration so far, plus everything is in one file), except for serving static files from another directory. Cannot figure it out.

Hm. The instructions for installing Elixir on Ubuntu from https://elixir-lang.org/install.html do not seem to work anymore. Trying to install esl-erlang wants to download a gigabyte of dependencies like icons, java and graphics-drivers lol.

For now, the solution is to do apt install elixir erlang-dev erlang-parsetools erlang-xmerl build-essential to get mirage to compile.

This has been a good day:

  • Got out of my depression by teaching installing nextcloud to a colleague
  • Got a new pair of speakers after a long headphones only drought
  • Talked to gf for an hour and never felt more connected
  • Rewired my desk so I can save some energy by turning off a few multiplugs

I’m thinking about creating a microsub server that uses miniflux for feed fetching. That would leave me with implementing the microsub api and offload the feed related tasks to a project that is pretty good at the thing that it does.

My gf just sent me a text asking me to do some printouts 😂

Please find the attachments. Don’t just find but also print it. Don’t just print it but also bring it home.

Today I added pages to Mirage. Pages are normal notes, but their title starts with an @. This makes it possible to exclude them from any normal note list or rss feed. It also allows me to show published pages in the main navigation as.. pages. It’s a really nice addition and makes Mirage a little more dynamic.

New navigation, the detail element rocks!

Today I worked on the design of Mirage and looked at how to improve the header and main navigation. In previous iterations the navigation was mostly a bootstrap-esque navbar which scrolled horizontally on smaller screens. I liked the approach because of its simplicity.

At some point I came across the 100Rabbits homepage. Their navigation uses the detail element and a few different list to build more of a block navigation that can be toggled whenever needed.

I’m a big fan of the detail element since I found out about it and I used it to build a navigation before, and I decided to try using it again. What really inspired me was the navigation on Jim Nielsen’s Blog, which does not use a details element but a tiny bit of js to toggle the navigation.

So my current navigation uses the detail element and a few lists. I’m not 100% happy with it because I am hiding the chevron of the details element which looks like some mystery meat to me but as a first iteration it’s cool.

One more thing I added were these quick fixes for the detail element by CSS Tricks. These went right into my reset.css file.

Today I reworked the hook system in Mirage. I knew from previous attempts that after creating a posts I needed to do certain things, like sending webmentions or syndicating the note to other platforms. That’s what I created the hooks module for. It will be called when a note is created or updated and will execute a list of actions.

At some point, I had lost track of what how it was supposed to work. I started executing the hook actions when publishing a note 1. I also added a hook action which published the note.

So the flow would be like this

  1. Create a new note, add some text (Hooks get executed)
  2. Update the note, add some tags (Hooks get executed)
  3. Publish the note (Hooks get executed)
  • Publish hook action gets executed, publishes the note again?
  • Goto 3.?

It’s still not really clear to me how this worked and did not blow up in my face 2, but I decided to have two separate hooks with different actions:

  1. Create/Update Hook
  • Update note tags
  • Create Syndication objects
  1. Publish Hook
  • Send webmentions
  • Syndicate note

This way, I can cleanly separate the actions which need to happen only at publishing from the actions that are only an extension of creating or updating a note.

There is still a few tests that need to be written, but this new hook module makes the whole process at least more easy to understand.

  1. Which is a fancy way of saying “Set to published_at date to now”, so technically it’s an update of the note.

  2. And I didn’t bother going down that rabbit hole.

Today I removed all code related to bookmarks from Mirage and concluded the migration from all the bookmarks into the notes table. I got the feeling that I was duplicating a lot of code while thinking how I want to approach saving syndicated versions of posts on my site.

I wanted to create a table note_syndications and an schema to go with it. But I would need to do the same thing for bookmarks as well and when comparing the notes and bookmarks schema, there was not much of a difference between the both.

So I decided to completely remove the bookmarks code. Before that, I copied the missing fields from bookmarks, bookmark_of, like_of and repost_of over into the notes schema and added a database migration for them.

I then thought of creating a migration to automatically convert all my bookmarks on the production site into notes, but there were only about 15 bookmarks to convert, so I just did it by hand. Afterwards I wrote a migration to drop all bookmark-related indexes and tables and then deleted all the code.

I hope I made the right decision and don’t create a huge big ball of complexity in the notes schema, but de-duplicating a lot of code sure felt the right thing to do.

35 changed files with 21 additions and 1212 deletions

One of the whatsapp groups I am in stopped receiving my messages. In the end, I was kicked and invited back in, and my messages went through again. The weirdest thing was probably that they could see me type and some web clients would still receive my messages. For a while I thought I was shadow banned by whatsapp. 🙄

This should be the final nail in my Whatsapp coffin.