diff --git a/webui/static/helper.js b/webui/static/helper.js index e3d96156..6ec49872 100644 --- a/webui/static/helper.js +++ b/webui/static/helper.js @@ -3415,6 +3415,7 @@ function closeHelperSearch() { const WHATS_NEW = { '2.6.3': [ { unreleased: true }, + { title: 'Library: Enhanced / Standard view toggle now sticks per browser', desc: 'the artist detail page used to revert to Standard view every time you clicked into a new artist — flipping to Enhanced was a per-click thing with no memory. now the choice is persisted in localStorage and reapplied automatically on every artist open. survives page reloads too. non-admins (who can\'t toggle Enhanced anyway) are unaffected; admins who never touched the Enhanced view stay on Standard since the saved value defaults to it.' }, { title: 'Fix popup: manual matches survive Playlist Pipeline runs', desc: 'manually mapping a mirrored-playlist track via the Fix popup (search or MBID) saved correctly and the download went through, but the next Playlist Pipeline run kept reverting the match — the track flipped back to "Provider Changed" and you had to map it again. three things were ganging up on it: the manual-fix save always stamped `provider: \'spotify\'` even when the match came from MusicBrainz / iTunes / Deezer, so prepare-discovery saw a provider mismatch on the next run; the discovery worker also re-queued any matched_data that lacked `track_number` / `album.id` / `release_date` for re-discovery, and Fix-popup saves never carry those fields by design (search results don\'t include track_number, MBID lookups don\'t include album.id) — so manual fixes always looked "incomplete" and got overwritten; and the prepare-discovery provider check didn\'t honour the `manual_match` flag at all. all three patched — manual matches now stamp the actual source, the worker short-circuits on `manual_match` before the incomplete-data branch, and prepare-discovery treats manual fixes as cached regardless of provider drift.' }, { title: 'Fix popup: artist + track fields no longer surface unrelated covers', desc: 'separate artist / track inputs in the Fix popup used to dump both into a bare MusicBrainz keyword query — and MB\'s scorer heavily favours title matches, so searching "Coffee Break" + "Zeds Dead" surfaced random "Coffee Break" tracks by other artists ahead of the canonical Zeds Dead one. fields-mode now uses a field-scoped Lucene query that actually anchors the artist, with the old bare query kept as a fallback for diacritic mismatches like "Bjork" vs "Björk" where strict phrase match misses. results also stable-prefer entries with known track length so the canonical 3:04 sibling sits above the 0:00 duplicate.' }, { title: 'Groundwork: unified playlist source layer', desc: 'first slice of a refactor that\'ll let ListenBrainz, Last.fm radio, and SoulSync Discovery playlists live as Sync-page tabs alongside Spotify / Tidal / Qobuz / YouTube — so they can be mirrored + scheduled like the rest. this commit adds the shared adapter layer all those sources will plug into; no UI changes yet. nothing to do on your end.' }, diff --git a/webui/static/library.js b/webui/static/library.js index 4e5467bf..dac0467a 100644 --- a/webui/static/library.js +++ b/webui/static/library.js @@ -879,6 +879,15 @@ function navigateToArtistDetail(artistId, artistName, sourceOverride = null, opt const bulkBar = document.getElementById('enhanced-bulk-bar'); if (bulkBar) bulkBar.classList.remove('visible'); + // Restore persisted view preference. Non-admins can't see / toggle the + // Enhanced control so only honour the saved choice for admins; default + // is still Standard. Wrapped in try/catch because localStorage can be + // disabled in private-browsing modes. + let _preferEnhanced = false; + try { + _preferEnhanced = localStorage.getItem('soulsync-library-view-mode') === 'enhanced'; + } catch (_) { /* localStorage unavailable */ } + // Navigate to artist detail page navigateToPage('artist-detail', { artistId, @@ -895,6 +904,13 @@ function navigateToArtistDetail(artistId, artistName, sourceOverride = null, opt // Load artist data loadArtistDetailData(artistId, artistName); + + // Apply persisted Enhanced view after the standard data load is kicked off. + // toggleEnhancedView() triggers its own loadEnhancedViewData() in parallel; + // the brief Standard render is hidden as soon as the toggle flips. + if (_preferEnhanced && isEnhancedAdmin()) { + toggleEnhancedView(true); + } } function _updateArtistDetailBackButtonLabel() { @@ -2905,6 +2921,12 @@ function toggleEnhancedView(enabled) { const bulkBar = document.getElementById('enhanced-bulk-bar'); if (bulkBar) bulkBar.classList.remove('visible'); } + + // Persist the choice so the next artist click (and the next page reload) + // honours it instead of always reverting to Standard. + try { + localStorage.setItem('soulsync-library-view-mode', enabled ? 'enhanced' : 'standard'); + } catch (_) { /* localStorage unavailable */ } } async function loadEnhancedViewData(artistId) {