From dbbcf55b2b34db74cdecf41f27e3a402d9e0492a Mon Sep 17 00:00:00 2001 From: David Keane Date: Wed, 10 Jun 2026 01:16:55 +0100 Subject: [PATCH] =?UTF-8?q?chore:=20v0.5.3=20=E2=80=94=20bump=20version=20?= =?UTF-8?q?+=20CHANGELOG=20entry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final headline-feature release. Per David: 'this app is kinda done' once Quick Stations picker + history export ship. After this version, polish remains but no headline features are missing. Bundled with v0.5.0's eventual Web Store upload — when v0.5.0 clears re-review, we'll build a v0.5.3 ZIP directly from main and upload that as the next user-visible update. Users at v0.4.0 jump straight to v0.5.3, getting all the polish in one notification. --- CHANGELOG.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- manifest.json | 2 +- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fc87a7..204a394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/) — versi ## [Unreleased] -### Planned — Future polish +### Planned — Long-term - `.m3u` parser alongside `.pls` to widen future-adapter compatibility - Station artwork lazy-load + fallback to family helmet - Better error UI for failed streams ("Stream unavailable, try another") @@ -16,6 +16,62 @@ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/) — versi --- +## [0.5.3] — 2026-06-10 — User-customizable Quick Stations + history export ("app is done") + +Per David: *"this app is kinda done"* — meaning the product surface is feature-complete. After this version, polish remains but no headline features are missing. + +### Added — User-customizable Quick Stations + +Pure-data architecture: the NewTab Quick Stations chip row is now driven by `tuner.quickStations` in `chrome.storage.local` rather than a hardcoded `QUICK_IDS` array. **Default 8 (tidy 2-row layout, matches v0.4.0 look).** User can pick any subset of all 46 SomaFM channels via a new Options page card. + +**Where:** new "Quick Stations" card on the Options page (sits between Appearance and Playback). Layout: helper text + selected-count badge + scrollable checkbox list + Reset-to-defaults button. + +**Each list row** shows: checkbox + station name + genre pill (accent green, uppercase) + the SomaFM channel description (the same string available as a chip-hover tooltip on the NewTab — now properly visible at the time of picking). + +**Live sync:** ticking a checkbox writes to `chrome.storage.local`. The NewTab `chrome.storage.onChanged` listener picks up the change and re-renders the Quick Stations chip row instantly without a reload. Cross-surface consistency is the same pattern as theme + station selection. + +**Robust fresh-install fallback:** if Options is opened BEFORE the NewTab has ever populated the station catalogue cache, `initQuickStationsUI` fetches SomaFM channels directly via `listAllStations()` then caches the result back to `tuner.stationsCache`. Future Options opens are then instant. + +**Empty-pick case:** if the user unticks everything, the Quick Stations row on the NewTab shows *"No Quick Stations picked — set some in ⚙ Settings."* instead of a silently empty section. + +### Added — History export (JSON + CSV) + +Two new buttons in the Local Data card: **Export history (JSON)** and **Export history (CSV)**. + +- **JSON**: full pretty-printed array of `tuner.history` entries. Best for programmatic re-import or backup. +- **CSV**: RFC 4180 quoted (every cell quoted, doubled quotes for embedded quotes). Header: `artist,title,station,station_id,when_iso`. Opens cleanly in Excel / Numbers / Google Sheets. + +Filename: `rangerhq-tuner-history-YYYY-MM-DD.{ext}`. + +Empty-history case shows an error toast ("No history to export yet — play some music first"). Success case shows a green toast with the export count and format. + +No new permissions — uses standard `Blob` + `URL.createObjectURL` + a programmatic `` click. The entire export runs client-side in the Options page; nothing is sent off-device. + +### New / changed files + +- `src/lib/quick-stations.js` (NEW, ~55 lines) — `DEFAULT_QUICK_IDS` constant + `getQuickStations / setQuickStations / resetQuickStations` helpers. Same defensive `storage()` accessor pattern as `lib/history.js` and `lib/theme.js`. +- `src/newtab/newtab.js` — removed hardcoded `QUICK_IDS` array, replaced with module-level `quickIds = []` populated during `init()` from `getQuickStations()` and re-loaded when `chrome.storage.onChanged` fires on `tuner.quickStations`. `renderQuick()` shows the empty-pick fallback message. +- `src/options/options.html` — new "Quick Stations" card + two export buttons in the Local Data card. +- `src/options/options.css` — ~90 lines for the picker (scrollable list, row layout, accent-coloured count badge, hover background, brand scrollbar). +- `src/options/options.js` — `initQuickStationsUI` builds the checkbox list, `onQuickStationToggle` persists picks, `exportHistoryAs` generates the download Blob. Plus the storage.onChanged listener was made async to support cross-surface picker sync. + +Total: 5 files, +372 / -25 lines (1 new file). + +### Not changed + +- No new permissions +- No new host_permissions +- No new external libraries / SDKs +- No data migration required +- Existing user state (current station / volume / history / favourites / theme) survives intact +- Defaults match v0.4.0's curated Quick Stations exactly — users who never open Options get the same look they had before + +### Workflow note + +This release was bundled into v0.5.0's eventual Web Store upload — when v0.5.0 clears re-review, we build a v0.5.3 ZIP directly from main and upload that instead. Users at v0.4.0 jump straight to v0.5.3 (skipping v0.5.0, v0.5.1, v0.5.2) and get all the polish in a single update notification. + +--- + ## [0.5.2] — 2026-06-10 — Quick Stations fix: replace retired BAGeL with PopTron Hotfix for v0.5.1's Quick Stations row. David flagged: *"the stations still look a bit off"* — turned out only 13 chips were rendering instead of the intended 14. Investigation showed **BAGeL Radio has been retired from SomaFM's current `channels.json` catalogue** — the render loop's "drop missing slugs silently" behaviour (working as designed) made the chip just disappear. diff --git a/manifest.json b/manifest.json index f1c2e6b..5d2b95a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "RangerHQ Tuner", - "version": "0.5.2", + "version": "0.5.3", "description": "Lightweight SomaFM radio player. Logs what plays. One-click search to Spotify, YouTube, Apple Music, Bandcamp. No telemetry.", "author": "David Keane", "homepage_url": "https://davidtkeane.com/rangerhq-tuner",