fix(desktop): hot-reload development themes
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
DEFAULT_LIGHT_THEME_ID,
|
||||
DEFAULT_DARK_THEME_ID,
|
||||
} from '@/lib/theme/themes';
|
||||
import { withPrColors } from '@/lib/theme/themes/prColors';
|
||||
import { ThemeSystemContext, type ThemeContextValue } from './theme-system-context';
|
||||
import type { VSCodeThemePayload } from '@/lib/theme/vscode/adapter';
|
||||
import { runtimeFetch } from '@/lib/runtime-fetch';
|
||||
@@ -158,6 +159,7 @@ export function ThemeSystemProvider({ children, defaultThemeId }: ThemeSystemPro
|
||||
const [preferences, setPreferences] = useState<ThemePreferences>(() => buildInitialPreferences(defaultThemeId));
|
||||
const [systemPrefersDark, setSystemPrefersDark] = useState<boolean>(() => getInitialSystemPreference());
|
||||
const [customThemes, setCustomThemes] = useState<Theme[]>([]);
|
||||
const [developmentThemes, setDevelopmentThemes] = useState<Theme[]>([]);
|
||||
const [embeddedBootstrapTheme] = useState<Theme | null>(() => readEmbeddedCurrentTheme());
|
||||
const [embeddedSyncedTheme, setEmbeddedSyncedTheme] = useState<Theme | null>(null);
|
||||
const [customThemesLoading, setCustomThemesLoading] = useState(false);
|
||||
@@ -204,10 +206,32 @@ export function ThemeSystemProvider({ children, defaultThemeId }: ThemeSystemPro
|
||||
|
||||
// Custom themes first so they can override built-ins with the same id.
|
||||
customThemes.forEach(add);
|
||||
// Vite publishes valid built-in JSON edits through this development-only
|
||||
// runtime channel, avoiding a full page reload for theme work.
|
||||
developmentThemes.forEach(add);
|
||||
themes.forEach(add);
|
||||
|
||||
return merged;
|
||||
}, [customThemes, embeddedBootstrapTheme, embeddedSyncedTheme, isVSCode, vscodeTheme]);
|
||||
}, [customThemes, developmentThemes, embeddedBootstrapTheme, embeddedSyncedTheme, isVSCode, vscodeTheme]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleThemeHmr = (event: Event) => {
|
||||
const theme = (event as CustomEvent<unknown>).detail;
|
||||
if (!isValidTheme(theme)) return;
|
||||
|
||||
const nextTheme = withPrColors(theme);
|
||||
setDevelopmentThemes((previous) => {
|
||||
const index = previous.findIndex((candidate) => candidate.metadata.id === nextTheme.metadata.id);
|
||||
if (index < 0) return [...previous, nextTheme];
|
||||
const next = [...previous];
|
||||
next[index] = nextTheme;
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener('openchamber:theme-hmr', handleThemeHmr);
|
||||
return () => window.removeEventListener('openchamber:theme-hmr', handleThemeHmr);
|
||||
}, []);
|
||||
|
||||
const getThemeByIdFromAvailable = useCallback(
|
||||
(themeId: string): Theme | undefined => availableThemes.find((theme) => theme.metadata.id === themeId),
|
||||
|
||||
Reference in New Issue
Block a user