diff --git a/src/main.js b/src/main.js index 8dd66f8..8c0070c 100644 --- a/src/main.js +++ b/src/main.js @@ -13,7 +13,7 @@ import { npToggleStar, updateMediaSession, updateNpColorMode, reconcileNativeState, initKeyboardShortcuts, } from './player/player.js'; import { - navigate, _navGoBack, _navLoad, onHeaderSearch, closeHeaderSearch, + navigate, _navGoBack, _navOnPopState, _navLoad, onHeaderSearch, closeHeaderSearch, onGlobalSearch, s_goArtist, s_goAlbum, playerBarGoArtist, playerBarGoAlbum, searchSimilarArtist, searchAndPreview, loadItunesAlbum, closeEventsModal, loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist, @@ -299,7 +299,7 @@ window.addEventListener('load', () => { } }); -window.addEventListener('popstate', () => _navGoBack()); +window.addEventListener('popstate', (e) => _navOnPopState(e.state)); document.addEventListener('keydown', e => { if(e.key !== 'Backspace') return; const t = document.activeElement?.tagName; diff --git a/src/views/navigation.js b/src/views/navigation.js index a73ae3e..db1da4b 100644 --- a/src/views/navigation.js +++ b/src/views/navigation.js @@ -86,16 +86,36 @@ export function navigate(page, data=null) { } } +// In-app back button / Backspace: dismiss NowPlaying overlays first, otherwise let the browser step +// back (→ popstate → _navOnPopState). Routing through the History API keeps the browser's back/ +// forward stack in sync, so browser/mouse Forward works too. export function _navGoBack() { if(document.getElementById('np-sheet')?.classList.contains('open')) { closeNpMenu(); return; } if(S.npOpen) { closeNowPlaying(); return; } - if(S._navCursor > 0) { - S._navCursor--; - const entry = S._navStack[S._navCursor]; - _navSave(); - S._navJumping = true; - navigate(entry.page, entry.data); - S._navJumping = false; + if(S._navCursor > 0) history.back(); +} + +// Browser/mouse Back OR Forward — both fire popstate. Apply whichever entry the browser moved to +// via nsIdx from the history state; this is what makes Forward work. Never pushState here — that +// would wipe the browser's forward stack. navigate() pushes only on genuine new navigation. +export function _navOnPopState(state) { + // Mirror the soft-back: a Back press with an overlay open just closes it and stays on the page. + if(document.getElementById('np-sheet')?.classList.contains('open')) { + closeNpMenu(); + try { history.pushState({ nsIdx: S._navCursor }, '', ''); } catch {} + return; } - try { history.pushState({ nsIdx: S._navCursor }, '', ''); } catch {} + if(S.npOpen) { + closeNowPlaying(); + try { history.pushState({ nsIdx: S._navCursor }, '', ''); } catch {} + return; + } + const idx = (state && typeof state.nsIdx === 'number') ? state.nsIdx : 0; + if(idx < 0 || idx >= S._navStack.length) return; + S._navCursor = idx; + const entry = S._navStack[idx]; + _navSave(); + S._navJumping = true; + navigate(entry.page, entry.data); + S._navJumping = false; }