From 9b52c1d94fbf4f8d77a7f8a694dff89e607440de Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Wed, 22 Apr 2026 19:35:17 -0700 Subject: [PATCH] =?UTF-8?q?Smart=20back=20button=20on=20artist-detail=20?= =?UTF-8?q?=E2=80=94=20labels=20and=20routes=20by=20origin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "← Back to Library" button on /artist-detail was hardcoded to navigate back to the Library page regardless of where the user came from. Now it captures the originating page and labels/routes accordingly. navigateToArtistDetail captures currentPage at call time (before the swap to artist-detail) and stashes it on artistDetailPageState.originPage. Falls back to library when the origin can't be determined or when chaining detail-to-detail (e.g. clicking a Similar Artist on the detail page). Back button label now adapts: - From Library card click → "← Back to Library" - From Search result → "← Back to Search" - From Discover hero / Your Artists → "← Back to Discover" - From Watchlist artist detail → "← Back to Watchlist" - From Wishlist / Stats / Explorer / Automations / Dashboard etc. → corresponding labels - Unknown origin → "← Back to Library" Click handler navigates to the captured origin instead of always going to library. State is cleared on click so a fresh artist-detail view starts clean next time. --- webui/static/library.js | 45 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/webui/static/library.js b/webui/static/library.js index b5b74d65..f70c1bac 100644 --- a/webui/static/library.js +++ b/webui/static/library.js @@ -640,6 +640,7 @@ let artistDetailPageState = { currentArtistId: null, currentArtistName: null, currentArtistSource: null, + originPage: null, // page id captured by navigateToArtistDetail for the back button enhancedView: false, enhancedData: null, expandedAlbums: new Set(), @@ -655,9 +656,36 @@ let discographyFilterState = { ownership: 'all' // 'all', 'owned', 'missing' }; +// Friendly labels for the dynamic "← Back to X" button on the artist-detail page. +// Page id (the value of currentPage) -> button label. +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', +}; + function navigateToArtistDetail(artistId, artistName, sourceOverride = null) { console.log(`🎵 Navigating to artist detail: ${artistName} (ID: ${artistId}${sourceOverride ? `, source: ${sourceOverride}` : ''})`); + // Capture where the user is coming from BEFORE navigateToPage flips + // currentPage. The back button on the artist-detail page reads this so it + // can say "Back to Search" / "Back to Discover" / etc. instead of the + // hardcoded "Back to Library". Falls back to library when origin is + // unknown or when chaining from one artist-detail page to another. + let origin = (typeof currentPage === 'string' && currentPage) ? currentPage : null; + if (!origin || origin === 'artist-detail') { + origin = artistDetailPageState.originPage || 'library'; + } + artistDetailPageState.originPage = origin; + // Abort any in-progress completion stream if (artistDetailPageState.completionController) { artistDetailPageState.completionController.abort(); @@ -703,6 +731,13 @@ function navigateToArtistDetail(artistId, artistName, sourceOverride = null) { // Navigate to artist detail page navigateToPage('artist-detail'); + // Update back-button label for the captured origin. + const backBtnLabel = document.querySelector('#artist-detail-back-btn span'); + if (backBtnLabel) { + const friendly = _ARTIST_DETAIL_BACK_LABELS[origin] || _ARTIST_DETAIL_BACK_LABELS.library; + backBtnLabel.textContent = `← ${friendly}`; + } + // Initialize if needed and load data if (!artistDetailPageState.isInitialized) { initializeArtistDetailPage(); @@ -715,11 +750,14 @@ function navigateToArtistDetail(artistId, artistName, sourceOverride = null) { function initializeArtistDetailPage() { console.log("🔧 Initializing Artist Detail page..."); - // Initialize back button + // Initialize back button — navigates back to whichever page initiated the + // current artist-detail view (Search, Discover, Watchlist, Library, etc.), + // captured by navigateToArtistDetail before the page swap. const backBtn = document.getElementById("artist-detail-back-btn"); if (backBtn) { backBtn.addEventListener("click", () => { - console.log("🔙 Returning to Library page"); + const dest = artistDetailPageState.originPage || 'library'; + console.log(`🔙 Returning to ${dest}`); // Abort any in-progress completion stream if (artistDetailPageState.completionController) { artistDetailPageState.completionController.abort(); @@ -728,7 +766,8 @@ function initializeArtistDetailPage() { // Clear artist detail state so we go back to the list view artistDetailPageState.currentArtistId = null; artistDetailPageState.currentArtistName = null; - navigateToPage('library'); + artistDetailPageState.originPage = null; + navigateToPage(dest); }); }