feat(web): segment watched/skipped action toggles

Watched and skipped are mutually exclusive (the store clears one when the other
is set), but rendered as three independent-looking buttons the exclusivity was
invisible. Group watched|skipped into a single segmented control and keep Saved
apart as an independent toggle (UX review C5). HTMX posting and the active/✓/
aria-pressed semantics are unchanged; extracted a shared actionButton component.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 14:02:31 +02:00
co-authored by Claude Opus 4.8
parent f775441a62
commit 51aa5d940c
4 changed files with 148 additions and 88 deletions
+26 -15
View File
@@ -530,20 +530,31 @@ templ ActionButtons(videoID string, active map[string]bool) {
hx-target="#action-buttons"
hx-swap="outerHTML"
>
for _, v := range actionVerbs {
<button
type="submit"
name="action"
value={ v }
class={ "action", templ.KV("active", active[v]) }
aria-pressed={ ariaPressed(active[v]) }
>
if active[v] {
{ "✓ " + actionLabel(v) }
} else {
{ actionLabel(v) }
}
</button>
}
// watched ↔ skipped are mutually exclusive (the store clears one when the
// other is set), so they read as a single segmented choice. "saved" is an
// independent toggle and sits apart (UX review C5).
<span class="segmented" role="group" aria-label="Watched or skipped">
@actionButton("watched", active["watched"])
@actionButton("skipped", active["skipped"])
</span>
@actionButton("saved", active["saved"])
</form>
}
// actionButton is one toggle button in the action group: a submit carrying its
// verb, marked active (accent fill + ✓ prefix + aria-pressed) when currently set.
templ actionButton(verb string, isActive bool) {
<button
type="submit"
name="action"
value={ verb }
class={ "action", templ.KV("active", isActive) }
aria-pressed={ ariaPressed(isActive) }
>
if isActive {
{ "✓ " + actionLabel(verb) }
} else {
{ actionLabel(verb) }
}
</button>
}