Screenshots The RSS feed for Screenshots.

  • A really nice quality of life improvement you can make in Terminal.app: map Option-Backspace to ^W (Control-W, or \027) so that pressing it in the shell will delete one word to the left, like most other MacOS apps:

    Key mapping preference pane within Terminal, with a new key mapping with the delete key and option modifier sends control W as text
  • I’ve been working on Micropub Checkins over the last week. It’s been a bit of a rush trying to get it into a usable state for an upcoming trip. And by “usable”, I mean a form that I can tolerate, and when it comes to projects like this, I can tolerate quite a lot. It can have a really dodgy UI (which this does) and miss some really important features that are annoying to work around; but if it works, and doesn’t loose data, I’ll be fine with it.

    The main screen showing three check-ins
    The main screen showing the recent check-ins. Note the lock next to some of them. These won't be published until the locks are removed.

    The last week was dedicated to making the act of checking in distinct from publishing it. Until now, check-ins were published the minute they were entered, meaning that you cannot check-in somewhere unless you’re comfortable with people knowing where you are the minute you do. Yes, some people like it that way, but not me. And I’m aware that this’ll only be the case if people are following my check-in blog, which I’m doubtful of.

    So pressing the floating action button and choosing a check-in type now starts the flow of a new check-in that will get saved in an SQLite database. You can edit the check-in whenever you like, so long as it’s not published. Currently there’s no real way of deleting a check-in unless it’s been published. This is a bit dodgy, but it’s a good example of how tolerant I am with working around these feature gaps for the moment.

    The new styled edit screen with a title, description, rating, and a ready for check-in switch
    The newly styled edit screen. Notice the rating field, which will appear for eateries.

    Check-ins can be published by tapping the upward facing button on the main screen. Any check-in with a lock is private and will not be published until you toggle the “Ready to publish” switch in the properties. Doing so will not change the date of the check-in: it will still have the date and time that check-in was created.

    The target list screen, showing two targets: one test target, and one for my real check-in blog
    The targets are currently hard-coded but they can be turned on or off. I had a bit of trouble publishing a check-in to two targets, so I'm not sure if I'll keep multi-target publishing.

    On the subject of publishing, I had some issues with Dart’s date and time methods. The method on the DateTime class used to produce an ISO-8501 date-stamp don’t include the time-zone if the date and time is not in UTC. This is important as I want the post date and time to be as close to the check-in time as possible, and in the time-zone of the phone. DateTime knows all this, including what the time-zone we’re in. So why didn’t the developers include it in the ISO-8501 date-time string?

    This is really strange. Fortunately, ChatGPT stepped in to help out, writing a function which will add the time-zone offset to the ISO-8501 date-time string:

    String formatTimeZoneOffset(Duration offset) {
      String sign = offset.isNegative ? '-' : '+';
      int hours = offset.inHours.abs();
      int minutes = (offset.inMinutes.abs() % 60);
    
      return '$sign${_padZero(hours)}:${_padZero(minutes)}';
    }
    

    Honestly, ChatGPT has been so helpful over the past week with this project, I probably should give it a credit if I get this polished enough to release.

  • I got a little bored today so I added task progress indicators to this Obsidian roadmap thing I built for work.

    Screenshot of coloured rectangles next to a link with the text 'View In Jira' and below the heading 'Jira Tickets'
    What the task progress indicators look like.

    When a task is created, but is not yet scheduled, it appears as an outlined rectangle. It turns into a grey rectangle when it’s added to the sprint. It then changes colour as the task progresses through the software lifecycle; turning purple while it’s being developed, blue while it’s being tested, and finally green when it’s ready for release.

    They’re implemented as embedded SVG images, added directly to the note much like the span element used for status labels.

    Screenshot of the markup of the embedded SVG image next to the 'View In Jira' link
    Move the insertion point over the the SVG image to edit the markup.

    It’s nice being able to add embellishments like this. Obsidian treating notes as regular files on the file-system is a huge advantage for these sorts of automations. No need to learn how to make a plugin; just write a shell script1 that’ll output Markdown, schedule it to run a couple of times a day, and you’re good to go.


    1. The “shell script” is actually written in Go, using the really useful script package to simplify all the pipelining stuff. ↩︎

  • Back working on Micropub Checkin. Re-engineered the home page to now include a list of what would eventually be check-ins — both historical and soon to be published — complete with the check-in type emoji as the icon:

    Main screen for Micropub Checkin
    Main screen for Micropub Checkin

    The same list of emoji icons now adorn the check-in type picker as well (except for the airplane one which seems to always be shown as what I can only describe as the “Wingding” representation):

    The check-in type picker
    The check-in type picker

    I went around a bit trying to work out how best to use these emojis icons in the leading slot of the ListTile widget. I expored trying to convert them to IconData, but it turns out just using a Text widget with a large font worked well. I wrapped in in a Widget type with a fixed font-size and so far it looks quite good, at least in the emulator:

    class EmojiIcon extends StatelessWidget {
      final String emoji;
    
      const EmojiIcon({super.key, required this.emoji});
    
      Widget build(BuildContext context) {
        return Text(emoji, style: TextStyle(fontSize: 26.0));
      }
    }
    

    Also started working on a Cubit to handle state for the main page. I had a bit of trouble working ont where the soon-to-be database call to get the list of checkins should go in the cubit. After asking ChatGPT, it looks like the initializer is the best place for it:

    class CheckinListCubit extends Cubit<CheckinListState> {
    
      CheckinListCubit(): super(LoadingCheckinListState()) {
        loadCheckinList();
      }
    
      void loadCheckinList() async {
        var listOfCheckins = await read_database(); 
        emit(FoundCheckinListState(checkins));
      }
    }
    

    I’ve got some scaffolding code in place to simulate this, and so far it seems to work.

    I need to start working on the database layer and having the ability to edit and delete check-ins before they’re published. I think I’ll tackle that next.

  • Does this loading window really need to be modal?

    The Android SDK Component Installer window showing installation of an emulator image at 47% through the download
  • Hmm, either Daniel is super obsessed with the Beths (or at least posting about it), or there’s a bug somewhere. 😀

    Multiple entries in the Micro.blog timeline of danielpunkass post about the Beths being his new obsession.
  • Building F5 To Run

    At the risk of talking about something that I’ve only just started, I’d thought today I write about what I’m working on right now.

    I’ve been going through my digital archives this weekend, trying to get it into something more permenant than the portable USB drives it’s currently stored on. Amongst all that stuff is a bunch of QBasic apps and games I wrote way back when I was a kid. Over the years it’s laid dormant but I do like revising them from time to time.

    Continue reading →

  • What would be a nice addition to the spell-check suggestions menu is a brief (3-5 words) definition of the word. I always find myself choosing the wrong suggestion, and a feature like this would help a lot.

    Concept screenshot of the spell-checker menu with definitions
  • Updating Bocce Scorecard

    I didn’t get to a lot of side-project work this week, but I did have to make a large change to a project we use to track scores for our “bocce club”. So I’d though I’d say a few words about that today.

    We had our bocce “grand final” a few weeks ago, and one of the matches resulted in a tie between two players. Unfortunately, the Bocce Scorecard web-app I build could not properly handle these, which meant that I had to fix it.

    Continue reading →

  • Getting some pretty strange spam emails sent to my Gmail address (which I still use). It’s the same badly formatted multi-MIME message body with different From and Subject lines. They’re trying to get… something from me? Logins, maybe? Worst phishing attempt ever!

    Screenshot of a spam email with a bad multi-MIME message body asking for login details (I think)
  • Updates To Dynamo-Browse And CCLM

    I started this week fearing that I’d have very little to write today. I actually organised some time off over the weekend where I wouldn’t be spending a lot of time on side projects. But the week started with a public holiday, which I guess acted like a bit of a time offset, so some things did get worked on.

    That said, most of the work done was starting or continuing things in progress, which is not super interesting at this stage. I’ll hold off on talking about those until there’s a little more there. But there were a few things that are worth mentioning.

    Continue reading →

  • Follow-up from my earlier post about ChatGTP this morning, it turns out I probably should’ve RTFM:

    ChatGTP welcome screen, with the limitation 'Limited knowledge of world and events after 2021' circled in red

    Thanks to @andreab@social.lol for the tip.

  • Here’s a bit of a blast from the past. I managed to get ccedit working again. This was the original level editor for workingset.net/2022/12/2… my Chips Challenge “fan game” I’ve been working on.

    I’ve been designing a few levels for it recently, but since moving to a new Mac, the level editor I was using was going to be difficult to port. It’s QT application and the QT bindings were a pain to setup, and I rather not go through that again. I was using a Mac at the time I started working on it, but I wasn’t yet ready to go all in on MacOS. So to hedge my bets, I decided to go with QT as the UI toolkit.

    This was 5 years ago and I’m unlikely to go back to Linux, so choosing QT was a bit of a bad decision. I think if I had my time again, I’d go with something like AppKit.

    Anyway, the level editor still works but I have to log into a screen share to use it. I’d like to be able to edit levels on the machine I’m using now.

    The code for the original level editor was still around but it hasn’t been touched in ages. It’s basically an SDL application — the same graphics library I’m using for the actual game itself — and the SDL v2 bindings I’m using are still maintained, so updating those were quite easy1.

    One thing I did have to pull out was the Lua VM2. The editor was using old C Lua bindings. Better Lua VMs written in pure Go are now available, so I didn’t want to keep using these old bindings anymore. In fact, I didn’t want to use Lua at all. Lua was originally used for the level scripts, but I replaced this in favour of another language (which is no longer maintained 😒, but I’m not changing it again).

    The original CCLM Editor
    The original CCLM Editor

    So far the editor boots up, but that’s about it. I can move the cursor around but I can’t add new tiles or load existing levels. There seems to be some weird things going on with the image name lookup. I originally thought image name were case insensitive, but after looking at the image name lookup logic in the game itself, I’m not so sure.

    How much time I’d like to spend on this is still a bit of a question. It all depends whether I’d like to release the game itself in some fashion. There are still questions about whether I’m allowed to, given that the graphics are not my own. Still need to think about that.

    But in any case, good to see the old editor again.


    1. The level editor was actually using older SDL v1 bindings, but it was relatively easy to port them over to v2, although some gaps are still present. ↩︎

    2. Lua was actually the second language used by the editor. The first was a Go native TCL interpretor. ↩︎

  • Trying out Keyboard Maestro to automate some niggly things I occasionally need to do. Got my first macro working, which converts a selected string FromCamelCase to UPPER_SNAKE_CASE.

    Screenshot of a Keyboard Maestro macro which converts the selected string from CamelCase to UPPER_SNAKE_CASE

    So far I’m impressed. Looking forward to finding other things I can automate away with this.

  • On the subject of birds, I was looking at my status.lol statuses this morning. There are only a handful on there but I saw these two and it made me smile. I obviously posted them while I was looking after my sisters cockatiels last November.

    Two status.lol statuses made 2 months ago: one saying 'Can't work, Too many parrots on hand (1, which is > 0)' and the other saying 'Ok, parrots off hand. Back to work'
  • Poking Around The Attic Of Old Coding Projects

    I guess I’m in a bit of a reflective mood these pass few days because I spent the morning digging up an old project that was lying dormant for several years. It’s effectively a clone of Chips Challenge, the old strategy game that came with the Microsoft Entertainment Pack. I was a fan of the game when I was a kid, even though I didn’t get through all the levels, and I’ve tried multiple times to make a clone of it.

    Continue reading →

  • Spent the day restyling the Dynamo-Browse website. The Terminal theme was fun, but over time I found the site to be difficult to navigate. And if you consider that Dynamo-Browse is not the most intuitive tool out there, an easy to navigate user manual was probably important. So I replaced that theme with Hugo-Book, which I think is a much cleaner layout. After making the change, and doing a few small style fixes, I found it to be a significant improvement.

    I also tried my hand at designing a logo for Dynamo-Browse. The blue box that came with the Terminal theme was fine for a placeholder, but it felt like it was time for a proper logo now.

    I wanted something which gave the indication of a tool that worked on DynamoDB tables while also leaning into it’s TUI characteristics. My first idea was a logo that looked like the DynamoDB icon in ASCII art. So after attempting to design something that looks like it in Affinity Designer, and passing it through an online tool which generated ASCII images from PNG, this was the result:

    First attempt at the Dynamo-Browse logo

    I tried adjusting the colours of final image, and doing a few things in Acorn to thicken the ASCII characters themselves, but there was no getting around the fact that the logo just didn’t look good. The ASCII characters were too thin and too much of the background was bleeding through.

    Other attempts at the Dynamo-Browse logo

    So after a break, I went back to the drawing board. I remembered that there were actually Unicode block characters which could produce filled-in rectangles of various heights, and I wondered if using them would be a nice play on the DynamoDB logo. Also, since the Dynamo-Browse screen consists of three panels, with only the top one having the accent colour, I thought having a similar colour banding would make a nice reference. So I came up with this design:

    Final design of the Dynamo-Browse logo

    And I must say, I like it. It does look a little closer to low-res pixel art than ASCII art, but what it’s trying to allude to is clear. It looks good in both light mode and dark mode, and it also makes for a nice favicon.

    That’s all the updates for the moment. I didn’t get around to updating the screenshots, which are in dark-mode to blend nicely with the dark Terminal theme. They actually look okay on a light background, so I can probably hold-off on this until the UI is changed in some way.

  • Ok, thank you for the insistent reminders, Patreon. I know my subscription for CGP Grey is coming up for renewal. You only need to tell me once. 🤦‍♂️

  • Project Exploration: A Check-in App

    I’m in a bit of a exploratory phase at the moment. I’ve set aside Dynamo-Browse for now and looking to start something new. Usually I need to start two or three things before I find something that grabs me: it’s very rare that I find myself something to work on that’s exciting before I actually start working on it. And even if I start something, there’s a good chance that I won’t actually finish it.

    Continue reading →

  • Flight home from the US is next week. I’m hoping for an uneventful trip. The news is not cooperating though. 😏

  • Dynamo-Browse Running With iSH

    Bit of a fun one today. After thinking about how one could go about setting up a small dev environment on the iPad, I remembered that I actually had iSH installed. I’ve had for a while but I’ve never really used it since I never installed tools that would be particularly useful. Thinking about what tools I could install, I was curious as to whether Dynamo-Browse could run on it. I guess if Dynamo-Browse was a simple CLI tool that does something and produces some output, it wouldn’t be to difficult to achieve this. But I don’t think I’d be exaggerating if I said Dynamo-Browse is a bit more sophisticated than your run-of-the-mill CLI tool. Part of this is finding out not only whether building it was possible, but whether it will run well.

    Continue reading →

  • Google Photos came up with this amusing suggestion today.

    Suggestion to rotate photos of birds

    Just to be clear: it was the birds that were rotated, not the camera. 😀

  • Audax Toolset Version 0.1.0

    Audax Toolset version 0.1.0 is finally released and is available on GitHub. This version contains updates to Dynamo-Browse, which is still the only tool in the toolset so far.

    Here are some of the headline features.

    Adjusting The Displayed Columns

    The Fields Popup

    Consider a table full of items that look like the following:

    pk           S    00cae3cc-a9c0-4679-9e3a-032f75c2b506
    sk           S    00cae3cc-a9c0-4679-9e3a-032f75c2b506
    address      S    3473 Ville stad, Jersey , Mississippi 41540
    city         S    Columbus
    colors       M    (2 items)
      door       S    MintCream
      front      S    Tan
    name         S    Creola Konopelski
    officeOpened BOOL False
    phone        N    9974834360
    ratings      L    (3 items)
      0          N    4
      1          N    3
      2          N    4
    web          S    http://www.investorgranular.net/proactive/integrate/open-source
    

    Let’s say you’re interested in seeing the city, the door colour and the website in the main table which, by default, would look something like this:

    Continue reading →

  • Working on recording that how-to video again this morning. Managed to get a take that I’m happy with. This is after maybe 35 recordings in total which didn’t work (wow, video is not easy). Now downloading the trial version of Final Cut Pro to try and edit the thing.

    Screenshot of 25 recorded takes.
  • Overlay Composition Using Bubble Tea

    Working on a new feature for Dynamo-Browse which will allow the user to modify the columns of the table: move them around, sort them, hide them, etc. I want the feature to be interactive instead of a whole lot of command incantations that are tedious to write. I also kind of want the table whose columns are being manipulated to be visible, just so that the affects of the change would be apparent to the user while they make them.

    Continue reading →

  • 🎉

    Notification of PagerDuty email stating that I am off call
  • Intermediary Representation In Dynamo-Browse Expressions

    One other thing I did in Dynamo-Browse is change how the query AST produced the actual DynamoDB call.

    Previously, the AST produced the DynamoDB call directly. For example, if we were to use the expression pk = "something" and sk ^= "prefix", the generated AST may look something like the following:

    AST from the parse expression

    The AST will then be traversed to determine whether this could be handled by either running a query or a scan. This is called “planning” and the results of this will determine which DynamoDB API endpoint will be called to produce the result. This expression may produce a call to DynamoDB that would look like this:

    Continue reading →

  • Saw someone at work use Numi to show some maths so I’m giving it a try. Only just started using it but I already like it. Feels very similar to Tot and Boop: a small MacOS utility that fits nicely in that middle-ground between Calculator and a spreadsheet.

    Screenshot of Numi
  • It could be that I’m just an old fogie that doesn’t like whimsy, but chalk me up as someone who doesn’t like the wiggling seek bar in Android’s playback notification.

  • Those “Accept Yours” & “Accept Theirs” buttons in GoLand’s conflicts dialog are a bit of a tease. Might be that I’m missing something (which is possible) but I though a file appearing here means that I manually need to review it. Would anyone blindly accept changes like this?

    Accept Yours, Accept Theirs & Merge buttons in Conflict resolution dialog
  • I’ve been seeing this message an awful lot recently when I’m trying to use mobile data. I originally thought it was Telstra, but now I suspect it’s Android, as restarting the phone seemed to have fixed it.

  • The names for GitHub Codespaces are randomly generated, but I kinda like the one chosen for this website repo. Seems fitting in a way.

  • WWDC Videos In Broadtail

    Some more work on Broadtail. This time, I added the ability to use it to download Apple WWDC videos.

    The way it works is based on the existing RSS feed concept. In order to get the list of videos for a particular WWDC year, you “subscribe” to that by setting up a feed with the new “Apple Developer Videos” type. The external ID is taken from the URL slug of the web-site that Apple publishes the session videos. For example, for WWDC 2021, the external ID would be “wwdc2021”.

    Continue reading →

  • Feed Rules In Broadtail

    Generally, when there’s a video that I’m interesting in watching, I take a look at Broadtail to see if it’s available. When it is, I go ahead and download it.

    However, some videos take a long time to download — we’re talking 10 hours or so — and they’re usually published when I’m not looking, like during the night when I’m asleep (thank’s time-zones). So I’d thought it would be nice for Broadtail to kick off the download for me when the video shows up in the feed.

    Continue reading →

  • Oh, I hope not.

    An exceeding long download estimation
  • New AWS Tools Commands

    For a while now, I’ve been wanting some tools which would help manage AWS resources that would also run in the terminal. I know in most circumstances the AWS console would work, but I know for myself, there’s a lot of benefit from doing this sort of administration from the command line.

    I use the terminal a lot when I’m developing or investigating something. Much of the time while I’m in the weeds I’ve got a bunch of tabs with tools running and producing output, and I’m switching between them as I try to get something working across a bunch of systems.

    Continue reading →

  • This is by far the most useful quick action I’ve made in Automator. It generates a UUID, and places it in the pasteboard. I’ve got it bound to Ctrl+Opt+Cmd+U and I’ve been using it constantly over the last week (writing a lot of tests with test data).

  • Some More Updates of Broadtail

    I’ve made some more changes to Broadtail over the last couple of weeks.

    The home page now shows a list of recently published videos below the currently running jobs.

    Clicking through to “Show All” displays all the published videos. A simple filter can be applied to filter them down to videos with titles containing the keywords (note: nothing fancy with the filter, just tokenisation and an OR query).

    Finally, items can now be favourited. This can be used to select videos that you may want to download in the future. I personally use this to keep the list of “new videos” in the Plex server these videos go to to a minimum.

    Continue reading →

  • Feeds In Broadtail

    My quest to watch YouTube without using YouTube got a little closer recently with the addition of feeds in Broadtail. This uses the YouTube RSS feed endpoint to list videos recently added to a channel or playlist.

    Feed listing, in all it's 90's web style glory.

    There are a bunch of channels that I watch regularly but I’m very hesitant to subscribe to them within YouTube itself (sorry YouTubers, but I choose not to smash that bell icon). I’m generally quite hesitant to give any signal to YouTube about my watching habits, feeding their machine learning models even more information about myself. But I do want to know when new videos are available, so that I can get them into Plex once they’re released. There is where feeds come in handy.

    Continue reading →

  • Some Screenshots Of Broadtail

    I spent some time this morning doing some styling work on Broadtail, my silly little YouTube video download manager I’m working on.

    Now, I think it’s fair to say that I’m not a designer. And these designs look a little dated, but, surprisingly, this is sort of the design I’m going for: centered pages, borders, etc. A bit of a retro, tasteless style that may be ugly, but still usable(-ish).

    Continue reading →