fix: reconcile native state on app foreground; refresh playlist after delete
- Call reconcileNativeState() on visibilitychange→visible so the player UI updates immediately when the user opens the app after a background auto-advance, before deferred evaluateJavascript callbacks have had a chance to fire - After deleteSong() succeeds, refresh the active playlist view (grid or detail) with a 2s delay to let Navidrome's background scan complete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
a2714dddaa
commit
07b8114cae
3 files changed
+32
-2
No files matched your search
+2
-1
@@ -9,7 +9,7 @@ import {
|
||||
initProgressScrub, updateProgress, updatePreviewProgress, stopPreview,
|
||||
toggleRadioMode, starCurrent, downloadCurrent, renderQueue, playPreview,
|
||||
toggleStar, dlSongLocal, _applyRadioBtn, _applyShuffleRepeat, _restoreLastPlayed, setPlayIcon,
|
||||
npToggleStar, updateMediaSession, updateNpColorMode,
|
||||
npToggleStar, updateMediaSession, updateNpColorMode, reconcileNativeState,
|
||||
} from './player.js';
|
||||
import {
|
||||
navigate, _navGoBack, _navLoad, onHeaderSearch, closeHeaderSearch,
|
||||
@@ -174,6 +174,7 @@ window.addEventListener('load', () => {
|
||||
let _wasPlayingBeforeHide = false;
|
||||
|
||||
function _onForeground() {
|
||||
reconcileNativeState();
|
||||
const s = S.queue[S.qIdx];
|
||||
if(!s) return;
|
||||
updateMediaSession(s);
|
||||
|
||||
@@ -1236,6 +1236,28 @@ if (HAS_BRIDGE) {
|
||||
}
|
||||
}
|
||||
|
||||
// Immediately sync JS track/play state with the native bridge snapshot.
|
||||
// Called on app foreground so the UI is correct before any deferred evaluateJavascript callbacks fire.
|
||||
export function reconcileNativeState() {
|
||||
if (!HAS_BRIDGE) return;
|
||||
try {
|
||||
const snap = JSON.parse(window.NSBridge.getState() || '{}');
|
||||
const snapId = String(snap.currentId || '');
|
||||
if (snapId && snapId !== String(S.queue[S.qIdx]?.id || '')) {
|
||||
const found = S.queue.findIndex(s => String(s.id) === snapId);
|
||||
if (found >= 0) {
|
||||
S.qIdx = found;
|
||||
const s = S.queue[S.qIdx];
|
||||
if (s) { updatePlayerUI(s, true); syncNowPlaying(); onNpSongChange(s.id); renderQueue(); }
|
||||
}
|
||||
}
|
||||
if (typeof snap.isPlaying === 'boolean' && snap.isPlaying !== _nativePlaying) {
|
||||
_nativePlaying = snap.isPlaying;
|
||||
setPlayIcon(snap.isPlaying);
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
export function _restoreLastPlayed() {
|
||||
try {
|
||||
const saved = JSON.parse(localStorage.getItem('ns_last_played') || 'null');
|
||||
|
||||
@@ -4,7 +4,7 @@ import { api, coverUrl, ndAuth, fetchRomajiIndex, romajiConvert, romajiLookup, i
|
||||
import { THEMES, applyTheme, getCurrentThemeId } from './themes.js';
|
||||
// Circular imports — safe (only used inside function bodies)
|
||||
import { playQueue, dlSongLocal, toggleStar, togglePlay, renderQueue, syncNpStar, updateStarBtn, npToggleStar, playCurrent, _syncNpDirect, setPlayIcon, nativeInsertAt, refreshDisplayMode, updateNpColorMode } from './player.js';
|
||||
import { navigate, loadPlaylists } from './views.js';
|
||||
import { navigate, loadPlaylists, loadPlaylistDetail } from './views.js';
|
||||
|
||||
// ─── SIDEBAR ───
|
||||
export function openSidebar() {
|
||||
@@ -536,6 +536,13 @@ export async function deleteSong() {
|
||||
if (!r.ok) throw new Error(d.error || `HTTP ${r.status}`);
|
||||
toast(`🗑 "${s.title}" gelöscht`);
|
||||
closeInfoModal();
|
||||
// Refresh playlist views after Navidrome's background scan has a chance to finish
|
||||
setTimeout(() => {
|
||||
if (document.getElementById('page-playlists')?.classList.contains('active'))
|
||||
loadPlaylists();
|
||||
else if (document.getElementById('page-playlist-detail')?.classList.contains('active') && S._currentPlaylist)
|
||||
loadPlaylistDetail(S._currentPlaylist);
|
||||
}, 2000);
|
||||
} catch (e) {
|
||||
status.textContent = '❌ Fehler: ' + e.message;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user