2022-11-26 13:51:56 +01:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) Contributors to the Suwayomi project
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
2024-05-20 16:28:36 +02:00
|
|
|
import {
|
|
|
|
|
createTheme as createMuiTheme,
|
|
|
|
|
darken,
|
|
|
|
|
Direction,
|
|
|
|
|
lighten,
|
2024-09-04 22:26:40 +02:00
|
|
|
Palette,
|
2024-08-31 22:42:06 +02:00
|
|
|
responsiveFontSizes,
|
2024-05-20 16:28:36 +02:00
|
|
|
Theme,
|
|
|
|
|
} from '@mui/material/styles';
|
2024-09-04 23:46:04 +02:00
|
|
|
import { ThemeMode } from '@/components/context/ThemeModeContext.tsx';
|
|
|
|
|
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
|
2024-09-07 01:07:02 +02:00
|
|
|
import { AppTheme, loadThemeFonts } from '@/lib/ui/AppThemes.ts';
|
|
|
|
|
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
2023-06-04 21:08:39 +02:00
|
|
|
|
2024-09-06 23:50:38 +02:00
|
|
|
const SCROLLBAR_SIZE = 14;
|
2024-08-30 15:52:02 +02:00
|
|
|
|
2024-09-04 22:26:40 +02:00
|
|
|
export const createTheme = (
|
2024-09-04 23:46:04 +02:00
|
|
|
themeMode: ThemeMode,
|
2024-09-05 12:20:21 +02:00
|
|
|
appTheme: AppTheme,
|
2024-09-04 22:26:40 +02:00
|
|
|
pureBlackMode: boolean = false,
|
2024-09-05 02:35:08 +02:00
|
|
|
direction: Direction = 'ltr',
|
2024-09-04 22:26:40 +02:00
|
|
|
) => {
|
2024-09-04 23:46:04 +02:00
|
|
|
const systemMode = MediaQuery.getSystemThemeMode();
|
2024-09-05 12:20:21 +02:00
|
|
|
|
2024-09-06 23:29:16 +02:00
|
|
|
const appThemeType = (appTheme.muiTheme.palette as any)?.type ?? appTheme.muiTheme.palette?.mode;
|
|
|
|
|
const isStaticThemeMode = !!appThemeType;
|
|
|
|
|
const appThemeMode = appThemeType === 'dark' ? ThemeMode.DARK : ThemeMode.LIGHT;
|
2024-09-05 12:20:21 +02:00
|
|
|
const staticThemeMode = isStaticThemeMode ? appThemeMode : undefined;
|
|
|
|
|
|
|
|
|
|
const mode = staticThemeMode ?? (themeMode === ThemeMode.SYSTEM ? systemMode : themeMode);
|
2024-09-04 23:46:04 +02:00
|
|
|
const isDarkMode = mode === ThemeMode.DARK;
|
2024-09-05 00:08:23 +02:00
|
|
|
const setPureBlackMode = isDarkMode && pureBlackMode;
|
2024-09-04 22:26:40 +02:00
|
|
|
|
|
|
|
|
const baseTheme = createMuiTheme({
|
2024-04-25 14:07:59 +02:00
|
|
|
direction,
|
2024-09-05 12:20:21 +02:00
|
|
|
...appTheme.muiTheme,
|
2022-11-26 13:51:56 +01:00
|
|
|
palette: {
|
2024-09-04 23:46:04 +02:00
|
|
|
mode,
|
2024-09-05 12:20:21 +02:00
|
|
|
...(appTheme.muiTheme.palette ?? {}),
|
2022-11-26 13:51:56 +01:00
|
|
|
},
|
2024-09-04 22:26:40 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const backgroundTrueBlack: Palette['background'] = {
|
|
|
|
|
paper: '#111',
|
|
|
|
|
default: '#000',
|
|
|
|
|
};
|
|
|
|
|
const backgroundDark: Palette['background'] = {
|
|
|
|
|
paper: darken(baseTheme.palette.primary.main, 0.75),
|
|
|
|
|
default: darken(baseTheme.palette.primary.main, 0.85),
|
|
|
|
|
};
|
|
|
|
|
const backgroundLight: Palette['background'] = {
|
|
|
|
|
paper: lighten(baseTheme.palette.primary.dark, 0.75),
|
|
|
|
|
default: lighten(baseTheme.palette.primary.dark, 0.85),
|
|
|
|
|
};
|
|
|
|
|
const backgroundThemeMode = isDarkMode ? backgroundDark : backgroundLight;
|
2024-09-05 12:20:21 +02:00
|
|
|
const automaticBackground = setPureBlackMode ? backgroundTrueBlack : backgroundThemeMode;
|
|
|
|
|
const appThemeBackground = appTheme.muiTheme.palette?.background;
|
|
|
|
|
|
|
|
|
|
const requiresAutomaticBackground = setPureBlackMode || !appThemeBackground;
|
|
|
|
|
const background = requiresAutomaticBackground ? automaticBackground : appThemeBackground;
|
2022-11-26 13:51:56 +01:00
|
|
|
|
2024-09-04 22:26:40 +02:00
|
|
|
const colorTheme = createMuiTheme(baseTheme, {
|
|
|
|
|
palette: {
|
|
|
|
|
background,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const suwayomiTheme = createMuiTheme(colorTheme, {
|
|
|
|
|
components: {
|
|
|
|
|
MuiUseMediaQuery: {
|
|
|
|
|
defaultProps: {
|
|
|
|
|
noSsr: true,
|
2023-02-06 10:06:33 +01:00
|
|
|
},
|
2022-11-26 13:51:56 +01:00
|
|
|
},
|
2024-09-04 22:26:40 +02:00
|
|
|
MuiCssBaseline: {
|
|
|
|
|
styleOverrides: `
|
2024-05-20 16:28:36 +02:00
|
|
|
*::-webkit-scrollbar {
|
2024-09-06 23:32:42 +02:00
|
|
|
width: ${SCROLLBAR_SIZE}px;
|
|
|
|
|
height: ${SCROLLBAR_SIZE}px;
|
2024-05-20 16:28:36 +02:00
|
|
|
}
|
|
|
|
|
*::-webkit-scrollbar-thumb {
|
|
|
|
|
border: 4px solid rgba(0, 0, 0, 0);
|
|
|
|
|
background-clip: padding-box;
|
|
|
|
|
border-radius: 9999px;
|
2024-09-04 22:26:40 +02:00
|
|
|
background-color: ${colorTheme.palette.primary[isDarkMode ? 'dark' : 'light']};
|
2024-05-20 16:28:36 +02:00
|
|
|
}
|
|
|
|
|
*::-webkit-scrollbar-thumb:hover {
|
|
|
|
|
border-width: 2px;
|
|
|
|
|
}
|
|
|
|
|
`,
|
2022-11-26 13:51:56 +01:00
|
|
|
},
|
|
|
|
|
},
|
2024-09-04 22:26:40 +02:00
|
|
|
});
|
2022-11-26 13:51:56 +01:00
|
|
|
|
2024-09-05 02:35:08 +02:00
|
|
|
return responsiveFontSizes(suwayomiTheme);
|
|
|
|
|
};
|
2024-04-07 15:33:08 +02:00
|
|
|
|
2024-09-05 02:35:08 +02:00
|
|
|
let theme: Theme;
|
|
|
|
|
export const getCurrentTheme = () => theme;
|
|
|
|
|
export const createAndSetTheme = (...args: Parameters<typeof createTheme>) => {
|
|
|
|
|
theme = createTheme(...args);
|
2024-09-07 01:07:02 +02:00
|
|
|
loadThemeFonts(theme).catch(defaultPromiseErrorHandler('theme::createAndSetTheme'));
|
|
|
|
|
|
2024-08-31 22:42:06 +02:00
|
|
|
return theme;
|
2022-11-26 13:51:56 +01:00
|
|
|
};
|
2024-04-26 12:53:31 +02:00
|
|
|
|
|
|
|
|
export const getOptionForDirection = <T>(ltrOption: T, rtlOption: T): T =>
|
|
|
|
|
(theme?.direction ?? 'ltr') === 'ltr' ? ltrOption : rtlOption;
|