From db96ea91cd38e30dd803cc138cdf27d474ed04d1 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Wed, 21 Oct 2026 21:08:15 -0400 Subject: [PATCH] =?UTF-8?q?refactor(audio-player):=20one=20source=20for=20?= =?UTF-8?q?the=20speed=20list=20(plan=20=C2=A75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- templates/audio_reader.templ | 2 +- templates/audio_reader_templ.go | 2 +- web/src/audio.test.ts | 55 +++++++++++++++++++++++++++++++++ web/src/audio.ts | 37 ++++++++++++++++++++-- 4 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 web/src/audio.test.ts diff --git a/templates/audio_reader.templ b/templates/audio_reader.templ index 4b95ea91..f5aaef04 100644 --- a/templates/audio_reader.templ +++ b/templates/audio_reader.templ @@ -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;" > -