<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>coding &amp;mdash; sknob’s fediblog</title>
    <link>https://noblogo.org/sknob/tag:coding</link>
    <description></description>
    <pubDate>Sun, 26 Apr 2026 21:48:23 +0000</pubDate>
    <item>
      <title>sknob/music, LLM Edition (not)</title>
      <link>https://noblogo.org/sknob/sknob-music-llm-edition-not</link>
      <description>&lt;![CDATA[#blogpost #coding&#xA;&#xA;So the other day, I was playing around with an entirely different UI paradigm for my music site, and got pretty far along, and then I hit a snag.&#xA;&#xA;I searched and scoured the slop-riddled Web and didn’t find answers to my questions.&#xA;&#xA;After a while, that duck.ai link started tugging at my willpower...&#xA;!--more--&#xA;And then I did the unthinkable and clicked on it. I asked whatever &#34;AI&#34; DDG is using how to do the thing I was trying to do, and it spat out an answer that worked.&#xA;&#xA;It was the first time since the early days of 2022 that I had used an LLM, but I still felt dirty and ashamed. I tried to justify what I had done by the fact that I had really tried to find the solution on my own. And by the fact that I had already decided I had no intention of releasing the version I was trying to finish.&#xA;&#xA;I also justified my lapse by telling myself I could understand the code the LLM had plagiarized. A couple of javascript functions, maybe 15 lines of code.&#xA;&#xA;I went on doing other stuff, and at one point I realized I wanted the LLM code to do something slightly different, and so I thought no problem, I should be able to easily modify it.&#xA;&#xA;And that’s when I realized that I absolutely could not. I stumbled in the dark for a while, to no avail.&#xA;&#xA;In the end:&#xA;&#xA;I trashed the LLM functions, and did manage to work everything out following examples on W3Schools and MDN docs, etc.&#xA;While doing so, and despite the fact that I had tried and failed to modify the LLM code for a lengthy amount of time, I realized that I couldn’t remember precisely any of the LLM code and logic. I hadn’t learned anything. In fact, as I’m writing this, I realize I can’t even remember what that code was meant to do.&#xA;And despite being over-informed on LLMs and how they can fuck with your brain, I grossly overestimated my degree of control of the situation and understanding of the generated code.&#xA;&#xA;All in all, an eye-opening and brain-deadening experience and experiment.&#xA;&#xA;And just to be clear, I will never, ever release anything done with the help of generative &#34;AI&#34;, be it code, art or music. Simply as a matter of principle, morals, ethics, whatever you want to call it. If I do, I am probably being held hostage, or having a stroke.]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>So the other day, I was playing around with an entirely different UI paradigm for my music site, and got pretty far along, and then I hit a snag.</p>

<p>I searched and scoured the slop-riddled Web and didn’t find answers to my questions.</p>

<p>After a while, that <em>duck.ai</em> link started tugging at my willpower...

And then I did the unthinkable and clicked on it. I asked whatever “AI” DDG is using how to do the thing I was trying to do, and it spat out an answer that worked.</p>

<p>It was the first time since the early days of 2022 that I had used an LLM, but I still felt dirty and ashamed. I tried to justify what I had done by the fact that I had really tried to find the solution on my own. And by the fact that I had already decided I had no intention of releasing the version I was trying to finish.</p>

<p>I also justified my lapse by telling myself I could understand the code the LLM had plagiarized. A couple of javascript functions, maybe 15 lines of code.</p>

<p>I went on doing other stuff, and at one point I realized I wanted the LLM code to do something <em>slightly</em> different, and so I thought no problem, I should be able to <em>easily</em> modify it.</p>

<p>And that’s when I realized that I absolutely could not. I stumbled in the dark for a while, to no avail.</p>

<p>In the end:</p>
<ul><li>I trashed the LLM functions, and did manage to work everything out following examples on W3Schools and MDN docs, etc.</li>
<li>While doing so, and despite the fact that I had tried and failed to modify the LLM code for a lengthy amount of time, I realized that <em>I couldn’t remember precisely any of the LLM code and logic</em>. I hadn’t learned <em>anything</em>. In fact, as I’m writing this, I realize I can’t even remember what that code was meant to do.</li>
<li>And despite being over-informed on LLMs and how they can fuck with your brain, I grossly overestimated my degree of control of the situation and understanding of the generated code.</li></ul>

<p>All in all, an eye-opening and brain-deadening experience and experiment.</p>

<p><em>And just to be clear, I will never, ever release anything done with the help of generative “AI”, be it code, art or music. Simply as a matter of principle, morals, ethics, whatever you want to call it. If I do, I am probably being held hostage, or having a stroke.</em></p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-llm-edition-not</guid>
      <pubDate>Sun, 05 Apr 2026 10:12:06 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.4.0 Release Notes, Fetch Edition!</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-4-0-release-notes-fetch-edition</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;In the first post in this series, I explained why I used PHP to generate the playlist of my new hand-crafted music site from a large-ish XML file, instead of doing it locally like I used to (damn you Chrome and Firefox for dropping XSLT support!)&#xA;&#xA;Thing is, depending on the speed of your device and your internet connection, it takes a few short seconds for PHP to do it’s thing on the server, before sending the result in one go to your browser. &#xA;&#xA;And this slight delay has been nagging at me since day one.&#xA;!--more--&#xA;So I’ve been thinking of ways to load the very lightweight page skeleton, and then retrieve the rendered playlist from the server.&#xA;&#xA;And I finally took the time to figure out how to do it, using the javascript Fetch API to fetch the PHP code in a separate file once the skeleton loads. Which meant rethinking a bit of code for everything to keep working like before (basically making sure the data is loaded before calling anything critical).&#xA;&#xA;After ironing out the kinks, I’m pretty sure I have a version that works! &#xA;&#xA;The question now is, do I actually like it better? It does have the following advantages:&#xA;&#xA;The site loads instantly, even on a slow device.&#xA;There’s a fun little loading animation. I went with an austere design after years of visual excess, so the animation reintroduces a touch of whimsy.&#xA;When you click on a link to an album or a song from somewhere else like here (or your Mastodon feed), you get a bit of visual context before the page scrolls down to the target album or song.&#xA;&#xA;I did a quick poll on Mastodon, which came out in favor of NOT going this route. Still, if you’re reading this, it probably means I decided to roll it out anyway.&#xA;&#xA;It’ll be easy enough to roll back if I change my mind or if it proves to be troublesome or unpopular.]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p><a href="sknob-music-v5-release-notes" rel="nofollow">In the first post in this series</a>, I explained why I used PHP to generate the playlist of my new hand-crafted <a href="https://sknob.fr/music/" rel="nofollow">music site</a> from a large-ish XML file, instead of doing it locally like I used to (damn you Chrome and Firefox for dropping XSLT support!)</p>

<p>Thing is, depending on the speed of your device and your internet connection, it takes a few short seconds for PHP to do it’s thing on the server, before sending the result in one go to your browser.</p>

<p>And this slight delay has been nagging at me since day one.

So I’ve been thinking of ways to load the very lightweight page skeleton, and then retrieve the rendered playlist from the server.</p>

<p>And I finally took the time to figure out how to do it, using the javascript Fetch API to fetch the PHP code in a separate file once the skeleton loads. Which meant rethinking a bit of code for everything to keep working like before (basically making sure the data is loaded before calling anything critical).</p>

<p>After ironing out the kinks, I’m pretty sure I have a version that works!</p>

<p>The question now is, do I actually like it better? It does have the following advantages:</p>
<ul><li>The site loads instantly, even on a slow device.</li>
<li>There’s a fun little loading animation. I went with an austere design after years of visual excess, so the animation reintroduces a touch of whimsy.</li>
<li>When you click on a link to <a href="https://sknob.fr/music/?cities_album" rel="nofollow">an album</a> or <a href="https://sknob.fr/music/?cities" rel="nofollow">a song</a> from somewhere else like here (or your Mastodon feed), you get a bit of visual context before the page scrolls down to the target album or song.</li></ul>

<p>I did a <a href="https://mamot.fr/@sknob/116261604312026253" rel="nofollow">quick poll on Mastodon</a>, which came out in favor of NOT going this route. Still, if you’re reading this, it probably means I decided to roll it out anyway.</p>

<p>It’ll be easy enough to roll back if I change my mind or if it proves to be troublesome or unpopular.</p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-4-0-release-notes-fetch-edition</guid>
      <pubDate>Sun, 22 Mar 2026 10:13:58 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.3.1 Release Notes, mediaSession Edition!</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-3-1-release-notes-mediasession-edition</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;So, thanks to @limebar@mastodon.social and @scy@chaos.social who implemented this feature for TIBR and TIBtv, I discovered how to send metadata to the system media player when you play my music on my site (using the Media Session API).&#xA;&#xA;What this means is that you can now see the title, artist and artwork in your system player when you play a song on sknob.fr/music.&#xA;&#xA;It could have ended there, but that’s when things got out of hand...&#xA;!--more--&#xA;In the following image, you’ll notice you can’t skip to the previous or next track. &#xA;&#xA;Screen capture of the full-screen music player on an old version of iOS which shows the song title, artist and cover image currently playing (in this case, Ukulele Bonk)&#xA;&#xA;But it turns out you can handle these actions with the mediaSession API, provided you have your own functions to do the actual work.&#xA;&#xA;This revealed a different paradigm between what I had implemented on the site, and how a system media player works. &#xA;&#xA;On my site, you could keep skipping tracks, including the last track of an album.&#xA;Whereas the mediaSession API sensibly assumes you have &#34;go to the previous/next track&#34; buttons, and if you are on the first or the last track of a playlist, well you can’t go back or forward, respectively.&#xA;&#xA;Which means that in the end, I had to:&#xA;&#xA;Rethink my &#34;skip&#34; function as a &#34;next track&#34; function&#xA;Write a &#34;previous track&#34; function&#xA;Add a &#34;previous track&#34; button to my weird UI (and to my keyboard shortcuts (available in &#34;about&#34;)&#xA;Grey out and deactivate the previous and next buttons in my weird UI when there is no previous or next track (which is what took me the longest to figure out; funny how it’s often the simple things that trip you up)&#xA;Add the appropriate calls in the mediaSession function to go to the previous/next track, including code to grey out the previous/next buttons in the system player when there is no previous or next track&#xA;This all seemed to work everywhere it was supposed to, until I noticed that the play/pause button was disabled in the media player on my old iPhone 7! So I had to add the appropriate calls in the mediaSession function to call my play/pause function.&#xA;&#xA;Phew... I told you things got out of hand! All this probably deserves more than a 0.0.1 version bump...&#xA;&#xA;Hopefully, it’s all sorted out now. But before you complain, according to the spec, this is supported pretty much everywhere except in the Android WebView!&#xA;&#xA;Media player on the Mac:&#xA;Mosaic of the Mac system player, showing the 4 tracks of my Cities EP with previous &amp; next buttons, which are grayed out for the first and last track.)&#xA;&#xA;Greyed-out buttons in my UI and in the iPhone 7 media player:&#xA;&#xA;Mosaic of the same album in my UI, with the grayed out previous and next buttons, successively, plus a capture of the system media player on my old iPhone 7 showing the last track of the album, with a greyed out next button.]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>So, thanks to <a href="https://noblogo.org/@/limebar@mastodon.social" class="u-url mention" rel="nofollow">@<span>limebar@mastodon.social</span></a> and <a href="https://noblogo.org/@/scy@chaos.social" class="u-url mention" rel="nofollow">@<span>scy@chaos.social</span></a> who implemented this feature for <a href="https://theindiebeat.fm" rel="nofollow">TIBR</a> and <a href="https://tv.theindiebeat.fm" rel="nofollow">TIBtv</a>, I discovered how to send metadata to the system media player when you play my music on my site (using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API" rel="nofollow">Media Session API</a>).</p>

<p>What this means is that you can now see the title, artist and artwork in your system player when you play a song on <a href="https://sknob.fr/music" rel="nofollow">sknob.fr/music</a>.</p>

<p>It could have ended there, but that’s when things got out of hand...

In the following image, you’ll notice you can’t skip to the previous or next track.</p>

<p><img src="https://sknob.fr/img/blog/player_01.jpg" alt="Screen capture of the full-screen music player on an old version of iOS which shows the song title, artist and cover image currently playing (in this case, Ukulele Bonk)"></p>

<p>But it turns out you can handle these actions with the mediaSession API, provided you have your own functions to do the actual work.</p>

<p>This revealed a different paradigm between what I had implemented on the site, and how a system media player works.</p>
<ul><li>On my site, you could keep skipping tracks, including the last track of an album.</li>
<li>Whereas the mediaSession API sensibly assumes you have “go to the previous/next track” buttons, and if you are on the first or the last track of a playlist, well you can’t go back or forward, respectively.</li></ul>

<p>Which means that in the end, I had to:</p>
<ul><li>Rethink my “skip” function as a “next track” function</li>
<li>Write a “previous track” function</li>
<li>Add a “previous track” button to my weird UI (and to my keyboard shortcuts (available in “about”)</li>
<li>Grey out and deactivate the previous and next buttons in my weird UI when there is no previous or next track (which is what took me the longest to figure out; funny how it’s often the simple things that trip you up)</li>
<li>Add the appropriate calls in the mediaSession function to go to the previous/next track, including code to grey out the previous/next buttons in the system player when there is no previous or next track</li>
<li>This all seemed to work everywhere it was supposed to, until I noticed that the play/pause button was disabled in the media player on my old iPhone 7! So I had to add the appropriate calls in the mediaSession function to call my play/pause function.</li></ul>

<p>Phew... I told you things got out of hand! All this probably deserves more than a 0.0.1 version bump...</p>

<p>Hopefully, it’s all sorted out now. But before you complain, according to the spec, this is supported pretty much everywhere <em>except</em> in the Android WebView!</p>

<p>Media player on the Mac:
<img src="https://sknob.fr/img/blog/player_02.png" alt="Mosaic of the Mac system player, showing the 4 tracks of my Cities EP with previous &amp; next buttons, which are grayed out for the first and last track.)"></p>

<p>Greyed-out buttons in my UI and in the iPhone 7 media player:</p>

<p><img src="https://sknob.fr/img/blog/player_03.jpg" alt="Mosaic of the same album in my UI, with the grayed out previous and next buttons, successively, plus a capture of the system media player on my old iPhone 7 showing the last track of the album, with a greyed out next button."></p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-3-1-release-notes-mediasession-edition</guid>
      <pubDate>Wed, 11 Mar 2026 15:05:53 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.3.0 Release Notes, Search Edition!</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-3-0-release-notes-search-edition</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;When you can’t choose between two options, choose both?&#xA;!--more--&#xA;In the release notes for the initial version of the new sknob.fr/music site, I wrote:&#xA;&#xA;  Feature-wise, the main addition is a filter/search function. I’m not sure how useful it is, but it’s there. After waffling some, I opted to only search through the titles and the on-screen metadata, not including the lyrics and other background info.&#xA;&#xA;It later dawned on me that I had basically just duplicated the search function built into the browser. Duh!&#xA;&#xA;Then again, on tablets and phones, the built-in search isn’t as easily accessible as in desktop browsers.&#xA;&#xA;And the reason I didn’t go with full-text search is that the site contains a lot of lyrics and a lot of background info text, which means full-text searches don’t filter out a lot of songs...&#xA;&#xA;Still, this arbitrary choice kept gnawing at me in the background, so yesterday, I decided to do something about it.&#xA;&#xA;The search field now includes a button on the right that toggles full-text search on and off.&#xA;Clicking on the button reinitializes the search (and places the cursor in the search field).&#xA;Hit It works in both album mode and radio mode.&#xA;Behind the scenes, all it took was filtering based on &#xA;So now, you can just hit `s` and search for bits of song titles you remember, or if you’re looking for that underground sknob hit that uses the word “monkey”, you can switch to full-text search and find it instantly (the background info for that song is worth the read span class=&#34;emoji&#34;😇/span).]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>When you can’t choose between two options, choose both?

In the <a href="sknob-music-v5-release-notes" rel="nofollow">release notes for the initial version</a> of the new <a href="https://sknob.fr/music" rel="nofollow">sknob.fr/music</a> site, I wrote:</p>

<blockquote><p>Feature-wise, the main addition is a filter/search function. I’m not sure how useful it is, but it’s there. After waffling some, I opted to only search through the titles and the on-screen metadata, not including the lyrics and other background info.</p></blockquote>

<p>It later dawned on me that I had basically just duplicated the search function built into the browser. Duh!</p>

<p>Then again, on tablets and phones, the built-in search isn’t as easily accessible as in desktop browsers.</p>

<p>And the reason I didn’t go with full-text search is that the site contains <em>a lot</em> of lyrics and <em>a lot</em> of background info text, which means full-text searches don’t filter out a lot of songs...</p>

<p>Still, this arbitrary choice kept gnawing at me in the background, so yesterday, I decided to do something about it.</p>
<ul><li>The search field now includes a button on the right that toggles full-text search on and off.</li>
<li>Clicking on the button reinitializes the search (and places the cursor in the search field).</li>
<li>Hit <code>f</code> to activate full-text search (if you’re not already inside the search field, naturally).</li>
<li>It works in both album mode and <a href="https://sknob.fr/music/?radiosknob" rel="nofollow">radio mode</a>.</li>
<li>Behind the scenes, all it took was filtering based on <code>innerText</code> for simple searches and <code>innerHTML</code> for full-text searches.</li></ul>

<p>So now, you can just hit <code>s</code> and search for bits of song titles you remember, or if you’re looking for that underground sknob hit that uses the word “monkey”, you can switch to full-text search and find it instantly (the background info for that song is worth the read <span class="emoji">😇</span>).</p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-3-0-release-notes-search-edition</guid>
      <pubDate>Wed, 22 Oct 2025 13:17:47 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.2.1 Release Notes, OG:image Edition!</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-3-release-notes-og-image-edition</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;I didn’t see that one coming...&#xA;!--more--&#xA;Having all the albums and songs on a single page means that by default, when you link to the page from somewhere else like a messaging app or your #fediverse feed, you always get the preview image specified in the &#xA;But then it dawned on me. Since I’m already using PHP to prep my XML playlist, it should be possible in theory to use PHP to dynamically change the &#xA;Problem was, I’m an absolute PHP beginner.&#xA;&#xA;Undaunted, I went ahead and figured it out, and tada, it works. If you call &#xA;Out of laziness, I kept the somewhat complex image organization from the v4 version of the site (yes, I aim to clean that up eventually, but it’s not a trivial task), which means that the code won’t always find an image, in which case it defaults back to the default image. Same if you type in a garbage URL.&#xA;&#xA;I’m really happy about this, because that was one thing that bothered me about going the single page route. I even sometimes shied away from posting links to my site on Mastodon because of it.&#xA;&#xA;No more!]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>I didn’t see that one coming...

Having all the albums and songs on a single page means that by default, when you link to the page from somewhere else like a messaging app or your <a href="/sknob/tag:fediverse" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">fediverse</span></a> feed, you always get the preview image specified in the <code>&lt;meta property=&#34;og:image...&#34;&gt;</code> tag in the page header...</p>

<p>But then it dawned on me. Since I’m already using PHP to prep my XML playlist, it should be possible in theory to use PHP to dynamically change the <code>og:image</code> property based on the incoming URL.</p>

<p>Problem was, I’m an absolute PHP beginner.</p>

<p>Undaunted, I went ahead and figured it out, and tada, it works. If you call <code>sknob.fr/music/?mysong</code>, the <code>og:image</code> meta tag image is dynamically changed to <code>mysong.jpg</code>.</p>

<p>Out of laziness, I kept the somewhat complex image organization from the v4 version of the site (yes, I aim to clean that up eventually, but it’s not a trivial task), which means that the code won’t always find an image, in which case it defaults back to the default image. Same if you type in a garbage URL.</p>

<p>I’m really happy about this, because that was one thing that bothered me about going the single page route. I even sometimes shied away from posting links to my site on Mastodon because of it.</p>

<p>No more!</p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-3-release-notes-og-image-edition</guid>
      <pubDate>Thu, 18 Sep 2025 09:35:52 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.2 Release Notes, Radio sknob Edition!</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-2-release-notes-radio-sknob-edition</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;Introducing... Radio sknob!&#xA;!--more--&#xA;If you read the preceding #coding posts, you know I finally decided to redo my antiquated site before it stopped working, and that I recoded everything from scratch.&#xA;&#xA;And now, I’m actually free to start adding new features.&#xA;&#xA;This release introduces an oft requested “radio mode”, i.e. a way to listen to everything, not just to single albums (as the artist originally intended span class=&#34;emoji&#34;😭/span).&#xA;&#xA;There is now a shuffle button radio button, which toggles between album mode and radio mode.&#xA;The radio mode is reshuffled on each toggle.&#xA;The radio mode doesn’t display the full lyrics, but does display the track background info, so you can download a song you like, or copy the link, or boost the song on the fediverse.&#xA;Other than that, Radio sknob behaves like a regular album, which means you can click on the span class=&#34;emoji&#34;🔗/span icon next to the title to get a link to open the site in radio mode.&#xA;Oh, and there’s also a keyboard shortcut to switch between album and radio mode. You’ll find it in the about dialog, along with other useful shortcuts span class=&#34;emoji&#34;😇/span.&#xA;&#xA;Hope you like the new feature (you know who you are...)&#xA;&#xA;details&#xA;summaryA few gory details.../summaryI’m sure there’s a lighter and easy-ish way to do this in javascript, cloning arrays, etc., but my XML data file weighs about 300 Kb, so I decided to just transform it twice with two different XSL templates. Zero code. I do shuffle the radio playlist in javascript however.&#xA;&#xA;I’m not sure the final size of the page would be lighter if I used javascript, but using XML+XSL transformed on the server using PHP does impact page load. This bugs me, but the site still loads pretty fast, so I’m choosing to go with this for now. If I get my javascript chops up in the future, I might recode this entirely.&#xA;&#xA;UPDATE: of course, I couldn’t resist optimizing the page load, so I now only load the XML playlist once, and build the radio playlist locally in javascript...&#xA;&#xA;I also tried a gazillion different interfaces/UIs until I worked my way down to this one which is minimal and consistent, which is what I always strive for.&#xA;/details]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>Introducing... Radio sknob!

If you read the preceding <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a> posts, you know I finally decided to redo my antiquated site before it stopped working, and that <a href="sknob-music-v5-release-notes" rel="nofollow">I recoded everything from scratch</a>.</p>

<p>And now, I’m actually free to start adding new features.</p>

<p>This release introduces an oft requested “radio mode”, i.e. a way to listen to <em>everything</em>, not just to single albums (as the artist originally intended <span class="emoji">😭</span>).</p>
<ul><li>There is now a <del>shuffle button</del> radio button, which toggles between <em>album mode</em> and <em>radio mode</em>.</li>
<li>The radio mode is reshuffled on each toggle.</li>
<li><del>The radio mode doesn’t display the full lyrics, but does display the track background info, so you can download a song you like, or copy the link, or boost the song on the fediverse.</del></li>
<li>Other than that, <em>Radio sknob</em> behaves like a regular album, which means you can click on the <span class="emoji">🔗</span> icon next to the title to get a link to <a href="https://sknob.fr/music/?radiosknob" rel="nofollow">open the site in radio mode</a>.</li>
<li>Oh, and there’s also a keyboard shortcut to switch between album and radio mode. You’ll find it in the <em>about</em> dialog, along with other useful shortcuts <span class="emoji">😇</span>.</li></ul>

<p>Hope you like the new feature (you know who you are...)</p>

<p><details>
<summary><em>A few gory details...</em></summary>I’m sure there’s a lighter and easy-ish way to do this in javascript, cloning arrays, etc., but my XML data file weighs about 300 Kb, so I decided to just transform it twice with two different XSL templates. Zero code. I do shuffle the radio playlist in javascript however.</p>

<p>I’m not sure the final size of the page would be lighter if I used javascript, but using XML+XSL transformed on the server using PHP does impact page load. This bugs me, but the site still loads pretty fast, so I’m choosing to go with this for now. If I get my javascript chops up in the future, I might recode this entirely.</p>

<p>UPDATE: of course, I couldn’t resist optimizing the page load, so I now only load the XML playlist once, and build the radio playlist locally in javascript...</p>

<p>I also tried a gazillion different interfaces/UIs until I worked my way down to this one which is minimal and consistent, which is what I always strive for.
</details></p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-2-release-notes-radio-sknob-edition</guid>
      <pubDate>Sat, 13 Sep 2025 08:09:40 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.1.2 Release Notes, RSS edition</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-1-2-release-notes-rss-edition</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;Note: These #coding posts are really notes to my future self. Do feel free to ignore them.&#xA;&#xA;So, it seems I like to do the opposite of what you’re supposed to do...&#xA;!--more--&#xA;I created an RSS feed for the music site, and then I thought, well, why not use XSLT to transform my RSS XML into a handy web page (instead of the other way around).&#xA;&#xA;So here are the changes:&#xA;&#xA;In music   about, I added an RSS icon to the Latest News section, for you to add the RSS feed to your favorite reader.&#xA;In music   about, I am now showing the 7 Latest News items, followed by a And since you are reading this, you can:&#xA;    Visit the sknob/scoop page directly, or&#xA;    Subscribe to the RSS feed directly.&#xA;&#xA;Hope that makes sense!&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p><em>Note: These <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a> posts are really notes to my future self. Do feel free to ignore them.</em></p>

<p>So, it seems I like to do the opposite of what you’re supposed to do...

I created an RSS feed for the music site, and then I thought, well, why not use XSLT to transform my RSS XML into a handy web page (instead of the other way around).</p>

<p>So here are the changes:</p>
<ul><li>In music &gt; about, I added an RSS icon to the <em>Latest News</em> section, for you to add the RSS feed to your favorite reader.</li>
<li>In music &gt; about, I am now showing the 7 <em>Latest News</em> items, followed by a <code>More...</code> link, which brings you to a <a href="https://sknob.fr/music/scoop.php" rel="nofollow">fully rendered web version of the RSS feed</a>.</li>
<li>And since you are reading this, you can:
<ul><li>Visit the <a href="https://sknob.fr/music/scoop.php" rel="nofollow">sknob/scoop</a> page directly, or</li>
<li><a href="https://sknob.fr/music/sknob-rss.xml" rel="nofollow">Subscribe to the RSS</a> feed directly.</li></ul></li></ul>

<p>Hope that makes sense!</p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-1-2-release-notes-rss-edition</guid>
      <pubDate>Tue, 09 Sep 2025 11:11:32 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5.1 Release Notes</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-1-x-release-notes</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;Before anything else, I moved the project to Git, and created a (private) repo on Codeberg. I think I’m finally getting the hang of it.&#xA;!--more--&#xA;Changed the Before:&#xA;Screen capture of a song info section, with links to download, copy the link to the song, and now to share on Mastodon&#xA;After:&#xA;Screen capture of a song info section, now with icons to download, copy the link to the song, and share it on Mastodon&#xA;Added a When navigating from elsewhere using a link to an album, the target album cover is surrounded by an outline.&#xA;Stopped the page from scrolling when an album cover is displayed full-screen. Doesn’t work in Safari. Quite a PITA to fix. I may or may not bother in the future.&#xA;The (small round) album covers are now “sticky” to make it easier to see which album the songs belong to when you scroll. Note that this is deactivated in portrait mode on phones.&#xA;Small code changes (offset scrolling, hiding the covers during search, since they were moved in the page hierarchy to make the &#xA;Read the lengthy, gory v5.0 Release Notes if you dare.]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>Before anything else, I moved the project to Git, and created a (private) repo on Codeberg. I <em>think</em> I’m finally getting the hang of it.

– Changed the <code>Download</code>, <code>Copy Link</code> and <code>Share on Mastodon</code> links in the song details to nice SVG icons.
<em>Before:</em>
<img src="https://sknob.fr/img/blog/sknoblinks-before.jpg" alt="Screen capture of a song info section, with links to download, copy the link to the song, and now to share on Mastodon">
<em>After:</em>
<img src="https://sknob.fr/img/blog/sknoblinks-after.jpg" alt="Screen capture of a song info section, now with icons to download, copy the link to the song, and share it on Mastodon">
– Added a <code>Copy Link</code> icon next to the album titles, so you can post links on the <a href="/sknob/tag:fediverse" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">fediverse</span></a> or send them to all your friends and loved ones :)
– When navigating from elsewhere using a <a href="https://sknob.fr/music/?spiral_album" rel="nofollow">link to an album</a>, the target album cover is surrounded by an outline.
– Stopped the page from scrolling when an album cover is displayed full-screen. Doesn’t work in Safari. Quite a PITA to fix. I may or may not bother in the future.
– The (small round) album covers are now “sticky” to make it easier to see which album the songs belong to when you scroll. Note that this is deactivated in portrait mode on phones.
–  Small code changes (offset scrolling, hiding the covers during search, since they were moved in the page hierarchy to make the <code>position: sticky</code> work).</p>

<p>Read the lengthy, gory <a href="sknob-music-v5-release-notes" rel="nofollow">v5.0 Release Notes</a> if you dare.</p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-1-x-release-notes</guid>
      <pubDate>Thu, 04 Sep 2025 10:17:07 +0000</pubDate>
    </item>
    <item>
      <title>sknob/music v5 Release Notes</title>
      <link>https://noblogo.org/sknob/sknob-music-v5-release-notes</link>
      <description>&lt;![CDATA[#blogpost #music #coding&#xA;&#xA;WARNING: Long geeky post. Proceed with caution. &#xA;&#xA;Long story short, the code underlying my music site was nearly 15 years old, and woefully obsolete.&#xA;&#xA;I&#39;d only been meaning to update it for about a decade...&#xA;!--more--&#xA;Some background&#xA;&#xA;You’ll find some embarrassing old posts about it on my mothballed blog:&#xA;&#xA;The Making of sknob | MUSIC version 3&#xA;sknob | MUSIC v4&#xA;Un blaireau chez les geeks&#xA;&#xA;For reasons I can’t divulge yet, I got back into the coding saddle recently, and so I decided it was finally time to give it a shot.&#xA;&#xA;While I wanted to keep all the song data in XML + XSL because I just love it (look, no code!), I was ready to redo everything else from scratch.&#xA;&#xA;My site still worked fine with a really old version of jQuery and a JQuery plugin for the XML transform step, but any attempt to move to a recent version of jQuery failed miserably, which was the final nail in the jQuery coffin. Good riddance. And while I would have loved to get rid of javascript altogether, that’s sadly not a real option if you&#39;re dealing with a lot of audio. Putting ~180 native audio players in a web page is not a good idea (I tried, don’t ask).&#xA;&#xA;Because yes, I wanted to keep everything on a single-page.&#xA;&#xA;Nitty-gritty &#xA;&#xA;I started with a bare-bones design, which I ended up keeping more or less as is, because it’s kind of a relief after nearly 15 years of visual excess. I can always spruce it up later if needed.&#xA;I wrote clean CSS and simple javascript (the kind I’m likely to understand if I ever want to update or change what I did down the road).&#xA;I replaced ~800 lines of super-compact jQuery code with about 450 lines of verbose, commented and airily-formatted plain javascript.&#xA;I optimized image handling (the image sizes were all over the place, and lazy loading didn’t even exist back then). &#xA;Last but not least, out of laziness (and incompetence), and after Google announced they wanted to remove XSLT support from Chrome, I ended up doing the XML transform server-side in less than 10 lines of PHP (which I had never used before).&#xA;&#xA;details&#xA;summaryGory details about line endings and HTML entities. Click to view at your own risk./summaryI needed to do two things to the HTML generated by the XML/XSL (same as on the previous site): Change &#xA;I laboriously implemented both in javascript, but l then discovered I could convert the line endings with a single line of CSS:&#xA;&#xA;As for decoding the HTML entities, it was all happening in the background since no lyrics are displayed on page load, but while mucking around, I noticed that it took a few seconds for javascript to do the job with something like &#xA;So I tried doing it in PHP on the transformed XML data with &#xA;Yes, I’m not a real geek. I only play one on the Internet. Anyway, back to our regularly scheduled programming... &#xA;/details&#xA;Altogether, the speed increase is dramatic.&#xA;&#xA;Before:&#xA;Total requests: 274&#xA;Size: 9,205.46 kB&#xA;Transferred Size: 5,672.55 kB&#xA;Time: 32.05 seconds&#xA;Non blocking time: 31.73 seconds&#xA;After: &#xA;Total requests: 9&#xA;Size: 460.27 kB&#xA;Transferred Size: 159.36 kB&#xA;Time: 0.11 seconds&#xA;Non blocking time: 0.11 seconds&#xA;Yes, I know...&#xA;&#xA;(To be fair, the old site loaded fast enough, and then the song data was processed and a ton of images were loaded, well, as fast as hardware and bandwidth allowed...)&#xA;&#xA;New and improved!&#xA;&#xA;Feature-wise, the main addition is a filter/search function. I’m not sure how useful it is, but it’s there. After waffling some, I opted to only search through the titles and the on-screen metadata, not including the lyrics and other background info. I spent a lot of time testing endless variations on that one feature, and in the end, it probably accounts for about a 1/4 of the javascript code...&#xA;&#xA;UPDATE: I’ve since improved the search!&#xA;&#xA;The rest of the code basically handles audio and interface behavior to give the user some hopefully useful tools and feedback to navigate through the long list of songs.&#xA;&#xA;details&#xA;summaryGory details about the audio player.../summaryIn version 4, I jumped through complicated hoops to assemble playlists for each album into javascript arrays, and then spliced and pushed and popped stuff as needed.&#xA;&#xA;This time around, the code just says play the song the user clicked on, and then keep playing the &#xA;The remaining code basically just toggles CSS classes to show the lyrics for the song that’s /details&#xA;The design may be simple, but it still rather unconventional for an audio site, and I tend to really sweat the details (#OCD), so everything is quite deliberate, for better or for worse.&#xA;&#xA;I won’t describe what everything does and how everything works here. You’ll just have to experiment to find out.&#xA;&#xA;A few final notes nonetheless:&#xA;&#xA;You can now click on the images to see larger versions of the album covers and song illustrations (when they’re available).&#xA;I added some keyboard shortcuts, which are documented in the &#34;about&#34; link at the top of the page, which also contains links to recent off-site music-related endeavors...&#xA;Fun fact: I use the system audio controls, albeit with a CSS blend-mode to make them...blend in. Not so fun fact: Chrome doesn’t want to blend in.&#xA;In case it wasn’t obvious, you can also pause songs by clicking on their titles.&#xA;I added backward-compatibility for handling the URLs with query strings I’ve published in the wild over the last ~15 years.&#xA;And I can now link to albums, not just to songs...&#xA;The site is responsive, and honors the system’s light/dark mode settings.&#xA;I’ll be cleaning up some of the “backstory” content over time, when I feel like it (it was hidden behind a tab and largely forgotten on the previous version of the site).&#xA;The Themes view from the previous version is gone. I may or may not reintroduce it in some guise or another at some point in the future.&#xA;The previous version of the site should still be available, but I won’t be updating it any longer.&#xA;TBC ?&#xA;&#xA;details&#xA;summaryGory details about about a nasty CSS rendering bug in Firefox.../summaryI’ve been using this CSS technique by @aral@mastodon.ar.al to implement dark mode on various sites, including this blog. It’s really clever. It basically just uses the CSS &#xA;Until I realized to my dismay that Firefox (and possibly Chrome, I don’t remember now) doesn’t seem to like CSS filters and blends in dark mode, and simply refuses to render... fixed divs (like the audio player). They simply disappear! I spent a ton of time researching and trying to fix or skirt the problem, but I finally gave up and coded my dark mode CSS the old-fashioned way. Sigh.&#xA;/details&#xA;Phew!&#xA;&#xA;So there you have it, only ~15 years in the making: the fifth major version of my canonical, official music site and archive.&#xA;&#xA;In a nutshell, it’s basically the same (somewhat sanitized) song data sandwiched between a shiny new interface and one hundred percent new code.&#xA;&#xA;Maybe someday I’ll ditch it altogether and just go with a #Faircamp site for everything. The main thing holding me back is having to find all the hi-res versions of the ~180 songs, many of which are decades old, and the size requirements that would ensue. So for now, you can visit my Faircamp site for some extra content, alternate mixes, collaborations, etc.&#xA;&#xA;I guess this post is really a note to my future self, but If you’ve actually read this far, thank you, and if you find any bugs or odd behavior, please let me know!&#xA;&#xA;Oh, and I nearly forgot! Here is the link to the site: &#xA;&#xA;https://sknob.fr/music/&#xA;---&#xA;Further reading:&#xA;sknob/music v5.1 Release Notes&#xA;sknob/music v5.1.2 Release Notes, RSS edition&#xA;sknob/music v5.2 Release Notes, Radio sknob Edition!&#xA;sknob/music v5.2.1 Release Notes, OG:image Edition!&#xA;sknob/music v5.3.0 Release Notes, Search Edition!&#xA;sknob/music v5.3.1 Release Notes, mediaSession Edition!&#xA;sknob/music v5.4.0 Release Notes, Fetch Edition!&#xA;&#xA;Screen capture of the new version of the site in light mode&#xA;&#xA;Screen capture of the new version of the site in dark mode]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/sknob/tag:blogpost" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">blogpost</span></a> <a href="/sknob/tag:music" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">music</span></a> <a href="/sknob/tag:coding" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">coding</span></a></p>

<p>WARNING: Long geeky post. Proceed with caution.</p>

<p>Long story short, the code underlying my music site was nearly 15 years old, and woefully obsolete.</p>

<p>I&#39;d only been meaning to update it for about a decade...
</p>

<h3 id="some-background">Some background</h3>

<p>You’ll find some embarrassing old posts about it on my mothballed blog:</p>
<ul><li><a href="https://sknob.fr/sknoblog/2011/12/31/the-making-of-vincent-knobil-music-version-3/" rel="nofollow">The Making of sknob | MUSIC version 3</a></li>
<li><a href="https://sknob.fr/usknoblog/2016/03/05/sknob-music-v4/" rel="nofollow">sknob | MUSIC v4</a></li>
<li><a href="https://sknob.fr/sknoblog/2022/12/21/un-blaireau-chez-les-geeks/" rel="nofollow">Un blaireau chez les geeks</a></li></ul>

<p>For reasons I can’t divulge yet, I got back into the coding saddle recently, and so I decided it was finally time to give it a shot.</p>

<p>While I wanted to keep all the song data in XML + XSL because I just <em>love</em> it (<a href="https://sknob.fr/sknoblog/2011/12/31/the-making-of-vincent-knobil-music-version-3/#:~:text=THE%20HOLY.%20FUCKING.%20GRAIL:%20XSLT." rel="nofollow">look, no code!</a>), I was ready to redo everything else from scratch.</p>

<p>My site still worked fine with a really old version of jQuery and a JQuery plugin for the XML transform step, but any attempt to move to a recent version of jQuery failed miserably, which was the final nail in the jQuery coffin. Good riddance. And while I would have loved to get rid of javascript altogether, that’s sadly not a real option if you&#39;re dealing with a lot of audio. Putting ~180 native audio players in a web page is not a good idea (I tried, don’t ask).</p>

<p>Because yes, I wanted to keep everything on a single-page.</p>

<h3 id="nitty-gritty">Nitty-gritty</h3>
<ul><li>I started with a bare-bones design, which I ended up keeping more or less as is, because it’s kind of a relief after nearly 15 years of visual excess. I can always spruce it up later if needed.</li>
<li>I wrote clean CSS and simple javascript (the kind I’m likely to understand if I ever want to update or change what I did down the road).</li>
<li>I replaced ~800 lines of super-compact jQuery code with about 450 lines of verbose, commented and airily-formatted plain javascript.</li>
<li>I optimized image handling (the image sizes were all over the place, and lazy loading didn’t even exist back then).</li>
<li>Last but not least, out of laziness (and incompetence), and after Google announced they wanted to remove XSLT support from Chrome, I ended up doing the XML transform server-side in less than 10 lines of PHP (which I had never used before).</li></ul>

<p><details>
<summary><em>Gory details about line endings and HTML entities. Click to view at your own risk.</em></summary>I needed to do two things to the HTML generated by the XML/XSL (same as on the previous site): Change <code>\n</code> new lines in the lyrics <code>CDATA</code> to <code>&lt;br&gt;</code> tags, and decode HTML entities.</p>

<p>I laboriously implemented both in javascript, but l then discovered I could convert the line endings with a single line of CSS:
<code>white-space: pre-line</code> !</p>

<p>As for decoding the HTML entities, it was all happening in the background since no lyrics are displayed on page load, but while mucking around, I noticed that it took a few seconds for javascript to do the job with something like <code>item.innerHTML.replace(/&amp;lt;/g, &#34;&lt;&#34;).replace(/&amp;gt;/g, &#34;&gt;&#34;)</code>.</p>

<p>So I tried doing it in PHP on the transformed XML data with <code>html_entity_decode</code> and it worked instantly.</p>

<p>Yes, I’m not a real geek. I only play one on the Internet. Anyway, back to our regularly scheduled programming...
</details>
Altogether, the speed increase is <em>dramatic</em>.</p>

<p>Before:</p>

<pre><code>Total requests: 274
Size: 9,205.46 kB
Transferred Size: 5,672.55 kB
Time: 32.05 seconds
Non blocking time: 31.73 seconds
</code></pre>

<p>After:</p>

<pre><code>Total requests: 9
Size: 460.27 kB
Transferred Size: 159.36 kB
Time: 0.11 seconds
Non blocking time: 0.11 seconds
</code></pre>

<p>Yes, I know...</p>

<p>(To be fair, the old site loaded fast enough, and then the song data was processed and a ton of images were loaded, well, as fast as hardware and bandwidth allowed...)</p>

<h3 id="new-and-improved">New and improved!</h3>

<p>Feature-wise, the main addition is a filter/search function. I’m not sure how useful it is, but it’s there. After waffling some, I opted to only search through the titles and the on-screen metadata, not including the lyrics and other background info. I spent a lot of time testing endless variations on that one feature, and in the end, it probably accounts for about a ¼ of the javascript code...</p>

<p><em>UPDATE: I’ve since <a href="sknob-music-v5-3-0-release-notes-search-edition" rel="nofollow">improved the search</a>!</em></p>

<p>The rest of the code basically handles audio and interface behavior to give the user some hopefully useful tools and feedback to navigate through the long list of songs.</p>

<p><details>
<summary><em>Gory details about the audio player...</em></summary>In version 4, I jumped through complicated hoops to assemble playlists for each album into javascript arrays, and then <em>spliced</em> and <em>pushed</em> and <em>popped</em> stuff as needed.</p>

<p>This time around, the code just says <em>play the song the user clicked on</em>, and then keep playing the <code>nextElementSibling</code> in the current <code>&lt;ul&gt;</code> until you run out.</p>

<p>The remaining code basically just toggles CSS classes to show the lyrics for the song that’s <code>.playing</code>, and turns appropriate interface elements on and off, etc.
</details>
The design may be simple, but it still rather unconventional for an audio site, and I tend to really sweat the details (<a href="/sknob/tag:OCD" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">OCD</span></a>), so everything is quite deliberate, for better or for worse.</p>

<p>I won’t describe what everything does and how everything works here. You’ll just have to experiment to find out.</p>

<p>A few final notes nonetheless:</p>
<ul><li>You can now click on the images to see larger versions of the album covers and song illustrations (when they’re available).</li>
<li>I added some keyboard shortcuts, which are documented in the “about” link at the top of the page, which also contains links to recent off-site music-related endeavors...</li>
<li>Fun fact: I use the system audio controls, albeit with a CSS blend-mode to make them...blend in. Not so fun fact: Chrome doesn’t want to blend in.</li>
<li>In case it wasn’t obvious, you can also <em>pause</em> songs by clicking on their titles.</li>
<li>I added backward-compatibility for handling the URLs with query strings I’ve published in the wild over the last ~15 years.</li>
<li>And I can now link to albums, not just to songs...</li>
<li>The site is responsive, and <a href="https://mamot.fr/@sknob/114801643818143762" rel="nofollow">honors the system’s light/dark mode settings</a>.</li>
<li>I’ll be cleaning up some of the “backstory” content over time, when I feel like it (it was hidden behind a tab and largely forgotten on the previous version of the site).</li>
<li>The Themes view from the previous version is gone. I may or may not reintroduce it in some guise or another at some point in the future.</li>
<li>The previous version of the site should <a href="https://sknob.fr/music/index.html" rel="nofollow">still be available</a>, but I won’t be updating it any longer.</li>
<li>TBC ?</li></ul>

<p><details>
<summary><em>Gory details about about a nasty CSS rendering bug in Firefox...</em></summary>I’ve been using <a href="https://ar.al/2021/08/24/implementing-dark-mode-in-a-handful-of-lines-of-css-with-css-filters/" rel="nofollow">this CSS technique</a> by <a href="https://noblogo.org/@/aral@mastodon.ar.al" class="u-url mention" rel="nofollow">@<span>aral@mastodon.ar.al</span></a> to implement dark mode on various sites, including this blog. It’s really clever. It basically just uses the CSS <code>filter</code> property to invert everything, and then inverts images back to normal. I would never have implemented dark mode on version 4 of my music site without it. Works flawlessly.</p>

<p>Until I realized to my dismay that Firefox (and possibly Chrome, I don’t remember now) doesn’t seem to like CSS filters and blends in dark mode, and simply refuses to render... fixed divs (like the audio player). They simply disappear! I spent a ton of time researching and trying to fix or skirt the problem, but I finally gave up and coded my dark mode CSS the old-fashioned way. Sigh.
</details></p>

<h3 id="phew">Phew!</h3>

<p>So there you have it, only ~15 years in the making: the fifth major version of my canonical, official music site and archive.</p>

<p>In a nutshell, it’s basically the same (somewhat sanitized) song data sandwiched between a shiny new interface and one hundred percent new code.</p>

<p>Maybe someday I’ll ditch it altogether and just go with a <a href="/sknob/tag:Faircamp" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Faircamp</span></a> site for everything. The main thing holding me back is having to find all the hi-res versions of the ~180 songs, many of which are <em>decades</em> old, and the size requirements that would ensue. So for now, you can visit my <a href="https://sknob.fr/faircamp/" rel="nofollow">Faircamp site</a> for some extra content, alternate mixes, collaborations, etc.</p>

<p>I guess this post is really a note to my future self, but If you’ve actually read this far, thank you, and if you find any bugs or odd behavior, <a href="https://mamot.fr/@sknob" rel="nofollow">please let me know</a>!</p>

<p>Oh, and I nearly forgot! Here is the link to the site:</p>

<p><a href="https://sknob.fr/music/" rel="nofollow">https://sknob.fr/music/</a></p>

<hr>

<p><strong>Further reading:</strong>
<a href="sknob-music-v5-1-x-release-notes" rel="nofollow">sknob/music v5.1 Release Notes</a>
<a href="sknob-music-v5-1-2-release-notes-rss-edition" rel="nofollow">sknob/music v5.1.2 Release Notes, RSS edition</a>
<a href="sknob-music-v5-2-release-notes-radio-sknob-edition" rel="nofollow">sknob/music v5.2 Release Notes, Radio sknob Edition!</a>
<a href="sknob-music-v5-3-release-notes-og-image-edition" rel="nofollow">sknob/music v5.2.1 Release Notes, OG:image Edition!</a>
<a href="sknob-music-v5-3-0-release-notes-search-edition" rel="nofollow">sknob/music v5.3.0 Release Notes, Search Edition!</a>
<a href="sknob-music-v5-3-1-release-notes-mediasession-edition" rel="nofollow">sknob/music v5.3.1 Release Notes, mediaSession Edition!</a>
<a href="sknob-music-v5-4-0-release-notes-fetch-edition" rel="nofollow">sknob/music v5.4.0 Release Notes, Fetch Edition!</a></p>

<p><img src="https://sknob.fr/img/blog/sknobmusic5light.jpg" alt="Screen capture of the new version of the site in light mode"></p>

<p><img src="https://sknob.fr/img/blog/sknobmusic5dark.jpg" alt="Screen capture of the new version of the site in dark mode"></p>
]]></content:encoded>
      <guid>https://noblogo.org/sknob/sknob-music-v5-release-notes</guid>
      <pubDate>Wed, 27 Aug 2025 07:45:00 +0000</pubDate>
    </item>
  </channel>
</rss>