Files
rangerhq-tuner/CHANGELOG.md
T
ranger 38b6b8d3f7 feat: initial commit — RangerHQ Tuner v0.1.0 (Tier 1 MVP)
Chrome MV3 extension, browser-resident sibling to rangerhq-radio
(WP plugin). Plays SomaFM via the chrome.offscreen API + a source-
adapter pattern at src/sources/.

Architecture highlights:
- Audio runs in offscreen document — SW would get killed.
- Source-adapter pattern locks Tier 1 contract (RadioSource interface
  in src/sources/base-source.js). Adding a network = drop a file +
  register one line in src/sources/index.js.
- Vanilla JS, no build step. Pure ES modules.
- No telemetry, no third-party JS. Outbound only to somafm.com.
- Narrow permissions: offscreen + storage + somafm.com host_perms.
  No tabs, no <all_urls>, no webRequest.

22 files, ~30 min build following the saved plan at
~/.ranger-memory/projects/rangerhq-tuner-plan.md.

Tier 2 + Tier 3 (Web Store submission) not started.
2026-06-08 23:31:29 +01:00

4.8 KiB
Raw Blame History

Changelog

All notable changes to RangerHQ Tuner are documented here. Format: Keep a Changelog 1.1.0 — versioning: SemVer.


[Unreleased]

Planned — New Tab Page override (Tier 2.5)

  • Replace Chrome's default New Tab Page with a RangerHQ-branded version that surfaces the player, current track, and a quick-station picker.
  • Adds chrome_url_overrides.newtab to manifest.json pointing at src/newtab/newtab.html.
  • Reuses the popup's CSS palette + source-adapter pattern — no new architectural concepts.

[0.1.0] — 2026-06-08

Added — Tier 1 MVP (Buddy is alive — er, Tuner is alive)

Buddy's browser cousin lives. First release of RangerHQ Tuner — a Chrome Manifest V3 extension that plays SomaFM internet radio from your toolbar. Sibling to rangerhq-radio (the WordPress version live on wp.org since 2026-06-04). Same brand idea, different surface: WP version lives in admin pages, Chrome version lives one toolbar-click away no matter what you're doing.

Architecture

  • Manifest V3 — uses the chrome.offscreen API to host the <audio> element in a hidden document. Service workers can't host audio in MV3 (they get killed when idle), so a one-off offscreen document is the only supported pattern. Working code in src/offscreen/offscreen.js + src/background/service-worker.js.
  • Source-adapter pattern at src/sources/ — every radio network is a single file conforming to the RadioSource interface in base-source.js. Adding a new network = drop a new file + register one line in src/sources/index.js. Popup, SW, and offscreen never know which network is which.
  • Vanilla JS, no build step — pure ES modules loaded directly. No webpack, no Vite, no npm install. Same ethos as the RangerHQ WP family (hand-rolled PHP).
  • No telemetry, no third-party JS — everything is local. Only outbound network calls are to SomaFM's public endpoints (catalogue + stream metadata).

Features

  • Toolbar popup showing a searchable SomaFM station list (~150 channels) with artwork, name, and genre.
  • Play / Pause / Volume controls. Volume persists across browser restarts.
  • Last station picked is remembered — Tuner remembers where you left off.
  • Now-playing metadata displayed from SomaFM's per-channel song history endpoint.
  • Catalogue cached in chrome.storage.local for 6 hours to make popup re-opens instant.
  • Audio continues after popup closes — the offscreen document owns the playback, popup is just a view.
  • RangerHQ helmet icon in the Chrome toolbar (resized from src/assets/img/ranger.png to 16/32/48/128 PNGs with a dark #1a221c padded background that matches the popup palette).

Files (22 created)

rangerhq-tuner/
├── manifest.json
├── README.md
├── CHANGELOG.md
├── .gitignore
└── src/
    ├── assets/
    │   ├── icons/icon-{16,32,48,128}.png   (toolbar icons)
    │   └── img/ranger.png                  (master helmet logo, 257×275)
    ├── background/service-worker.js        (message router only)
    ├── offscreen/offscreen.{html,js}       (audio host — the MV3 gotcha solved)
    ├── popup/popup.{html,css,js}           (the toolbar UI)
    ├── sources/
    │   ├── base-source.js                  (RadioSource interface contract)
    │   ├── somafm.js                       (first concrete adapter)
    │   └── index.js                        (registry)
    └── lib/
        ├── messages.js                     (type + target constants)
        └── playlist-parser.js              (.pls parser)

Manifest permissions (narrow on purpose)

"permissions":      ["offscreen", "storage"],
"host_permissions": ["https://somafm.com/*", "https://*.somafm.com/*"]

No tabs, no <all_urls>, no webRequest. Smallest permission ask possible = easiest Web Store review.

Architecture / status

  • Tier 1 MVP — shipped this commit.
  • Tier 2 (planned) — full UX polish, favourites via chrome.storage.sync, now-playing polling loop, .m3u parser, .crx packaging, second source adapter stub.
  • Tier 3 (planned) — Chrome Web Store submission. See ~/.ranger-memory/docs/ for the per-family submission checklist; Chrome Web Store specifics tracked in the user's memory under reference_chrome_web_store_rules.

Why this exists

David has Chrome open essentially all day. The WP version of RangerHQ Radio requires going to admin pages to use; the toolbar version is one click away regardless of context. Same code-level effort, dramatically higher daily-use payoff. The "best thing we done so far" verdict on first sound (2026-06-08 evening) confirmed the bet.

Rangers lead the way 🪖🎵