refactor(audio-player): one source for the speed list (plan §5)

The rate list was duplicated — hardcoded in the templ x-for AND
implicitly in audio.ts — and phase 2's keyboard stepping would have
needed a third copy. SPEEDS is now the single exported const (the
agreed nine values, 0.5 through 3); the component exposes it as
'speeds' for the dropdown's x-for (templ cannot import TS), and
stepSpeed() walks the same array for the future audio-keys consumer.

normalizeSpeed() maps persisted values onto the list: garbage or
out-of-list localStorage entries fall back to 1x, and init() writes
the normalized value back so storage heals instead of staying
poisoned.

Pure logic unit-tested in audio.test.ts; live-verified with Playwright
on the KJV folder book: nine options render, pick/reload/persist and
the stale-value fallback all behave, button label and
audio.playbackRate agree in every case.
This commit is contained in:
John O'Keefe committed 2026-10-21 21:08:27 -04:00
1 parent 408a972665
commit db96ea91cd
4 files changed
+91 -5

No files matched your search

+1 -1
View File
@@ -249,7 +249,7 @@ templ AudioReader(user User, metadata ReaderMetadata) {
class="absolute bottom-full mb-2 left-1/2 -translate-x-1/2 rounded-xl shadow-lg p-1.5 flex flex-col min-w-[7rem]"
style="background-color: var(--bg-secondary); border: 1px solid var(--border); z-index: 30;"
>
<template x-for="rate in [0.75, 1, 1.25, 1.5, 2]" :key="'speed' + rate">
<template x-for="rate in speeds" :key="'speed' + rate">
<button
type="button"
@click="setSpeed(rate); speedOpen = false"