fix: stop ExoPlayer shuffle conflict causing end-of-queue desync

When reaching the last shuffled song, the UI changed but audio kept playing
the same song. Root cause: ExoPlayer still had its own shuffle mode on (set
in onReady), so its auto-advance and _nsBridge('next') picked random indices
that conflicted with the pre-shuffled JS array.

- setShuffleMode always false: we own the playback order via pre-shuffled
  JS array, ExoPlayer must advance sequentially through it
- Remove _nsBridge('next') fallback: never let ExoPlayer decide the next
  song autonomously. End of queue with no repeat = let ExoPlayer stop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-04 11:13:45 +02:00
1 parent ef40795a9c
commit db7a515ee4
1 file changed
+4 -5
+4 -5
View File
@@ -130,8 +130,10 @@ window.NSPlayer = {
} catch (e) {}
}
// Always sync shuffle/repeat settings.
// setShuffleMode is always false — we pre-shuffle the JS array ourselves and
// traverse sequentially, so ExoPlayer's internal shuffle must stay off.
_nsBridge('setRepeatMode', S.repeat === false ? 'off' : S.repeat);
_nsBridge('setShuffleMode', S.shuffle);
_nsBridge('setShuffleMode', false);
},
// Play/pause/buffer state changed.
@@ -714,10 +716,7 @@ export function nextSong() {
// Explicit index prevents desync when JS and native queue pointers diverge.
_nsBridge('seekToIndex', ni, 0);
_nsBridge('play');
} else {
// Shuffle mode: native picks the shuffled-next item; onTrackChanged will confirm the index.
_nsBridge('next');
}
// else: ni = -1 means end of queue with no repeat — let ExoPlayer stop naturally.
if (S.radioMode && S.queue.length - S.qIdx < 5) fillRadioQueue();
return;
}