fix: correct onReady sync logic for single-track model; remove stale _setSkipping call
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
3252706dc2
commit
ac474b1760
1 file changed
+28
-22
+28
-22
@@ -90,41 +90,48 @@ window.NSPlayer = {
|
|||||||
const state = raw ? (JSON.parse(raw) || {}) : {};
|
const state = raw ? (JSON.parse(raw) || {}) : {};
|
||||||
const nativeLen = state.queueLength || 0;
|
const nativeLen = state.queueLength || 0;
|
||||||
const nativePlaying = state.isPlaying || false;
|
const nativePlaying = state.isPlaying || false;
|
||||||
const nativeIdx = typeof state.currentIndex === 'number' ? state.currentIndex : S.qIdx;
|
|
||||||
const nativeId = state.currentId || '';
|
const nativeId = state.currentId || '';
|
||||||
|
|
||||||
// Helper: true if native's current song matches JS queue at nativeIdx
|
// Single-track model: native index is always 0, meaningless for queue position.
|
||||||
const inSync = nativeIdx >= 0 && nativeIdx < S.queue.length &&
|
// Match by song ID against S.queue[S.qIdx] — the JS-side current position.
|
||||||
(!nativeId || !S.queue[nativeIdx]?.id ||
|
const currentSong = S.queue[S.qIdx];
|
||||||
String(nativeId) === String(S.queue[nativeIdx].id));
|
const idMatch = !nativeId || !currentSong?.id ||
|
||||||
|
String(nativeId) === String(currentSong.id);
|
||||||
|
|
||||||
if (nativeLen > 0 && nativePlaying) {
|
if (nativeLen > 0 && nativePlaying) {
|
||||||
if (inSync) {
|
if (idMatch) {
|
||||||
// Native is actively playing and we have the right song — re-sync.
|
// Native is playing our current song — re-sync UI without touching S.qIdx.
|
||||||
S.qIdx = nativeIdx;
|
|
||||||
_nativePlaying = true;
|
_nativePlaying = true;
|
||||||
_nativePos = state.positionMs || 0;
|
_nativePos = state.positionMs || 0;
|
||||||
const s = S.queue[S.qIdx];
|
if (currentSong) { updatePlayerUI(currentSong, true); onNpSongChange(currentSong.id); }
|
||||||
if (s) { updatePlayerUI(s, true); onNpSongChange(s.id); }
|
|
||||||
setPlayIcon(true);
|
setPlayIcon(true);
|
||||||
renderQueue();
|
renderQueue();
|
||||||
} else {
|
} else {
|
||||||
// Native is playing a song we don't have (e.g. radio advanced while backgrounded).
|
// Native advanced to a different song while backgrounded — find it in the queue.
|
||||||
// Reset the stale JS queue to avoid showing the wrong song — native keeps playing.
|
const found = nativeId ? S.queue.findIndex(s => String(s.id) === String(nativeId)) : -1;
|
||||||
S.queue = [];
|
if (found >= 0) {
|
||||||
S.qIdx = 0;
|
S.qIdx = found;
|
||||||
|
_nativePlaying = true;
|
||||||
|
_nativePos = state.positionMs || 0;
|
||||||
|
const s = S.queue[S.qIdx];
|
||||||
|
if (s) { updatePlayerUI(s, true); onNpSongChange(s.id); }
|
||||||
|
setPlayIcon(true);
|
||||||
|
renderQueue();
|
||||||
|
} else {
|
||||||
|
// Playing a song not in our queue (radio advanced past known tracks) — clear.
|
||||||
|
S.queue = [];
|
||||||
|
S.qIdx = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (nativeLen > 0 && inSync) {
|
} else if (nativeLen > 0 && !nativePlaying && idMatch) {
|
||||||
// Paused but we can confirm the current song — re-sync UI state only.
|
// Paused, song matches — re-sync UI state only.
|
||||||
S.qIdx = nativeIdx;
|
|
||||||
_nativePlaying = false;
|
_nativePlaying = false;
|
||||||
_nativePos = state.positionMs || 0;
|
_nativePos = state.positionMs || 0;
|
||||||
const s = S.queue[S.qIdx];
|
if (currentSong) { updatePlayerUI(currentSong, true); onNpSongChange(currentSong.id); }
|
||||||
if (s) { updatePlayerUI(s, true); onNpSongChange(s.id); }
|
|
||||||
setPlayIcon(false);
|
setPlayIcon(false);
|
||||||
renderQueue();
|
renderQueue();
|
||||||
} else if (!nativePlaying) {
|
} else {
|
||||||
// Native is idle/empty — push just the current song (single-track model).
|
// Native is idle/empty or has a mismatched paused song — push current (single-track model).
|
||||||
const s = S.queue[S.qIdx];
|
const s = S.queue[S.qIdx];
|
||||||
if (s) window.NSBridge.setQueue(_nativeSingle(s), 0, false);
|
if (s) window.NSBridge.setQueue(_nativeSingle(s), 0, false);
|
||||||
}
|
}
|
||||||
@@ -849,7 +856,6 @@ function _initBarScrub(bar, fill, onMove, noTouch = false) {
|
|||||||
fill.style.width = (pos * 100) + '%';
|
fill.style.width = (pos * 100) + '%';
|
||||||
const dur = _dur();
|
const dur = _dur();
|
||||||
if (HAS_BRIDGE) {
|
if (HAS_BRIDGE) {
|
||||||
_setSkipping();
|
|
||||||
_nsBridge('seekTo', Math.round(pos * _lastDurationMs));
|
_nsBridge('seekTo', Math.round(pos * _lastDurationMs));
|
||||||
S._scrubbing = false;
|
S._scrubbing = false;
|
||||||
requestAnimationFrame(() => { fill.style.transition = ''; });
|
requestAnimationFrame(() => { fill.style.transition = ''; });
|
||||||
|
|||||||
Reference in new issue
Block a user