feat(radio): wire radio + similarity into the queue (A11/B6, §6.5)
"Start radio" in the track menu seeds the queue from a track; RadioController
(headless, in AppShell) tops it up via /radio/next as it drains. QueuePanel's
radio scaffolding is now live: the exploration slider drives familiar<->new and
each entry shows its reason ("why this is playing"). Adds the radio endpoints
(start/next/similar), radio context + actions on the queue slice, and the pick->
entry mapper. Degrades to metadata picks while ML is offline.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -192,6 +192,20 @@ export interface DuplicateGroup {
|
||||
tracks: Track[];
|
||||
}
|
||||
|
||||
/** One radio/similarity pick with its reason code (§6.5). `reason`: `ml` |
|
||||
* `similar` | `from_likes` | `discover` — localized client-side. */
|
||||
export interface RadioPick {
|
||||
track: Track;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
/** Radio / similar response: where the picks came from + the picks. `source`:
|
||||
* `ml` (recommender) or `metadata` (fallback heuristics). */
|
||||
export interface RadioResult {
|
||||
source: string;
|
||||
picks: RadioPick[];
|
||||
}
|
||||
|
||||
/** Cached lyrics for a track (§6.7). `not_found` is a normal state, not an
|
||||
* error. `synced` is raw LRC (client parses timestamps); `plain` is fallback. */
|
||||
export interface Lyrics {
|
||||
|
||||
Reference in New Issue
Block a user