mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 12:30:12 +02:00
add setting to override theme primary shade (#1791)
This commit is contained in:
@@ -724,6 +724,10 @@
|
||||
"accentColor": "accent color",
|
||||
"useThemeAccentColor": "use theme accent color",
|
||||
"useThemeAccentColor_description": "use the primary color defined in the selected theme instead of the custom accent color",
|
||||
"useThemePrimaryShade": "use theme primary shade",
|
||||
"useThemePrimaryShade_description": "use the primary shade defined in the selected theme for primary color variants",
|
||||
"primaryShade": "primary shade",
|
||||
"primaryShade_description": "override the primary shade (0–9) used for buttons, links, and other primary-colored elements",
|
||||
"albumBackground_description": "adds a background image for album pages containing the album art",
|
||||
"albumBackground": "album background image",
|
||||
"albumBackgroundBlur_description": "adjusts the amount of blur applied to the album background image",
|
||||
|
||||
@@ -103,6 +103,7 @@ type SettingsProperties = {
|
||||
'settings.themeLight': string;
|
||||
'settings.tray': boolean;
|
||||
'settings.useThemeAccentColor': boolean;
|
||||
'settings.useThemePrimaryShade': boolean;
|
||||
'settings.windowBarStyle': Platform;
|
||||
'settings.zoomFactor': number;
|
||||
};
|
||||
@@ -192,6 +193,7 @@ const getSettingsProperties = (): SettingsProperties => {
|
||||
'settings.themeLight': settings.general.themeLight,
|
||||
'settings.tray': ignoreWeb(settings.window.tray),
|
||||
'settings.useThemeAccentColor': settings.general.useThemeAccentColor,
|
||||
'settings.useThemePrimaryShade': settings.general.useThemePrimaryShade,
|
||||
'settings.windowBarStyle': ignoreWeb(settings.window.windowBarStyle),
|
||||
'settings.zoomFactor': ignoreWeb(settings.general.zoomFactor),
|
||||
} as any;
|
||||
|
||||
@@ -13,6 +13,7 @@ import { THEME_DATA, useSetColorScheme } from '/@/renderer/themes/use-app-theme'
|
||||
import { ColorInput } from '/@/shared/components/color-input/color-input';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
import { Slider } from '/@/shared/components/slider/slider';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { getAppTheme } from '/@/shared/themes/app-theme';
|
||||
@@ -253,6 +254,51 @@ export const ThemeSettings = memo(() => {
|
||||
}),
|
||||
title: t('setting.accentColor', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
checked={settings.useThemePrimaryShade}
|
||||
onChange={(e) => {
|
||||
setSettings({
|
||||
general: {
|
||||
useThemePrimaryShade: e.currentTarget.checked,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
description: t('setting.useThemePrimaryShade', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: false,
|
||||
title: t('setting.useThemePrimaryShade', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Slider
|
||||
defaultValue={settings.primaryShade}
|
||||
label={(value) => value}
|
||||
max={9}
|
||||
min={0}
|
||||
onChangeEnd={(value) => {
|
||||
setSettings({
|
||||
general: {
|
||||
primaryShade: value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
step={1}
|
||||
w={120}
|
||||
/>
|
||||
),
|
||||
description: t('setting.primaryShade', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: settings.useThemePrimaryShade,
|
||||
title: t('setting.primaryShade', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@@ -462,6 +462,7 @@ export const GeneralSettingsSchema = z.object({
|
||||
playerbarOpenDrawer: z.boolean(),
|
||||
playerbarSlider: PlayerbarSliderSchema,
|
||||
playlistTarget: PlaylistTargetSchema,
|
||||
primaryShade: z.number().min(0).max(9),
|
||||
resume: z.boolean(),
|
||||
showLyricsInSidebar: z.boolean(),
|
||||
showRatings: z.boolean(),
|
||||
@@ -479,6 +480,7 @@ export const GeneralSettingsSchema = z.object({
|
||||
themeDark: z.nativeEnum(AppTheme),
|
||||
themeLight: z.nativeEnum(AppTheme),
|
||||
useThemeAccentColor: z.boolean(),
|
||||
useThemePrimaryShade: z.boolean(),
|
||||
volumeWheelStep: z.number(),
|
||||
volumeWidth: z.number(),
|
||||
zoomFactor: z.number(),
|
||||
@@ -1051,6 +1053,7 @@ const initialState: SettingsState = {
|
||||
type: PlayerbarSliderType.SLIDER,
|
||||
},
|
||||
playlistTarget: PlaylistTarget.TRACK,
|
||||
primaryShade: 6,
|
||||
resume: true,
|
||||
showLyricsInSidebar: true,
|
||||
showRatings: true,
|
||||
@@ -1072,6 +1075,7 @@ const initialState: SettingsState = {
|
||||
themeDark: AppTheme.DEFAULT_DARK,
|
||||
themeLight: AppTheme.DEFAULT_LIGHT,
|
||||
useThemeAccentColor: false,
|
||||
useThemePrimaryShade: true,
|
||||
volumeWheelStep: 5,
|
||||
volumeWidth: 70,
|
||||
zoomFactor: 100,
|
||||
@@ -2371,10 +2375,12 @@ export const useThemeSettings = () =>
|
||||
useSettingsStore(
|
||||
(state) => ({
|
||||
followSystemTheme: state.general.followSystemTheme,
|
||||
primaryShade: state.general.primaryShade,
|
||||
theme: state.general.theme,
|
||||
themeDark: state.general.themeDark,
|
||||
themeLight: state.general.themeLight,
|
||||
useThemeAccentColor: state.general.useThemeAccentColor,
|
||||
useThemePrimaryShade: state.general.useThemePrimaryShade,
|
||||
}),
|
||||
shallow,
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ export const useAppTheme = (overrideTheme?: AppTheme) => {
|
||||
const themeInlineStylesRef = useRef<HTMLStyleElement | null>(null);
|
||||
const getCurrentTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const [isDarkTheme, setIsDarkTheme] = useState(getCurrentTheme());
|
||||
const { followSystemTheme, theme, themeDark, themeLight, useThemeAccentColor } =
|
||||
const { followSystemTheme, primaryShade, theme, themeDark, themeLight, useThemeAccentColor, useThemePrimaryShade } =
|
||||
useThemeSettings();
|
||||
|
||||
const mqListener = (e: any) => {
|
||||
@@ -144,14 +144,23 @@ export const useAppTheme = (overrideTheme?: AppTheme) => {
|
||||
? themeProperties.colors?.primary || themeProperties.colors?.['state-info'] || accent
|
||||
: accent;
|
||||
|
||||
// Use theme's primary shade if useThemePrimaryShade is enabled, otherwise use slider value
|
||||
const effectivePrimaryShade = useThemePrimaryShade
|
||||
? themeProperties.mantineOverride?.primaryShade
|
||||
: { dark: primaryShade, light: primaryShade };
|
||||
|
||||
return {
|
||||
...themeProperties,
|
||||
colors: {
|
||||
...themeProperties.colors,
|
||||
primary: primaryColor,
|
||||
},
|
||||
mantineOverride: {
|
||||
...themeProperties.mantineOverride,
|
||||
...(effectivePrimaryShade != null && { primaryShade: effectivePrimaryShade }),
|
||||
},
|
||||
};
|
||||
}, [accent, selectedTheme, useThemeAccentColor]);
|
||||
}, [accent, primaryShade, selectedTheme, useThemeAccentColor, useThemePrimaryShade]);
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
@@ -241,7 +250,7 @@ export const useAppThemeColors = () => {
|
||||
const accent = useAccent();
|
||||
const getCurrentTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const [isDarkTheme] = useState(getCurrentTheme());
|
||||
const { followSystemTheme, theme, themeDark, themeLight, useThemeAccentColor } =
|
||||
const { followSystemTheme, primaryShade, theme, themeDark, themeLight, useThemeAccentColor, useThemePrimaryShade } =
|
||||
useThemeSettings();
|
||||
|
||||
const getSelectedTheme = () => {
|
||||
@@ -262,14 +271,23 @@ export const useAppThemeColors = () => {
|
||||
? themeProperties.colors?.primary || themeProperties.colors?.['state-info'] || accent
|
||||
: accent;
|
||||
|
||||
// Use theme's primary shade if useThemePrimaryShade is enabled, otherwise use slider value
|
||||
const effectivePrimaryShade = useThemePrimaryShade
|
||||
? themeProperties.mantineOverride?.primaryShade
|
||||
: { dark: primaryShade, light: primaryShade };
|
||||
|
||||
return {
|
||||
...themeProperties,
|
||||
colors: {
|
||||
...themeProperties.colors,
|
||||
primary: primaryColor,
|
||||
},
|
||||
mantineOverride: {
|
||||
...themeProperties.mantineOverride,
|
||||
...(effectivePrimaryShade != null && { primaryShade: effectivePrimaryShade }),
|
||||
},
|
||||
};
|
||||
}, [accent, selectedTheme, useThemeAccentColor]);
|
||||
}, [accent, primaryShade, selectedTheme, useThemeAccentColor, useThemePrimaryShade]);
|
||||
|
||||
const themeVars = useMemo(() => {
|
||||
return Object.entries(appTheme?.app ?? {})
|
||||
|
||||
Reference in New Issue
Block a user