38b6b8d3f7
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.
84 lines
4.8 KiB
Markdown
84 lines
4.8 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to **RangerHQ Tuner** are documented here.
|
||
Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/) — versioning: [SemVer](https://semver.org/).
|
||
|
||
---
|
||
|
||
## [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`](https://git.davidtkeane.com/ranger/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)
|
||
|
||
```json
|
||
"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 🪖☕🎵
|