From ee6df1e1fe048bc7eeef4a2cdf0d69ac0491fbf0 Mon Sep 17 00:00:00 2001 From: Honey Date: Thu, 14 May 2026 19:21:29 +0200 Subject: [PATCH] fix: prevent music canplay callback from interrupting ABS playback start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When absPlayItem() paused S.audio, the stale canplay listener from the last playCurrent() call still had a matching _playGen value and would call S.audio.play() — triggering absInterrupt() which immediately paused the ABS audio. Fix: export cancelMusicAutoplay() that bumps _playGen before pausing, invalidating any pending canplay/guard callbacks. Also shrink OK button and widen time input in sleep timer. Co-Authored-By: Claude Sonnet 4.6 --- src/abs.js | 3 ++- src/player.js | 4 ++++ styles.css | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/abs.js b/src/abs.js index 1a41da5..bef7f40 100644 --- a/src/abs.js +++ b/src/abs.js @@ -1,5 +1,6 @@ import { S } from './state.js'; import { esc, toast } from './utils.js'; +import { cancelMusicAutoplay } from './player.js'; // ─── HTTP HELPERS ─── // API calls are routed through the NovaSonic backend proxy to avoid CORS restrictions. @@ -204,7 +205,7 @@ export async function absPlayItem(item) { const ap = S.absPlayer; const audio = _getAudio(); - if (!S.audio.paused) S.audio.pause(); // stop music if playing + cancelMusicAutoplay(); // pause music + invalidate any stale canplay callbacks if (ap._sessionId) { absCloseSession(ap._sessionId); ap._sessionId = null; } _stopSync(); audio.pause(); diff --git a/src/player.js b/src/player.js index 4fb0957..05bcd60 100644 --- a/src/player.js +++ b/src/player.js @@ -433,6 +433,10 @@ export function _syncNpDirect(s) { syncNpStar(); } +// Bump _playGen so any stale canplay/guard callbacks from the last playCurrent() +// bail out and don't call S.audio.play() after ABS has taken over audio. +export function cancelMusicAutoplay() { _playGen++; S.audio.pause(); } + // ─── TRANSPORT ──────────────────────────────────────────────────────────── export function togglePlay() { diff --git a/styles.css b/styles.css index be86016..c49a302 100644 --- a/styles.css +++ b/styles.css @@ -956,7 +956,7 @@ nav{flex:1;overflow-y:auto;padding:4px 10px} .abs-sleep-custom-row input:focus{border-color:var(--accent)} .abs-sleep-custom-row input[type=number]::-webkit-inner-spin-button,.abs-sleep-custom-row input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0} .abs-sleep-custom-row input[type=number]{-moz-appearance:textfield} -.abs-sleep-custom-ok{flex-shrink:0;padding:4px 10px;background:var(--accent);border:none;border-radius:6px;color:#fff;font-family:var(--font);font-size:12px;font-weight:600;cursor:pointer} +.abs-sleep-custom-ok{flex-shrink:0;padding:3px 7px;background:var(--accent);border:none;border-radius:5px;color:#fff;font-family:var(--font);font-size:11px;font-weight:600;cursor:pointer} .abs-chapter-list{flex-shrink:0;overflow-y:auto;max-height:0;transition:max-height .3s ease;border-top:1px solid transparent} .abs-chapter-list.open{max-height:220px;border-color:var(--border)} .abs-ch-item{display:flex;align-items:center;gap:10px;padding:8px 20px;cursor:pointer;transition:background .15s}