From 38b89f97307825ecfa810744936a6f4481277821 Mon Sep 17 00:00:00 2001 From: Frank Stellmacher <171614930+Psychotoxical@users.noreply.github.com> Date: Thu, 7 May 2026 02:46:25 +0200 Subject: [PATCH] fix(theme): migrate persisted state from removed theme ids (#491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #490 dropped five community themes (amber-night, ice-blue, monochrome, phosphor-green, rose-dark). Existing users who had any of those selected land on a non-existent data-theme attribute after the update — the browser silently falls back to :root defaults and the picker shows the old id as inactive in the list. Add a Zustand persist `migrate` hook (version 1) that remaps the removed ids to the closest surviving palette per family — gold for amber, carbon grey for ice / monochrome, deep forest for phosphor green, sakura night for rose. Applies to `theme`, `themeDay` and `themeNight` (theme scheduler), so a scheduled night theme that was set to a removed id is remapped too. New installs are unaffected (migrate runs against persisted state only). --- src/store/themeStore.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/store/themeStore.ts b/src/store/themeStore.ts index 8fd4598d..4a1fa963 100644 --- a/src/store/themeStore.ts +++ b/src/store/themeStore.ts @@ -44,6 +44,23 @@ export function getScheduledTheme(state: Pick = { + 'amber-night': 'obsidian-gold', // warm gold/amber dark family + 'ice-blue': 'carbon-grey', // cool neutral dark (no surviving cyan) + 'monochrome': 'carbon-grey', // neutral grey dark + 'phosphor-green': 'deep-forest', // green dark family + 'rose-dark': 'sakura-night', // pink/rose dark family +}; + +function remapTheme(value: unknown): unknown { + return typeof value === 'string' && value in REMOVED_THEME_REMAP + ? REMOVED_THEME_REMAP[value] + : value; +} + export const useThemeStore = create()( persist( (set) => ({ @@ -74,6 +91,17 @@ export const useThemeStore = create()( }), { name: 'psysonic_theme', + version: 1, + migrate: (persistedState, _version) => { + if (!persistedState || typeof persistedState !== 'object') return persistedState; + const s = persistedState as Record; + return { + ...s, + theme: remapTheme(s.theme), + themeDay: remapTheme(s.themeDay), + themeNight: remapTheme(s.themeNight), + }; + }, } ) );