fix(podcasts+ui): user-test round 3 — five browser-reported defects

1. Add-modal 'Download order' never revealed: the CSS sibling selector
   (#podcast-download-all:checked ~ .podcast-add-order) can't fire —
   the checkbox was nested inside a wrapper div, so the select row was
   no SIBLING of the input. Restructured: input, label, and order row
   are now siblings under one flex-wrap wrapper.

2. Order + auto-download dropdowns always displayed the LAST option
   ('Newest first'/'Newest') regardless of the saved value: templ's
   selected={ boolExpr } compiles to selected="false" — and the mere
   PRESENCE of the attribute selects the option, so every option was
   selected and the browser honored the last. Sweep to the boolean-
   attribute form selected?={...} (omits on false) across
   podcast_detail (14), book_detail_modals (10: manga type/reading
   direction selects + abridged/explicit checkboxes — same defect,
   always-checked), collection_modal (2: hide-finished/show-up-next
   always-checked). Values were SAVING correctly all along; this was
   pure display. audio_reader/collections :selected/:checked are
   Alpine bindings — unaffected.

3. Remove Feed (and every hx-confirm) still showed the browser dialog
   for signed-in users: the global confirm modal rendered at the end
   of SidebarSignIn — signed-IN pages have no SidebarSignIn, so no
   #confirm-modal existed and confirmDialog() degraded to
   window.confirm. Moved the modal into Header proper (rendered on
   every page, after </aside>).

4. Facet bar at scale: values now carry feed COUNTS, sort by frequency
   DESC then alphabetically, cap at 6 chips per group flat, and the
   rest collapse into a native <details> '+N more' expander — hundreds
   of hosts/tags degrade gracefully instead of a wall of chips.

Verified live on the dev instance (order select reflects the saved
override, override row persists, reveal fires, modal renders on
signed-in pages). Podcast + logout + media-pin suites green; vitest
167 green.
This commit is contained in:
John O'Keefe committed 2026-10-30 12:03:44 -04:00
1 parent 15f41e6fd4
commit 2fd0828c06
13 files changed
+1004 -948

No files matched your search

+14 -14
View File
@@ -130,10 +130,10 @@ templ PodcastDetailPage(user User, data PodcastDetailData) {
hx-target="#episode-list"
hx-swap="outerHTML"
>
<option value="native" selected={ data.Order == "native" }>Feed order</option>
<option value="reverse" selected={ data.Order == "reverse" }>Feed order (reversed)</option>
<option value="oldest" selected={ data.Order == "oldest" }>Oldest first (pub date)</option>
<option value="newest" selected={ data.Order == "newest" }>Newest first (pub date)</option>
<option value="native" selected?={ data.Order == "native" }>Feed order</option>
<option value="reverse" selected?={ data.Order == "reverse" }>Feed order (reversed)</option>
<option value="oldest" selected?={ data.Order == "oldest" }>Oldest first (pub date)</option>
<option value="newest" selected?={ data.Order == "newest" }>Newest first (pub date)</option>
</select>
<!-- Serial suggestion (D5, §0 item 3 rename): one-click,
@@ -421,9 +421,9 @@ templ PodcastAutoDownloadSelect(feed PodcastFeedCard) {
hx-target="#episode-list"
hx-swap="outerHTML"
>
<option value="off" selected={ feed.AutoDownload == "off" || feed.AutoDownload == "" }>Off</option>
<option value="all" selected={ feed.AutoDownload == "all" }>All episodes</option>
<option value="newest" selected={ feed.AutoDownload == "newest" }>Newest</option>
<option value="off" selected?={ feed.AutoDownload == "off" || feed.AutoDownload == "" }>Off</option>
<option value="all" selected?={ feed.AutoDownload == "all" }>All episodes</option>
<option value="newest" selected?={ feed.AutoDownload == "newest" }>Newest</option>
</select>
}
@@ -441,10 +441,10 @@ templ PodcastOrderSelectOOB(feedID string, order string) {
hx-target="#episode-list"
hx-swap="outerHTML"
>
<option value="native" selected={ order == "native" }>Feed order</option>
<option value="reverse" selected={ order == "reverse" }>Feed order (reversed)</option>
<option value="oldest" selected={ order == "oldest" }>Oldest first (pub date)</option>
<option value="newest" selected={ order == "newest" }>Newest first (pub date)</option>
<option value="native" selected?={ order == "native" }>Feed order</option>
<option value="reverse" selected?={ order == "reverse" }>Feed order (reversed)</option>
<option value="oldest" selected?={ order == "oldest" }>Oldest first (pub date)</option>
<option value="newest" selected?={ order == "newest" }>Newest first (pub date)</option>
</select>
}
@@ -460,9 +460,9 @@ templ PodcastAutoDownloadSelectOOB(feed PodcastFeedCard) {
hx-target="#episode-list"
hx-swap="outerHTML"
>
<option value="off" selected={ feed.AutoDownload == "off" || feed.AutoDownload == "" }>Off</option>
<option value="all" selected={ feed.AutoDownload == "all" }>All episodes</option>
<option value="newest" selected={ feed.AutoDownload == "newest" }>Newest</option>
<option value="off" selected?={ feed.AutoDownload == "off" || feed.AutoDownload == "" }>Off</option>
<option value="all" selected?={ feed.AutoDownload == "all" }>All episodes</option>
<option value="newest" selected?={ feed.AutoDownload == "newest" }>Newest</option>
</select>
}