fix: ignore onQueueEnded before onReady fires — prevents stale end-of-song event from advancing queue on app reopen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
21d55d8ab0
commit
b924f01b2a
1 file changed
+8
-6
+8
-6
@@ -15,6 +15,7 @@ let _nativePlaying = false;
|
|||||||
let _lastPositionMs = 0; // ms — set by onPositionUpdate, used for prev() decision
|
let _lastPositionMs = 0; // ms — set by onPositionUpdate, used for prev() decision
|
||||||
let _lastDurationMs = 0; // ms — set by onPositionUpdate, used for seek calculations
|
let _lastDurationMs = 0; // ms — set by onPositionUpdate, used for seek calculations
|
||||||
let _readyTs = 0; // timestamp of last onReady — used to suppress spurious onQueueEnded
|
let _readyTs = 0; // timestamp of last onReady — used to suppress spurious onQueueEnded
|
||||||
|
let _bridgeReady = false; // true once onReady has fired; onQueueEnded is ignored before this
|
||||||
|
|
||||||
// ─── SCROBBLE ─────────────────────────────────────────────────────────────
|
// ─── SCROBBLE ─────────────────────────────────────────────────────────────
|
||||||
let _scrobbleTimer = null;
|
let _scrobbleTimer = null;
|
||||||
@@ -85,9 +86,9 @@ window.NSPlayer = {
|
|||||||
|
|
||||||
// Called when MediaController connects (first load or WebView reload).
|
// Called when MediaController connects (first load or WebView reload).
|
||||||
onReady() {
|
onReady() {
|
||||||
// Guard window: ignore onQueueEnded for 1.5s after reconnect.
|
// Mark bridge as ready: onQueueEnded fired before this point came from a previous
|
||||||
// ExoPlayer can deliver a stale STATE_ENDED callback right after the MediaController
|
// session (song finished while backgrounded) and must not advance the queue.
|
||||||
// reconnects to a session whose last track had already finished.
|
_bridgeReady = true;
|
||||||
_readyTs = Date.now();
|
_readyTs = Date.now();
|
||||||
|
|
||||||
if (HAS_BRIDGE && S.queue.length > 0) {
|
if (HAS_BRIDGE && S.queue.length > 0) {
|
||||||
@@ -216,9 +217,10 @@ window.NSPlayer = {
|
|||||||
|
|
||||||
// Single track finished — JS drives what plays next.
|
// Single track finished — JS drives what plays next.
|
||||||
onQueueEnded() {
|
onQueueEnded() {
|
||||||
// Suppress if fired within 1.5s of onReady — ExoPlayer can replay a stale STATE_ENDED
|
// Ignore if onReady hasn't fired yet: the song ended while the app was backgrounded
|
||||||
// callback right after the MediaController reconnects, which would skip the queue.
|
// and the callback arrived before the new page session is fully connected.
|
||||||
if (Date.now() - _readyTs < 1500) return;
|
// Also ignore the brief window right after onReady (stale STATE_ENDED replay).
|
||||||
|
if (!_bridgeReady || Date.now() - _readyTs < 1500) return;
|
||||||
_nativePlaying = false;
|
_nativePlaying = false;
|
||||||
setPlayIcon(false);
|
setPlayIcon(false);
|
||||||
onEnded(); // handles repeat, radio top-up, and queue advance
|
onEnded(); // handles repeat, radio top-up, and queue advance
|
||||||
|
|||||||
Reference in new issue
Block a user