fix: eliminate NP overlay stale-song on autoplay and cover-load delay

Three improvements:
- openNowPlaying(): reads NSBridge.getState() (always-fresh @Volatile snapshot)
  via ID search to reconcile S.qIdx before render; fixes NP showing old song
  when deferred evaluateJavascript callbacks haven't fired yet after backgrounding
- onPositionUpdate(): periodic check (~every 2s) detects track mismatch via
  snapshot ID; catches missed/delayed onTrackChanged when NP is open
- updatePlayerUI(): pre-warms next song's 1024px cover so auto-advance NP
  swap is instant from browser cache instead of a 1-second load delay
- styles: add backface-visibility:hidden + isolation:isolate to .np-overlay
  to reduce GPU composite flicker on Android WebView on manual skip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-05-28 01:30:55 +02:00
1 parent 050aff6dbe
commit 0788c801fa
3 files changed
+45 -1

No files matched your search

+18 -1
View File
@@ -2,12 +2,29 @@ import { S } from './state.js';
import { esc } from './utils.js';
import { coverUrl } from './api.js';
// Circular imports — safe (only used inside function bodies)
import { playCurrent, _syncNpDirect, dlSongLocal, npToggleStar, _syncOverlayState, isPlaying, seekToMs } from './player.js';
import { playCurrent, _syncNpDirect, dlSongLocal, npToggleStar, _syncOverlayState, isPlaying, seekToMs, updatePlayerUI } from './player.js';
import { navigate } from './views.js';
import { openPlModal, showSongInfo } from './ui.js';
// ─── NOW PLAYING OVERLAY ───
export function openNowPlaying() {
// Reconcile S.qIdx with native state before rendering.
// NSBridge.getState() reads a @Volatile snapshot updated synchronously before every callJs(),
// so it is always fresh even when evaluateJavascript callbacks are still queued (backgrounded app).
if (typeof window.NSBridge !== 'undefined') {
try {
const live = JSON.parse(window.NSBridge.getState() || '{}');
const liveId = String(live.currentId || '');
if (liveId && liveId !== String(S.queue[S.qIdx]?.id || '')) {
const found = S.queue.findIndex(s => String(s.id) === liveId);
if (found >= 0) {
S.qIdx = found;
const s = S.queue[S.qIdx];
if (s) { updatePlayerUI(s, true); onNpSongChange(s.id); }
}
}
} catch {}
}
S.npOpen = true;
const overlay = document.getElementById('np-overlay');
overlay.classList.add('open');