Support theme fonts

This commit is contained in:
schroda
2024-09-07 01:07:02 +02:00
parent 527ab8c149
commit e0b58652f4
6 changed files with 92 additions and 4 deletions

View File

@@ -8,7 +8,9 @@
import { ThemeOptions } from '@mui/material/styles';
import { t as translate } from 'i18next';
import WebFont from 'webfontloader';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { ControlledPromise } from '@/lib/ControlledPromise.ts';
type Theme = { isCustom: boolean; getName: () => string; muiTheme: ThemeOptions };
@@ -168,3 +170,58 @@ export const getTheme = (id: AppThemes, customThemes: Record<string, AppTheme> =
export const isThemeNameUnique = (id: string, customThemes: Record<string, AppTheme>): boolean =>
Object.keys({ ...themes, ...customThemes }).every((themeId) => themeId.toLowerCase() !== id.toLowerCase());
const getFontsFromTheme = (obj: Record<string, any>, fonts: string[] = []): string[] => {
const tmpFonts = [...fonts];
const propertyNames = Object.keys(obj);
for (const propertyName of propertyNames) {
const propertyValue = obj[propertyName];
const propertyType = typeof obj[propertyName];
const isValidFontProperty = propertyName === 'fontFamily' && propertyType === 'string';
if (isValidFontProperty) {
tmpFonts.push(propertyValue as string);
// eslint-disable-next-line no-continue
continue;
}
const isObject = propertyType === 'object';
if (isObject) {
tmpFonts.push(...getFontsFromTheme(propertyValue as Record<string, any>, tmpFonts));
}
}
return [...new Set(tmpFonts)];
};
const loadedFonts: string[] = [];
export const loadThemeFonts = async (theme: ThemeOptions): Promise<void> => {
const themeFonts = getFontsFromTheme(theme);
const missingThemeFonts = themeFonts.filter((font) => !loadedFonts.includes(font));
if (!missingThemeFonts.length) {
return;
}
const loadFontsPromise = new ControlledPromise();
try {
WebFont.load({
google: {
families: missingThemeFonts,
},
active: () => {
loadedFonts.push(...missingThemeFonts);
loadFontsPromise.resolve();
},
inactive: () => {
loadFontsPromise.reject();
},
});
} catch (e) {
defaultPromiseErrorHandler('AppThemes::loadFonts')(e);
loadFontsPromise.reject(e);
}
await loadFontsPromise.promise;
};