diff --git a/webui/static/script.js b/webui/static/script.js index 64432cd2..1f5f8db3 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -60,8 +60,10 @@ let artistsPageState = { cache: { searches: {}, // Cache search results by query discography: {}, // Cache discography by artist ID - colors: {} // Cache extracted colors by image URL - } + colors: {}, // Cache extracted colors by image URL + completionData: {} // Cache completion data by artist ID + }, + isInitialized: false // Track if the page has been initialized }; let artistsSearchTimeout = null; let artistsSearchController = null; @@ -362,7 +364,13 @@ async function loadPageData(pageId) { break; case 'artists': stopDownloadPolling(); - initializeArtistsPage(); + // Only fully initialize if not already initialized + if (!artistsPageState.isInitialized) { + initializeArtistsPage(); + } else { + // Just restore state if already initialized + restoreArtistsPageState(); + } break; case 'settings': initializeSettings(); @@ -9065,10 +9073,10 @@ async function resetYouTubePlaylist(urlHash) { // ============================================================================ /** - * Initialize the artists page when navigated to + * Initialize the artists page when navigated to (only runs once) */ function initializeArtistsPage() { - console.log('🎵 Initializing Artists Page'); + console.log('🎵 Initializing Artists Page (first time)'); // Get DOM elements const searchInput = document.getElementById('artists-search-input'); @@ -9077,7 +9085,7 @@ function initializeArtistsPage() { const backButton = document.getElementById('artists-back-button'); const detailBackButton = document.getElementById('artist-detail-back-button'); - // Set up event listeners + // Set up event listeners (only need to do this once) if (searchInput) { searchInput.addEventListener('input', handleArtistsSearchInput); searchInput.addEventListener('keypress', handleArtistsSearchKeypress); @@ -9096,12 +9104,90 @@ function initializeArtistsPage() { detailBackButton.addEventListener('click', () => showArtistsResultsState()); } - // Initialize tabs + // Initialize tabs (only need to do this once) initializeArtistTabs(); - // Reset to search state - showArtistsSearchState(); - console.log('✅ Artists Page initialized successfully'); + // Mark as initialized + artistsPageState.isInitialized = true; + + // Restore previous state instead of always resetting to search + restoreArtistsPageState(); + console.log('✅ Artists Page initialized successfully (ready for navigation)'); +} + +/** + * Restore the artists page to its previous state + */ +function restoreArtistsPageState() { + console.log(`🔄 Restoring artists page state: ${artistsPageState.currentView}`); + + switch (artistsPageState.currentView) { + case 'results': + // Restore search results state + if (artistsPageState.searchQuery && artistsPageState.searchResults.length > 0) { + console.log(`📦 Restoring search results for: "${artistsPageState.searchQuery}"`); + + // Restore search input values + const searchInput = document.getElementById('artists-search-input'); + const headerSearchInput = document.getElementById('artists-header-search-input'); + + if (searchInput) searchInput.value = artistsPageState.searchQuery; + if (headerSearchInput) headerSearchInput.value = artistsPageState.searchQuery; + + // Display the cached results + displayArtistsResults(artistsPageState.searchQuery, artistsPageState.searchResults); + } else { + // No valid results state, fall back to search + showArtistsSearchState(); + } + break; + + case 'detail': + // Restore artist detail state + if (artistsPageState.selectedArtist && artistsPageState.artistDiscography) { + console.log(`🎤 Restoring artist detail for: ${artistsPageState.selectedArtist.name}`); + + // First restore search results if they exist + if (artistsPageState.searchQuery && artistsPageState.searchResults.length > 0) { + const searchInput = document.getElementById('artists-search-input'); + const headerSearchInput = document.getElementById('artists-header-search-input'); + + if (searchInput) searchInput.value = artistsPageState.searchQuery; + if (headerSearchInput) headerSearchInput.value = artistsPageState.searchQuery; + } + + // Show artist detail state + showArtistDetailState(); + + // Update artist info in header + updateArtistDetailHeader(artistsPageState.selectedArtist); + + // Display cached discography + if (artistsPageState.artistDiscography.albums || artistsPageState.artistDiscography.singles) { + displayArtistDiscography(artistsPageState.artistDiscography); + // Restore cached completion data instead of re-scanning + restoreCachedCompletionData(artistsPageState.selectedArtist.id); + } + } else { + // No valid detail state, fall back to search or results + if (artistsPageState.searchQuery && artistsPageState.searchResults.length > 0) { + displayArtistsResults(artistsPageState.searchQuery, artistsPageState.searchResults); + } else { + showArtistsSearchState(); + } + } + break; + + default: + case 'search': + // Show search state (but preserve any existing search query) + if (artistsPageState.searchQuery) { + const searchInput = document.getElementById('artists-search-input'); + if (searchInput) searchInput.value = artistsPageState.searchQuery; + } + showArtistsSearchState(); + break; + } } /** @@ -9482,6 +9568,35 @@ function displayArtistDiscography(discography) { } } +/** + * Restore cached completion data without re-scanning the database + */ +function restoreCachedCompletionData(artistId) { + console.log(`📦 Restoring cached completion data for artist: ${artistId}`); + + const cachedData = artistsPageState.cache.completionData[artistId]; + if (!cachedData) { + console.log('⚠️ No cached completion data found, skipping restoration'); + return; + } + + // Restore album completion overlays + if (cachedData.albums) { + cachedData.albums.forEach(albumCompletion => { + updateAlbumCompletionOverlay(albumCompletion, 'albums'); + }); + console.log(`✅ Restored ${cachedData.albums.length} album completion overlays`); + } + + // Restore singles completion overlays + if (cachedData.singles) { + cachedData.singles.forEach(singleCompletion => { + updateAlbumCompletionOverlay(singleCompletion, 'singles'); + }); + console.log(`✅ Restored ${cachedData.singles.length} single completion overlays`); + } +} + /** * Check completion status for entire discography with streaming updates */ @@ -9547,16 +9662,27 @@ function handleStreamingCompletionUpdate(data) { switch (data.type) { case 'start': console.log(`🎤 Starting completion check for ${data.artist_name} (${data.total_items} items)`); - // Could show a progress indicator here + // Initialize cache for this artist if not exists + const artistId = artistsPageState.selectedArtist?.id; + if (artistId && !artistsPageState.cache.completionData[artistId]) { + artistsPageState.cache.completionData[artistId] = { + albums: [], + singles: [] + }; + } break; case 'album_completion': updateAlbumCompletionOverlay(data, 'albums'); + // Cache the completion data + cacheCompletionData(data, 'albums'); console.log(`📀 Updated album: ${data.name} (${data.status})`); break; case 'single_completion': updateAlbumCompletionOverlay(data, 'singles'); + // Cache the completion data + cacheCompletionData(data, 'singles'); console.log(`🎵 Updated single: ${data.name} (${data.status})`); break; @@ -9574,6 +9700,29 @@ function handleStreamingCompletionUpdate(data) { } } +/** + * Cache completion data for future restoration + */ +function cacheCompletionData(completionData, type) { + const artistId = artistsPageState.selectedArtist?.id; + if (!artistId) return; + + // Ensure cache structure exists + if (!artistsPageState.cache.completionData[artistId]) { + artistsPageState.cache.completionData[artistId] = { + albums: [], + singles: [] + }; + } + + // Add to appropriate cache array + if (type === 'albums') { + artistsPageState.cache.completionData[artistId].albums.push(completionData); + } else if (type === 'singles') { + artistsPageState.cache.completionData[artistId].singles.push(completionData); + } +} + /** * Update completion overlay for a specific album/single */ @@ -9745,6 +9894,21 @@ function showArtistsSearchState() { function showArtistsResultsState() { console.log('🔄 Showing results state'); + // Clear artist-specific data when navigating back to results + // This ensures that selecting the same artist again will trigger a fresh scan + if (artistsPageState.selectedArtist) { + const artistId = artistsPageState.selectedArtist.id; + console.log(`🗑️ Clearing cached data for artist: ${artistsPageState.selectedArtist.name}`); + + // Clear artist-specific cache data + delete artistsPageState.cache.completionData[artistId]; + delete artistsPageState.cache.discography[artistId]; + + // Clear artist state + artistsPageState.selectedArtist = null; + artistsPageState.artistDiscography = { albums: [], singles: [] }; + } + const searchState = document.getElementById('artists-search-state'); const resultsState = document.getElementById('artists-results-state'); const detailState = document.getElementById('artist-detail-state');