feat(audio-player): gear-menu default speed + split shortcuts into Mouse/Touch (plan §12)
Release / build-and-push (push) Successful in 3m13s

The Player settings popover gains a 'Default playback speed' row
beside autoplay — a compact rate select, always visible (the Speed ▾
footer hides when current == default, which made the setting
undiscoverable at 1x/1×); same setDefaultSpeed PUT. The shortcuts
dialog splits its pointer section into MOUSE (click/drag/shift/wheel)
and TOUCH (drag/pull-away) — the bar has two scrub systems and the
sections now say so.
This commit is contained in:
John O'Keefe committed 2026-10-22 15:39:14 -04:00
1 parent 3576a4415a
commit 03c3e151dc
4 files changed
+119 -28

No files matched your search

+30 -4
View File
@@ -145,6 +145,25 @@ templ AudioReader(user User, metadata ReaderMetadata) {
<span class="absolute top-0.5 left-0.5 h-4 w-4 rounded-full transition-transform" :class="autoplayOn ? 'translate-x-4' : ''" style="background-color: var(--text-primary);"></span>
</button>
</div>
<!-- §12: default speed — always visible (unlike the
Speed ▾ footer, which hides when the current rate
IS the default), same setDefaultSpeed PUT -->
<div class="flex items-center justify-between gap-3 px-1 py-2 rounded-lg">
<span class="text-sm" style="color: var(--text-secondary);">Default playback speed</span>
<select
class="text-xs rounded-md px-1.5 py-1"
style="background-color: var(--surface-hover); color: var(--text-primary); border: 1px solid var(--border);"
aria-label="Default playback speed"
@change="setDefaultSpeed(Number($event.target.value))"
>
for _, rate := range SpeedOptions {
<option
value={ fmt.Sprintf("%g", rate) }
:selected={ fmt.Sprintf("Number(defaultSpeed) === %g", rate) }
>{ fmt.Sprintf("%g×", rate) }</option>
}
</select>
</div>
</div>
</div>
</span>
@@ -689,10 +708,17 @@ templ AudioReader(user User, metadata ReaderMetadata) {
</span>
</div>
</template>
<!-- Pointer gestures (audio-keys.ts POINTER_GUIDE): same
dialog, so every scrub interaction is discoverable -->
<div class="mt-3 mb-1 px-2 text-xs font-semibold uppercase tracking-wide" style="color: var(--text-secondary);">Mouse &amp; touch</div>
<template x-for="row in pointerGuide" :key="row.label">
<!-- Pointer gestures (audio-keys.ts MOUSE_GUIDE/TOUCH_GUIDE):
two sections — the bar has two scrub systems -->
<div class="mt-3 mb-1 px-2 text-xs font-semibold uppercase tracking-wide" style="color: var(--text-secondary);">Mouse</div>
<template x-for="row in mouseGuide" :key="'m' + row.label">
<div class="flex items-center justify-between gap-3 px-2 py-1.5 rounded-lg">
<span class="text-sm" style="color: var(--text-secondary);" x-text="row.description"></span>
<kbd class="text-xs px-1.5 py-0.5 rounded tabular-nums shrink-0" style="background-color: var(--surface-hover); color: var(--text-primary); border: 1px solid var(--border);" x-text="row.label"></kbd>
</div>
</template>
<div class="mt-3 mb-1 px-2 text-xs font-semibold uppercase tracking-wide" style="color: var(--text-secondary);">Touch</div>
<template x-for="row in touchGuide" :key="'t' + row.label">
<div class="flex items-center justify-between gap-3 px-2 py-1.5 rounded-lg">
<span class="text-sm" style="color: var(--text-secondary);" x-text="row.description"></span>
<kbd class="text-xs px-1.5 py-0.5 rounded tabular-nums shrink-0" style="background-color: var(--surface-hover); color: var(--text-primary); border: 1px solid var(--border);" x-text="row.label"></kbd>