-
Browser History Explorer | 2024 →
A macOS desktop app to explore your browsing history by date. -
Search Params (Raycast Extension) | 2023
An extension to ease composing or analyzing URLs with many search parameters (also known as query parameters). -
Mealime/Siri integration | 2022 → 2023
An unofficial Mealime API wrapper for usage with Siri via Apple Shortcuts. -
Personal Website (current iteration) | 2020 →
The website you're looking at right now! I recently added a project database, which you're seeing right here. -
Spranki | 2020
A suite of tools I used to extract unknown Swedish words from books, web- and televesion content, to practice them with Anki. -
Dash | 2020
A "new tab" dashboard with widgets driven by personal data from various sources, to keep track of your commitments & habits. -
Retrospective | 2019 →
A data-driven diary concept, which imagined repurposing personal data from sources such as Google location history, Spotify playback history, calendars, task managers and health trackers. -
No Feed | 2018
A concept and proof of concept for a more intentional way to access social media profiles. -
Vocabulary.com Tools | 2018 → 2020
A suite of tools to enhance English language learning on vocabulary.com. -
Movie Visualization | 2018 → 2019
An interactive visualization of movies I watched during 2015-2018, with some commentary. -
Klimzaal Hungaria | 2014 → 2024
A concept website for a climbing gym. -
Pixpaint | 2011
A paint program for the TI-83/84 Plus graphing calculator.
. If you're interested in extending operating system or browser support, check out the [notes for contribution](https://codeberg.org/thor/browser-history-explorer/src/branch/main/CONTRIBUTING.md).](/static/be15ac78c51dad3cf5c219da0f49eb11/8c5e7/screenshot_758a6c44e9.png)

. It abstracts away cookie-based authentication into a simple fixed token, so the API can be used from an iOS Shortcut and other simple HTTP clients.
Amongst others, I used this Shortcut to build a grocery list integration with Siri: I can now add items to my grocery list without picking up my phone, and I often do!
In February/March 2023, I rewrote the Node.js app into Deno, extended its functionality, and released it publicly on GitHub.](/static/62b9c0aad47fbff82532afe34751ab04/b21a6/mealime_6d4894e3c8.png)
. It started off with some simple static pages and articles sourced from Contentful. It was was a complete technical reboot when compared to the previous iteration, a PHP "monolith" built with Grav CMS.
In early 2023, I merged in a "portfolio database" experiment using [Strapi](https://strapi.io/), leading to the ["projects" page](/projects/).
In early 2024, I added [a "notes" section](/notes/) using an Obsidian vault.
The site is, a will always be, a work-in-progress, and many ideas remain unimplemented. I hope to add RSS support next, perhaps after improving permalinks.](/static/fe8c55752036049dd771cfb6c0aa4010/29338/Clean_Shot_2023_05_07_at_19_08_11_2x_2ef47f701f.jpg)
 Swedish-English dictionary that worked on my Kindle, so that if I didn't know a word, I could just long-tap it to see a definition and translation. This was great!
However, I wanted to keep practicing the words I didn't know using the spaced repetition flash card tool [Anki](https://apps.ankiweb.net/).
I made a custom Anki card template that would show the surrounding sentence from a word that I looked up, but omit the word itself, and show its translation too. The other side then filled in the correct word. Another template showed the word with full sentence context on one side, and the translation on the other.
Finally, I automated the creation of these cards by writing a tool that extracted the Kindle dictionary lookups, and converted them into Anki CSVs corresponding to my card templates (as I had learned from a previous [dictionary-related project](/projects/vocabulary-com-tools/), the Kindle's dictionary lookups were stored in a SQLite database that was transparently accessible through the Kindle's USB storage view).
After some usage, I liked this system, and I extended the tool with ways to ingest words and sentences from various other places with Swedish content:
- One function pulled dictionary saves from the Lingoal/SVT Språkplay API (a learning-focused app with subtitled Swedish television content available at the time).
- In another workflow, I selected sentences on the web on my iPhone, and shared them with an iOS Shortcut. The Shortcut then prompted me to select a word of interest, after which it HTTP-posted the context (url, sentence, and word) to an Airtable database. The Anki tool could also ingest this.
The Språkplay integration gave this project its name: Språkplay + Anki = Spranki.](/static/e20ebf5c15a6c75b88ae4e2a53e724d0/e9d4a/Clean_Shot_2024_07_22_at_20_21_56_2x_a3b3f0427c.png)
 for my personal projects at the time, and the [Harvest API](https://help.getharvest.com/api-v2/) for my Columbia Road work projects at the time.
- Time goals, which I set in the dashboard, for projects I wanted to commit to at the time. For example, "I want to learn Swedish for 6 hours per week" would be a goal.
The widget then showed my progress towards the goal of each project in a progress bar, dividing the time goal equally over each weekday. With colors, it visually represented how much I was on- or off-balance:
- <span style="color: blue;">Blue</span> meant: completed according to schedule
- <span style="color: red;">Red</span> meant: overdue, should have been done.
- <span style="color: gold;">Yellow</span> meant: to be done today.
- <span style="color: green;">Green</span> meant I "overshot" the goal, or did more than planned given this distribution (can be a bad thing!).
I used this for about two months, and I felt it did help me to achieve a better balance. A new tab page is one you see often, so I would get reminded of my undershooting and overshooting all the time, which would steer my behavior.
I wanted to take this step further, according to my original designs: what if you didn't just set a fixed number of hours as a project goal for a week/month, but would also integrate it with your digital calendar?
Then the tool would help you in more ways:
- When planning, you could add, re-scale and reshuffle calendar events for each project, until each project reached the desired quota of time: _"Is your calendar sound? Does it match your intentions?"_
- Your expectations for a day would be more fine-tuned: the dashboard wouldn't nudge you to work on a project on Tuesday or Wednesday if you wanted to complete it all Thursday.
- When your calendar changed, as it often does, you would see the impact it had on your overall distribution of time for a week/month, and you'd be better informed to make resulting changes.
But while getting somewhere, I had not finished this part of the implementation. Along the way though, I saw more opportunities for this Dashboard that I did try out.
## The "Streaks" Widget
Not everything ought to take a distinguishable number of hours in a weekly plan. A habit can be a small thing, like practicing on Duolingo for a few minutes each day. For these types of commitments, I added a "streaks" widget.
I picked two external services that I wanted to use daily at the time. Both had a "streaks" concept of their own.
- First, there was Vocabulary.com, the object of my [Vocabulary.com Enhancer tools](/projects/vocabulary-com-tools/). The entry would also link to my last-practiced list, so I could directly jump into the next session.
- Next, there was Readup.com (for which I didn't work yet at the time). Similarly, it showed my last Starred article.
Neither of these had a public API, however. This sparked some creative web engineering to retrieve arbitrary authenticated web app HTML from these sources. I used a web extension to proxy privileged requests with my cookies/credentials to my "new tab" page, which inconveniently was a regular web page. It needed to be a regular web page, because I relied on the Service Worker's Cache API to cache requests for quick loads, and that was not supported in extension pages at the time.
## The book widget
The last widget I added was the book widget. I didn't only want to track time spent on my computer, but also time spent learning otherwise: through books, or audio books, and bring it fairly into consideration along with the rest.
Using the same proxy extension, I could parse my progress on audio books with Audible's web app (see [this post](/articles/regex-puzzle-either-and/) on a regex challenge therein). I could then set a time goal to finish my book by a certain date. I also worked on fetching progress from Kindle's web app, but if I remember correctly, couldn't sufficiently reverse-engineer the web app to extract my progress.
## Conclusion & legacy
I used a development build of this project for some months as my daily-driver new tab, and enjoyed it! It helped me. However, after some time, I got stability problems with some widgets. Building unofficial APIs for personal data through web scraping does not guarantee stability, as HTML structures might change at any point. Other work encroached; I submitted my thesis, became a full-time employee at [Columbia Road](/work/#Columbia-Road), and _Dash_ faded out of focus.
I've re-pondered this concept sporadically ever since, so I might revisit it at some point.
### Potential
About a year after shelving this project, I learned about [Potential](https://potential.app), a humane tech start-up building a habit _forming_ app aligned well with what I had dreamed of for Dash. I tried out the app, and quickly started enjoying it. Potential also had a (much better designed) widget with automatically-updating streak counts, such as for Duolingo. I contacted their CEO, to present _Dash_ as a reference for a possible expansion of Potential into the web browser. Some discussion ensued.
Not much later, Potential opened a role for a Software Engineer. I got the job! (at least, for a few fun months, until it got cancelled by [some complicated times](https://welf.substack.com/p/its-over-were-so-back-potential-2024))](/static/ecbfe0e503c3303117a97240b61549ad/e103f/dash_demo_0b87f276f2.png)
 has since done, in part, with automated prompts.
It might also be useful for research purposes, to figure out what you did on a certain day (for whatever reason you may have!). I've since implemented a tool to [do this with browser history](/projects/browser-history-explorer/).
More broadly, with more data and more complicated app logic, it could help you extract useful insights from personal data. The independent app [Exist](https://exist.io/) is doing this (I'm happy to see it still is, in 2024, at the time of writing), and big tech health apps are generally doing this with your health data.
Finally, one more angle for an app that requires personal data to be accessible, is to _preserve_ personal data. Cloud services that contain much of our data today are likely to, at some point, be shut down or transformed with loss. This [old X thread](https://x.com/th0rgall/status/1640370570486218753) provides some more context.](/static/6ce477316e25187e8c5b3e1843713339/b3d3a/retrospective1_ec6372fb7c.png)


.](/static/cf0801a66332f6fb4aa8e0d6aa13066e/d0392/movieviz_tiles_12257f373b.jpg)

 to turn any pixel on the screen on or off. By that point, I had only used the graph function as I had been taught: to plot mathematical functions on a X-Y axis. What if I could leverage this command to draw "freehand" on the screen? Could I recreate a kind of MS Paint?
The core of the program was a "cursor" that could be moved using the arrow keys, together with "ink on" and "ink off" buttons to start and stop drawing under the cursor. The program also did the necessary setup to remove axes and other unwanted visual clutter from the screen before drawing. Eventually, this was all wrapped with a multi-level menu-based UI, which allowed...
- displaying help text
- inserting text on the canvas in two sizes
- drawing shapes such as lines, circles and squares
- opening and storing drawings in slots
- "archiving" picture slots to free up storage
All of these were existing calculator functions that I made more accessible by linking them to the current cursor position, rather than requiring X,Y coordinates by text input for them to be inserted.
The program of 263 lines was built during, between and after classes, and after school.
In June 2011, I figured out how to connect my calculator to my computer, to transfer programs and files back and forth. I made a backup of the program, and collections of stored "pictures". Somewhere in 2024, I got reminded of these files, and found a [simple web-based TI emulator](https://www.cemetech.net/projects/jstified/) that could work with them. That's how you're seeing one of my authentic 2011 Pixpaint drawings today.](/static/1f85b22371af374bec7dba01ef8c828f/b5591/Clean_Shot_2024_07_23_at_01_47_25_2x_cc0ad97752.png)