Dev Diary 0010 - Week of December 4th
This was a major work week. I’m trying to wrap up a couple more features and get in a few more bug fixes before I wrap up for the holidays.
At work, I am doing a major rewrite of our application(s). This marks heading into year 3 of the project. I needed to redesign the UI and workflows. I rearchitected the database, mapped all the data that needed to transfer over and reimplemented all the business logic (and in many cases extended it).I needed to rewrite an API that supports both the old way, for compatibility, and the new way. Next up is making an android app, finishing touches on the web app and implementing all our custom reports. Then on to launch phase!
This is by far the largest project I’ve ever tackled. I’ve had a few contractors come on here and there to help but the lions share has been just little old me. Yes this is a little braggy… but since I work solo the only people I can really brag to are the people who read my blog. ๐
Okay… back to the regular updates.
Lillihub
Lillihub got some attention on Friday. It had been almost two weeks since I glanced at it and wanted to knock out a couple improvements. So on Friday I spent about fours hours working on a couple of improvements and a bug fix.
Never trust data from a client side
That phrase has been drilled into my brain for more years than I can count. So, Lillihub sanitizes all the HTML from posts before rendering it. To do so I used the Deno Library ammonia and everything looked great. Except it was stripping out video tags. Woops. But luckily you can tell ammonia to whitelist some attributes.
const builder = new ammonia.AmmoniaBuilder();
builder.tags.add("video");
builder.tagAttributes.set("video", new Set(["src","width","height","controls","poster"]));
const cleaner = builder.build();
const cleaned = cleaner.clean(str);
and that fixed the videos not showing issue.
Toggle the dark theme
Next up was being able to turn on dark mode and have that override the system settings. There are plenty of articles that give some ideas on how to pull it off but this is what I did:
- Add a spot in the UI, under “Settings”, where there is a checkbox to enable dark mode. I save the user’s preference in a cookie.
- Update the CSS to include
html:not(.style-scope)[dark]that sets all the CSS variable colors to the dark theme colors - Add in an additional selector of
html:not(.style-scope)[dark]where I have my@media (prefers-color-scheme: dark)media queries - When rendering the HTML, check the cookie and if they want the dark theme, add to the HTML tag the dark attribute like so:
dark="true"
Limit # of replies display in the feeds
There have been a couple of times over the last few weeks that Lillihub got really slow on the conversations page. Turns out that some people can have really lively discussions and have lots and lots of replies. After around 100 or so it gets really noticeable. So I decided to set a default limit of 25 that a user can override if they want to. This should also allow people with slower connections set a low limit and reduce the data Lillihub is trying to send over to the device.
Unfortunately I haven’t spotted a way to limit the number of replies on a post coming back from the Micro.blog API. So I’m adding it to my mental wishlist ๐
There wasn’t too much to this one. Just:
- Add a spot in the UI, under “Settings”, where there is a number input to set the “Display comment limit”. I save the user’s preference in a cookie.
- After grabbing the post and when I start streaming the comments I check the limit and only output under that limit. See the code here
- If I did truncate the comments, add a link to view the post, which still shows all comments.
Create the most basic PWA possible
At the very least I wanted a way to launch Lillihub in a full screen way but PWA’s also have some other features I may be interested in adding in down the road. Like some basic offline support on the “Create Post” page or geolocation or notifications… ๐คฉ
But how to get started in the most barebones way…
By spending an hour and a half coloring in a little frog. Seriously… isn’t it adorable? The drawing is from a black and white sketch my sister sent me and I’m using it with her permission.
With that outta the way it was time to get started. I needed to offer up a manifest.webmanifest which I used my middleware function to do:
if(ctx.request.url.pathname == "/manifest.webmanifest") {
ctx.response.body = `{
"name": "Lillihub",
"short_name": "Lillihub",
"start_url": "/app/timeline",
"display": "standalone",
"theme_color": "#000000",
"background_color":"#000000",
"icons": [
{
"src": "lillihub-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}]
}`;
ctx.response.type = "text/json";
}
The service worker is as small as I could make it:
self.addEventListener('install', function(event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('fetch', function(event) {
});
Then just tell the HTML head where things are…
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/lillihub-512.png">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="theme-color" content="#000000">
<meta name="apple-mobile-web-app-title" content="Lillihub">
<link rel="manifest" href="/manifest.webmanifest">
<script>if('serviceWorker' in navigator){ navigator.serviceWorker.register('/sw.js') </script>
Wrap Up
So that was my week basically. I’m excited to get a little more work into Lillihub. Next week is the one month mark of making it public and I want to get a couple of things released for it in the next two weeks before I take a holiday break.
Until next time, Loura ๐
Dispatches from the fleet
What passing ships signaled back
Unfurl the messages