feat(audio-player): settings popover + autoplay-on-open (plan §4)
Header gear (beside the keyboard icon) opens a 'Player settings'
popover — one option row today, structured for more: 'Autoplay on
open', a role=switch toggle persisted to localStorage audio_autoplay
('1'/'0', default off) via the normalizeAutoplay one-source helper.
maybeAutoplay() runs strictly AFTER restorePosition resolves: the
?loc=audio:<seconds> deep link keeps winning on position; the setting
only decides whether playback starts. A browser autoplay-policy
rejection (or any play() failure) is swallowed silently — the user
just taps play; the unhandled-rejection trap in init would otherwise
shout 'REJ:' into the title. settingsOpen joins closeTopSurface, so
Esc closes the panel with the other surfaces.
Unit: normalizeAutoplay tests. Live: 13 Playwright checks — default
off stays paused, toggle + persistence, reload autoplays with no
gesture, deep link lands at 600s global while autoplay starts, off
stays paused, and a stubbed NotAllowedError proves the silent
swallow; probe user created and deleted.
This commit is contained in:
1 parent
fe7eab91e8
commit
18bed79d3a
4 files changed
+115
-7
No files matched your search
+23
-1
@@ -1,6 +1,13 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { SPEEDS, normalizeSpeed, stepSpeed, SKIP_SECONDS, cycleSkip } from "./audio";
|
||||
import {
|
||||
SPEEDS,
|
||||
normalizeSpeed,
|
||||
stepSpeed,
|
||||
SKIP_SECONDS,
|
||||
cycleSkip,
|
||||
normalizeAutoplay,
|
||||
} from "./audio";
|
||||
|
||||
describe("SPEEDS", () => {
|
||||
it("is the agreed list from the player plan (0.5 through 3)", () => {
|
||||
@@ -71,3 +78,18 @@ describe("SKIP_SECONDS + cycleSkip", () => {
|
||||
expect(cycleSkip(7, -1)).toBe(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe("normalizeAutoplay", () => {
|
||||
it("is on only for explicitly-on values", () => {
|
||||
expect(normalizeAutoplay("1")).toBe(true);
|
||||
expect(normalizeAutoplay("true")).toBe(true);
|
||||
});
|
||||
|
||||
it("defaults to off for null, off, and garbage", () => {
|
||||
expect(normalizeAutoplay(null)).toBe(false);
|
||||
expect(normalizeAutoplay("0")).toBe(false);
|
||||
expect(normalizeAutoplay("")).toBe(false);
|
||||
expect(normalizeAutoplay("on")).toBe(false);
|
||||
expect(normalizeAutoplay("2")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user