Restore smart back-button label on artist detail page
PR #644 removed the back-button label logic as collateral when removing the full originStack. The label is independent of the stack — restore it without restoring the old click-handler navigation (browser history handles that now). - _artistDetailLabelStack: module-level stack of {type:'page',pageId} or {type:'artist',name} entries, pushed on forward navigation, popped on back - _artistDetailGoingBack flag: set by the back button click handler so navigateToArtistDetail knows to pop instead of push when called by the React route on browser-history navigation - Backfill currentArtistName from the API response so URL-driven entries (which pass '' for name) have real names on state before the next similar- artist navigation pushes them onto the stack - No-history fallback navigates to the recorded origin page
This commit is contained in:
parent
4bfa43bece
commit
e7ba5408aa
2 changed files with 70 additions and 2 deletions
|
|
@ -3417,6 +3417,7 @@ const WHATS_NEW = {
|
|||
{ date: 'May 18, 2026 — 2.5.6 release' },
|
||||
{ title: 'MusicBrainz as Primary Metadata Source', desc: 'MusicBrainz is now a full primary metadata source on equal footing with Deezer, iTunes, Spotify, and Discogs. switch to it in Settings → Metadata Source — always available, no account or API key needed, rate-limited to 1 req/sec. covers all primary source flows: search, album/track/artist lookup, watchlist scans, discover hero, similar artist backfill, artist map.', page: 'settings' },
|
||||
{ title: 'Fix: MusicBrainz artist detail showing MBID as name', desc: 'clicking a MusicBrainz artist from search results was showing the raw MBID as the artist name on the detail page. URL-driven routing (PR #644) no longer passes the display name to the backend, so the source detail endpoint now looks it up directly from MusicBrainz by MBID.' },
|
||||
{ title: 'Fix: artist detail back button always showing "← Back"', desc: 'PR #644 removed the back-button label logic along with the origin stack. restored: a label stack (separate from browser history, which handles actual navigation) tracks where you came from across the full similar-artist chain — "← Back to Search", "← Back to Artist A", "← Back to Artist B", etc. API response backfills the current artist name so the stack has real names when clicking similar artists.' },
|
||||
],
|
||||
'2.5.5': [
|
||||
{ date: 'May 17, 2026 — 2.5.5 release' },
|
||||
|
|
|
|||
|
|
@ -680,6 +680,26 @@ async function toggleLibraryCardWatchlist(btn, artist) {
|
|||
// ===============================================
|
||||
|
||||
// Artist detail page state
|
||||
const _ARTIST_DETAIL_BACK_LABELS = {
|
||||
library: 'Back to Library',
|
||||
search: 'Back to Search',
|
||||
discover: 'Back to Discover',
|
||||
watchlist: 'Back to Watchlist',
|
||||
wishlist: 'Back to Wishlist',
|
||||
stats: 'Back to Stats',
|
||||
'playlist-explorer': 'Back to Explorer',
|
||||
automations: 'Back to Automations',
|
||||
dashboard: 'Back to Dashboard',
|
||||
sync: 'Back to Sync',
|
||||
'active-downloads': 'Back to Downloads',
|
||||
};
|
||||
|
||||
// Stack of origins for the back-button label. Each entry: {type:'page', pageId}
|
||||
// or {type:'artist', name}. Pushed on forward navigation, popped on back.
|
||||
// Separate from browser history — only used for the label display.
|
||||
let _artistDetailLabelStack = [];
|
||||
let _artistDetailGoingBack = false;
|
||||
|
||||
let artistDetailPageState = {
|
||||
isInitialized: false,
|
||||
currentArtistId: null,
|
||||
|
|
@ -797,6 +817,23 @@ function navigateToArtistDetail(artistId, artistName, sourceOverride = null, opt
|
|||
}
|
||||
console.log(`🎵 Navigating to artist detail: ${artistName} (ID: ${artistId}${sourceOverride ? `, source: ${sourceOverride}` : ''})`);
|
||||
|
||||
// Maintain the label stack. Back navigations pop; forward navigations push.
|
||||
if (_artistDetailGoingBack) {
|
||||
_artistDetailLabelStack.pop();
|
||||
_artistDetailGoingBack = false;
|
||||
} else {
|
||||
if (currentPage !== 'artist-detail') {
|
||||
_artistDetailLabelStack = []; // fresh chain from a non-artist page
|
||||
}
|
||||
if (currentPage === 'artist-detail' && artistDetailPageState.currentArtistName) {
|
||||
_artistDetailLabelStack.push({ type: 'artist', name: artistDetailPageState.currentArtistName });
|
||||
} else {
|
||||
const pageId = (typeof currentPage === 'string' && currentPage && currentPage !== 'artist-detail')
|
||||
? currentPage : 'library';
|
||||
_artistDetailLabelStack.push({ type: 'page', pageId });
|
||||
}
|
||||
}
|
||||
|
||||
// Abort any in-progress completion stream
|
||||
if (artistDetailPageState.completionController) {
|
||||
artistDetailPageState.completionController.abort();
|
||||
|
|
@ -851,10 +888,28 @@ function navigateToArtistDetail(artistId, artistName, sourceOverride = null, opt
|
|||
initializeArtistDetailPage();
|
||||
}
|
||||
|
||||
_updateArtistDetailBackButtonLabel();
|
||||
|
||||
// Load artist data
|
||||
loadArtistDetailData(artistId, artistName);
|
||||
}
|
||||
|
||||
function _updateArtistDetailBackButtonLabel() {
|
||||
const backBtnLabel = document.querySelector('#artist-detail-back-btn span');
|
||||
if (!backBtnLabel) return;
|
||||
const top = _artistDetailLabelStack[_artistDetailLabelStack.length - 1];
|
||||
if (!top) {
|
||||
backBtnLabel.textContent = '← Back';
|
||||
return;
|
||||
}
|
||||
if (top.type === 'artist') {
|
||||
backBtnLabel.textContent = `← Back to ${top.name}`;
|
||||
} else {
|
||||
const friendly = _ARTIST_DETAIL_BACK_LABELS[top.pageId] || _ARTIST_DETAIL_BACK_LABELS.library;
|
||||
backBtnLabel.textContent = `← ${friendly}`;
|
||||
}
|
||||
}
|
||||
|
||||
function initializeArtistDetailPage() {
|
||||
console.log("🔧 Initializing Artist Detail page...");
|
||||
|
||||
|
|
@ -870,12 +925,15 @@ function initializeArtistDetailPage() {
|
|||
}
|
||||
|
||||
if (window.history.length > 1) {
|
||||
_artistDetailGoingBack = true;
|
||||
window.history.back();
|
||||
return;
|
||||
}
|
||||
|
||||
// No history — default to library
|
||||
navigateToPage('library');
|
||||
// No history — fall back to recorded origin page or library
|
||||
const top = _artistDetailLabelStack.pop();
|
||||
_updateArtistDetailBackButtonLabel();
|
||||
navigateToPage(top?.type === 'page' ? (top.pageId || 'library') : 'library');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -981,6 +1039,15 @@ async function loadArtistDetailData(artistId, artistName) {
|
|||
artistDetailPageState.currentArtistId = data.artist.id;
|
||||
}
|
||||
|
||||
// Backfill name from API response — URL-driven navigation passes '' for the
|
||||
// name so the label stack has real names when the user clicks a similar artist.
|
||||
if (data.artist?.name && !artistDetailPageState.currentArtistName) {
|
||||
artistDetailPageState.currentArtistName = data.artist.name;
|
||||
if (typeof _updateSidebarLibraryBreadcrumb === 'function') {
|
||||
_updateSidebarLibraryBreadcrumb();
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the resolved metadata source for album-track lookups.
|
||||
artistDetailPageState.currentArtistSource = data.discography?.source || data.artist?.source || null;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue