feat(podcasts): queue context source + player order control — item 2.2
Foundation rule R2 (§10): the queue context is the only queue, and every producer emits the same shape. PodcastSequenceContext gains source (feed|collection), feed_id, and order; the feed producer sets them now — the collection producer (2.3) slots into the same shape without the player ever special-casing beyond showing/hiding controls. The player header gains the FEED-mode order control next to the "Ep N/M" counter: a dropdown (native/reverse/oldest/newest) plus a one-click reverse button. Both PUT the existing per-user feed order override — the SAME state the feed page writes, so flipping it in the player updates the feed page's dropdown too. The control renders only when source=feed: a collection queue's order is curated content (R1), never a listening preference. Behavior is hx-put + hx-swap="none" (response discarded) with a module-level htmx:afterRequest listener in audio.ts reloading the page — the server re-renders prev/next/index in the new order; templ decides what it looks like, JS only triggers the round trip (CSP-clean, no inline handlers). Pinned by TestPodcastPlayerOrderControl: the config JSON carries source/feed_id/order/episode_index; the control renders feed-mode; an order override re-renders with the dropdown reflecting it (data- json pins must match templ's " attribute escaping).
This commit is contained in:
1 parent
7bf0b1257d
commit
a90e7debfd
6 files changed
+279
-81
No files matched your search
@@ -327,6 +327,19 @@ type PodcastSequenceContext struct {
|
||||
PrevURL string `json:"prev_url,omitempty"`
|
||||
NextURL string `json:"next_url,omitempty"`
|
||||
NextTitle string `json:"next_title,omitempty"`
|
||||
// Source is the queue's owner (§10 R2: every producer emits the
|
||||
// same shape): "feed" = the feed's effective order (per-user
|
||||
// override applied), "collection" = an ordered Up Next collection
|
||||
// (2.3). The player shows/hides controls by source — the order
|
||||
// control is FEED-mode only, because a collection's order is
|
||||
// curated content, not a listening preference.
|
||||
Source string `json:"source,omitempty"`
|
||||
// Feed-mode fields: FeedID powers the player's order control (it
|
||||
// PUTs /api/podcasts/feeds/:id/order — the same per-user override
|
||||
// the feed page writes); Order is the resolved current value that
|
||||
// the dropdown reflects. Empty in collection mode.
|
||||
FeedID string `json:"feed_id,omitempty"`
|
||||
Order string `json:"order,omitempty"`
|
||||
// EpisodeIndex/IndexTotal render the "Ep N of M" indicator (D7).
|
||||
EpisodeIndex int `json:"episode_index,omitempty"`
|
||||
IndexTotal int `json:"index_total,omitempty"`
|
||||
|
||||
Reference in new issue
Block a user