diff --git a/web/src/lib/serverEvents.svelte.ts b/web/src/lib/serverEvents.svelte.ts index d3ab5bcc..98699045 100644 --- a/web/src/lib/serverEvents.svelte.ts +++ b/web/src/lib/serverEvents.svelte.ts @@ -12,7 +12,20 @@ import { user } from '$lib/auth/store.svelte'; // deliberately do NOT yank a playing queue here — that would interrupt a // mid-song listen to restart the new mix at track 0. +// Monotonic rebuild counter (#980). Bumped on every playlist.system_rebuilt. +// An open system-playlist DETAIL page can't be invalidated in place (its id +// rotates on rebuild — a refetch would 404), so instead it watches this +// counter and offers a "this mix was refreshed → Refresh" affordance that +// re-resolves the variant to the new playlist. +let _systemRebuildCount = $state(0); +export const systemRebuilt = { + get count(): number { + return _systemRebuildCount; + } +}; + function onSystemRebuilt(): void { + _systemRebuildCount++; queryClient.invalidateQueries({ queryKey: qk.home() }); // Prefix match invalidates every kind ('user' | 'system' | 'all'). queryClient.invalidateQueries({ queryKey: ['playlists'] }); diff --git a/web/src/routes/playlists/[id]/+page.svelte b/web/src/routes/playlists/[id]/+page.svelte index f35fcd06..5581aecb 100644 --- a/web/src/routes/playlists/[id]/+page.svelte +++ b/web/src/routes/playlists/[id]/+page.svelte @@ -1,6 +1,7 @@ @@ -187,6 +224,24 @@ playlistQuery.refetch()} /> {:else if playlistQuery?.data} {@const pl = playlistQuery.data} + {#if staleSystemView} +
+ This mix was refreshed since you opened it. + +
+ {/if} {#if !editing}