fix: prevent music canplay callback from interrupting ABS playback start

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 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-14 19:21:29 +02:00
1 parent f5343efd37
commit ee6df1e1fe
3 files changed
+7 -2

No files matched your search

+2 -1
View File
@@ -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();
+4
View File
@@ -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() {
+1 -1
View File
@@ -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}