John O'Keefe
db96ea91cd
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.
2026-10-21 21:08:27 -04:00
..
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-13 12:24:12 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 16:38:03 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-18 18:02:34 -04:00
2026-10-15 19:33:18 -04:00
2026-10-15 19:33:18 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-21 21:08:27 -04:00
2026-10-21 21:08:27 -04:00
2026-10-20 19:38:02 -04:00
2026-10-19 15:43:59 -04:00
2026-10-21 20:21:33 -04:00
2026-10-21 20:21:33 -04:00
2026-05-24 21:20:24 -04:00
2026-03-27 15:52:02 -04:00
2026-10-20 19:38:02 -04:00
2026-10-20 15:36:31 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-19 15:43:59 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-19 15:43:59 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:42:50 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 16:45:48 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-08-10 13:43:13 -04:00
2026-10-20 19:38:02 -04:00
2026-08-10 13:43:13 -04:00
2026-10-20 19:38:02 -04:00
2026-10-19 18:59:36 -04:00
2026-10-20 19:38:02 -04:00
2026-08-05 16:45:02 -04:00
2026-10-20 19:38:02 -04:00
2026-10-19 12:40:31 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:07 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:07 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 13:16:35 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:07 -04:00
2026-10-18 16:45:48 -04:00
2026-10-20 19:38:02 -04:00
2026-10-14 11:08:12 -04:00
2026-10-20 19:38:02 -04:00
2026-08-05 16:45:02 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-21 20:21:07 -04:00
2026-10-21 20:21:07 -04:00
2026-10-18 12:08:07 -04:00
2026-10-18 12:08:07 -04:00
2026-08-05 16:45:02 -04:00
2026-08-05 16:45:02 -04:00
2026-10-20 19:38:02 -04:00
2026-10-19 12:39:20 -04:00
2026-10-03 23:54:07 -04:00
2026-10-18 16:38:03 -04:00
2026-10-18 16:38:03 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 12:08:20 -04:00
2026-10-18 12:08:07 -04:00
2026-10-18 12:08:07 -04:00
2026-10-18 12:08:07 -04:00
2026-10-20 19:38:02 -04:00
2026-05-10 16:13:21 -04:00
2026-10-19 15:43:59 -04:00
2026-10-20 19:38:02 -04:00
2026-10-18 16:00:04 -04:00
2026-10-19 18:59:36 -04:00
2026-10-20 08:24:36 -04:00