From f3c94641a7ded3d1751fda16ab4b733171bbf1e2 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Wed, 7 Oct 2026 00:36:28 +0200 Subject: [PATCH] fix(player): a library item played from the start keeps its point A cached file that autoplays from 0:00 fires its one playing event before the resume hook subscribes, so the hook never counted it as played and reported nothing - not on pause, not on close. An element already playing when the hook subscribes now counts as played. --- frontend/src/lib/resume.dom.test.ts | 12 ++++++++++++ frontend/src/lib/resume.ts | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/resume.dom.test.ts b/frontend/src/lib/resume.dom.test.ts index 29053ec7..aa071ace 100644 --- a/frontend/src/lib/resume.dom.test.ts +++ b/frontend/src/lib/resume.dom.test.ts @@ -94,6 +94,18 @@ describe("useResume", () => { expect(save).toHaveBeenLastCalledWith(42, 600, true); }); + it("counts an element already playing when it subscribes as played", () => { + // A cached file started from 0 autoplays before the effect runs: its one `playing` is gone. + const m = fakeMedia(); + m.metadata(); + m.play(); + const save = vi.fn(); + renderHook(() => useResume(m.el, "7", 0, save)); + m.at(42); + m.pause(); + expect(save).toHaveBeenLastCalledWith(42, 600, false); + }); + it("checkpoints while it plays, at most once per interval", () => { vi.useFakeTimers(); const m = fakeMedia(); diff --git a/frontend/src/lib/resume.ts b/frontend/src/lib/resume.ts index 396d4d44..c0f49428 100644 --- a/frontend/src/lib/resume.ts +++ b/frontend/src/lib/resume.ts @@ -48,7 +48,9 @@ export function useResume( const report = useEffectEvent(save); useEffect(() => { if (!media || itemKey == null) return; - let played = false; + // Already playing counts as played: a cached file that autoplays from the start can fire its + // one `playing` before this effect subscribes, and would then never report at all. + let played = !media.paused; let lastAt = 0; const duration = () => (Number.isFinite(media.duration) ? media.duration : 0); const put = (leaving: boolean) => {