feat(web): refresh the current view after deleting a song or playlist

Deletes left the removed item visible because the list loaders are cached (getPlaylists
~3 min): deletePlaylist navigated to a still-cached list, and deleteSong only reloaded
playlists. Add refreshCurrentView() — drops the API cache and re-runs the active nav
entry's loader (playlists, playlist/album/artist detail, starred, home, …). deleteSong
calls it after the delete+rescan delay; deletePlaylist invalidates getPlaylists before
navigating. Bump SW cache to ns-v46.

Also record the post-1.2 work in the 1.2 changelog (importer Enter, search single-song
+ radio, NowPlaying order, official-audio artist-metadata match, JP-katakana album
artist fix, year back-fill, delete refresh).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-07-26 23:27:29 +02:00
1 parent 966b318d9e
commit d98978a6c7
5 files changed
+36 -8

No files matched your search

+22
View File
@@ -8,6 +8,7 @@ import { loadHomeData, loadAlbumRow, loadArtists, loadAlbums, loadGenreDetail }
import { loadArtistDetail, loadArtistAllSongs, loadAlbumDetail, loadItunesAlbumDetail, loadPartialAlbumDetail } from './detail.js';
import { loadPlaylists, loadPlaylistDetail, loadStarred, loadRandom } from './playlists.js';
import { loadNewReleases, loadRecommendations } from './discover.js';
import { invalidateApiCache } from '../api.js';
// ─── NAVIGATION HISTORY ───
export function _navSave() {
@@ -36,6 +37,27 @@ export function closeHeaderSearch() {
clearTimeout(S._headerSearchTimer);
}
// Force-refresh the active view after a mutating action (delete a song / playlist, etc.): drop the
// cached API responses so the reload is fresh, then re-run the current nav entry's loader.
export function refreshCurrentView() {
invalidateApiCache();
const entry = S._navStack[S._navCursor];
if (!entry) return;
const { page, data } = entry;
switch (page) {
case 'home': loadHomeData(true); break;
case 'albums': loadAlbums(); break;
case 'artists': loadArtists(); break;
case 'starred': loadStarred(); break;
case 'random': loadRandom(); break;
case 'playlists': loadPlaylists(); break;
case 'playlist-detail': if (data) loadPlaylistDetail(data); break;
case 'album-detail': if (data) loadAlbumDetail(data); break;
case 'artist-detail': if (data) loadArtistDetail(data); break;
case 'genre-detail': if (data) loadGenreDetail(data); break;
}
}
export function navigate(page, data=null) {
closeHeaderSearch();
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));