mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 10:03:33 +00:00
add theme stylesheet loader
This commit is contained in:
parent
bb7d561d0f
commit
ea122f5a4f
1 changed files with 58 additions and 1 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
import { useMantineColorScheme } from '@mantine/core';
|
import { useMantineColorScheme } from '@mantine/core';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { useSettingsStore } from '/@/renderer/store/settings.store';
|
import { useSettingsStore } from '/@/renderer/store/settings.store';
|
||||||
import { createMantineTheme } from '/@/renderer/themes/mantine-theme';
|
import { createMantineTheme } from '/@/renderer/themes/mantine-theme';
|
||||||
|
|
@ -17,6 +17,7 @@ export const useAppTheme = (overrideTheme?: AppTheme) => {
|
||||||
const nativeImageAspect = useSettingsStore((store) => store.general.nativeAspectRatio);
|
const nativeImageAspect = useSettingsStore((store) => store.general.nativeAspectRatio);
|
||||||
const { builtIn, custom, system, type } = useSettingsStore((state) => state.font);
|
const { builtIn, custom, system, type } = useSettingsStore((state) => state.font);
|
||||||
const textStyleRef = useRef<HTMLStyleElement | null>(null);
|
const textStyleRef = useRef<HTMLStyleElement | null>(null);
|
||||||
|
const loadedStylesheetsRef = useRef<Set<string>>(new Set());
|
||||||
const getCurrentTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches;
|
const getCurrentTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
const [isDarkTheme, setIsDarkTheme] = useState(getCurrentTheme());
|
const [isDarkTheme, setIsDarkTheme] = useState(getCurrentTheme());
|
||||||
const { followSystemTheme, theme, themeDark, themeLight } = useSettingsStore(
|
const { followSystemTheme, theme, themeDark, themeLight } = useSettingsStore(
|
||||||
|
|
@ -27,6 +28,56 @@ export const useAppTheme = (overrideTheme?: AppTheme) => {
|
||||||
setIsDarkTheme(e.matches);
|
setIsDarkTheme(e.matches);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadStylesheet = (href: string): Promise<void> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (loadedStylesheetsRef.current.has(href)) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = href;
|
||||||
|
link.onload = () => {
|
||||||
|
loadedStylesheetsRef.current.add(href);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
link.onerror = () => {
|
||||||
|
console.warn(`Failed to load stylesheet: ${href}`);
|
||||||
|
reject(new Error(`Failed to load stylesheet: ${href}`));
|
||||||
|
};
|
||||||
|
|
||||||
|
document.head.appendChild(link);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const unloadStylesheet = (href: string) => {
|
||||||
|
const existingLink = document.querySelector(`link[href="${href}"]`);
|
||||||
|
if (existingLink) {
|
||||||
|
existingLink.remove();
|
||||||
|
loadedStylesheetsRef.current.delete(href);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadThemeStylesheets = useCallback(async (stylesheets: string[] = []) => {
|
||||||
|
if (loadedStylesheetsRef.current.size > 0) {
|
||||||
|
loadedStylesheetsRef.current.forEach((href) => unloadStylesheet(href));
|
||||||
|
loadedStylesheetsRef.current.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stylesheets.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadPromises = stylesheets.map((href) =>
|
||||||
|
loadStylesheet(href).catch((error) => {
|
||||||
|
console.warn(`Error loading stylesheet ${href}:`, error);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(loadPromises);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const getSelectedTheme = () => {
|
const getSelectedTheme = () => {
|
||||||
if (overrideTheme) {
|
if (overrideTheme) {
|
||||||
return overrideTheme;
|
return overrideTheme;
|
||||||
|
|
@ -113,6 +164,12 @@ export const useAppTheme = (overrideTheme?: AppTheme) => {
|
||||||
root.style.setProperty('--theme-image-fit', nativeImageAspect ? 'contain' : 'cover');
|
root.style.setProperty('--theme-image-fit', nativeImageAspect ? 'contain' : 'cover');
|
||||||
}, [nativeImageAspect]);
|
}, [nativeImageAspect]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (appTheme?.stylesheets) {
|
||||||
|
loadThemeStylesheets(appTheme.stylesheets);
|
||||||
|
}
|
||||||
|
}, [selectedTheme, appTheme?.stylesheets, loadThemeStylesheets]);
|
||||||
|
|
||||||
const themeVars = useMemo(() => {
|
const themeVars = useMemo(() => {
|
||||||
return Object.entries(appTheme?.app ?? {})
|
return Object.entries(appTheme?.app ?? {})
|
||||||
.map(([key, value]) => {
|
.map(([key, value]) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue