From 597675d6a021742af8514947dba8d68da03ba3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Tue, 28 Jul 2026 12:44:25 +0000 Subject: [PATCH] fix: paused track resumed on any page click (unlock listener overrode pause) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AudioContext autoplay-unlock listener (pointerdown → ctx.resume()) was persistent, so every click anywhere resumed the context — including after a deliberate pause (pause = ctx.suspend()). Result: pause, click back on the page, and the track resumed from its position while React's `playing` stayed false, so the button showed "paused" and it took two clicks to actually stop it. The gesture only needs to unlock the context ONCE; sticky activation lets engine.play() resume it thereafter. Make the listener { once: true } so it can't fight an intentional pause. Co-Authored-By: Claude Opus 4.8 --- .../officerdev/src/MusicPlayer/MusicPlayerHost.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx b/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx index 461b1d2e..ec99306f 100644 --- a/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx +++ b/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx @@ -106,9 +106,11 @@ export const MusicPlayerHost = () => { }); engineRef.current = engine; engine.setVolume(muted ? 0 : volume); - // Resume the AudioContext on the first user gesture (browser autoplay policy). + // Satisfy the browser autoplay policy ONCE, on the first user gesture — after that, sticky activation + // lets engine.play() resume the context on its own. It MUST be once-only: a persistent listener would + // resume the context on every click, overriding a deliberate pause (pause = ctx.suspend()). const unlock = () => engine.unlock(); - document.addEventListener('pointerdown', unlock); + document.addEventListener('pointerdown', unlock, { once: true }); return () => { document.removeEventListener('pointerdown', unlock); engine.destroy();