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
@@ -206,6 +206,21 @@ function fmtTime(seconds: number): string {
|
||||
return `${m}:${String(sec).padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
// Player order control (item 2.2, feed-mode only): the header's select
|
||||
// and reverse button PUT the feed's per-user order override (the same
|
||||
// endpoint the feed page writes) with hx-swap="none" — the response is
|
||||
// discarded, and THIS reload is the swap: the server re-renders the
|
||||
// sequence context (prev/next/index) in the new order. Rendered only
|
||||
// when the queue source is "feed" (§10 R2 — collection queues hide it).
|
||||
document.addEventListener("htmx:afterRequest", (e) => {
|
||||
const target = e.target as HTMLElement | null;
|
||||
if (!target || !target.matches("#player-order-select, [aria-label='Reverse episode order']"))
|
||||
return;
|
||||
const evt = e as CustomEvent<{ successful?: boolean }>;
|
||||
if (!evt.detail?.successful) return;
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
Alpine.data("audioReader", () => ({
|
||||
mediaItemId: "",
|
||||
title: "",
|
||||
|
||||
Reference in new issue
Block a user