Merge pull request #502 from fanlusky/fix/settings-lazy-page-theme

fix(ui-html): 延迟加载的设置页预览补上主题
This commit is contained in:
Lu Fan(SonnyCalcr) authored and GitHub committed 2026-09-28 00:31:24 +08:00
commit 75ca041d20
3 files changed
+59

No files matched your search

@@ -33,15 +33,18 @@ const setupLoaders: Record<string, () => Promise<void>> = {
},
skin: async () => {
await (await import('./skin')).setupSkin();
(await import('./theme')).reapplyThemeConfig();
},
voice: async () => {
(await import('./voice')).setupVoiceInput();
},
'screenkb-settings': async () => {
(await import('./screenkb-settings')).setupScreenKeyboardSettings();
(await import('./theme')).reapplyThemeConfig();
},
'handwriting-settings': async () => {
(await import('./handwriting-settings')).setupHandwritingSettings();
(await import('./theme')).reapplyThemeConfig();
},
'tools-settings': async () => {
(await import('./tools-settings')).setupToolsSettings();
@@ -0,0 +1,47 @@
import { afterEach, beforeEach, expect, it, vi } from 'vitest';
import { applyThemeConfig, reapplyThemeConfig } from './theme';
class FakeImage {
src = '/assets/softkbd.png';
}
function fakeElement() {
return {
style: {} as Record<string, string>,
setAttribute: vi.fn(),
classList: { toggle: vi.fn() }
};
}
let previewLoaded = false;
let image: FakeImage;
beforeEach(() => {
previewLoaded = false;
image = new FakeImage();
vi.stubGlobal('HTMLImageElement', FakeImage);
vi.stubGlobal('window', { matchMedia: () => ({ matches: true, onchange: null }) });
vi.stubGlobal('document', {
documentElement: fakeElement(),
body: fakeElement(),
querySelector: (selector: string) =>
selector === '.screenkb-preview' && previewLoaded ? fakeElement() : null,
querySelectorAll: () => [],
getElementById: (id: string) => (id === 'screenKeyboardPreviewImage' && previewLoaded ? image : null)
});
});
afterEach(() => {
vi.unstubAllGlobals();
});
it('themes a preview page that loads after the snapshot was applied', async () => {
applyThemeConfig({ theme_mode: 'system', theme_screen_keyboard: 'follow' });
await vi.dynamicImportSettled();
expect(image.src).toBe('/assets/softkbd.png');
previewLoaded = true;
reapplyThemeConfig();
await vi.dynamicImportSettled();
expect(image.src).toBe('/assets/softkbd_light.png');
});
@@ -33,6 +33,7 @@ const SURFACE_THEME_LABELS: Record<SurfaceTheme, string> = {
};
let mediaQuery: MediaQueryList | null = null;
let lastThemeConfig: ThemeConfig | null = null;
function normalizeThemeMode(value: string | undefined): ThemeMode {
if (value === 'light' || value === 'dark' || value === 'system') {
@@ -99,6 +100,7 @@ function ensureSystemThemeListener(onChange: () => void): void {
}
export function applyThemeConfig(config: ThemeConfig | undefined): void {
lastThemeConfig = config ?? null;
const mode = normalizeThemeMode(config?.theme_mode);
const settingsTheme = normalizeSurfaceTheme(config?.theme_settings);
const candTheme = normalizeSurfaceTheme(config?.theme_cand);
@@ -159,6 +161,13 @@ export function applyThemeConfig(config: ThemeConfig | undefined): void {
updateSkinThemeCard(mode, settingsResolved, candResolved);
}
// Skin, screen keyboard and handwriting pages load after the first snapshot has been applied, so their previews only exist once the theme has already been resolved; they call this when their DOM is ready.
export function reapplyThemeConfig(): void {
if (lastThemeConfig) {
applyThemeConfig(lastThemeConfig);
}
}
export function applyFtbPreviewTheme(theme: ResolvedTheme): void {
document.querySelectorAll('.ftb-preview-host:not(#skinToolbarPreview):not([data-skin-toolbar])').forEach((element) => {
element.classList.toggle('theme-light', theme === 'light');