2023-07-07 13:58:15 +00:00
|
|
|
import { useAppDispatch, useAppSelector } from '$app/stores/store';
|
2024-02-08 06:22:44 +00:00
|
|
|
import { useEffect, useMemo } from 'react';
|
2023-07-07 13:58:15 +00:00
|
|
|
import { currentUserActions } from '$app_reducers/current-user/slice';
|
2023-12-18 09:44:47 +00:00
|
|
|
import { Theme as ThemeType, ThemeMode } from '$app/stores/reducers/current-user/slice';
|
2023-07-07 13:58:15 +00:00
|
|
|
import { createTheme } from '@mui/material/styles';
|
|
|
|
import { getDesignTokens } from '$app/utils/mui';
|
2023-07-31 03:39:44 +00:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2024-01-10 11:24:40 +00:00
|
|
|
import { UserService } from '$app/application/user/user.service';
|
2023-07-07 13:58:15 +00:00
|
|
|
|
|
|
|
export function useUserSetting() {
|
|
|
|
const dispatch = useAppDispatch();
|
2023-07-31 03:39:44 +00:00
|
|
|
const { i18n } = useTranslation();
|
2024-02-08 06:22:44 +00:00
|
|
|
const {
|
|
|
|
themeMode = ThemeMode.System,
|
|
|
|
isDark = false,
|
|
|
|
theme: themeType = ThemeType.Default,
|
|
|
|
} = useAppSelector((state) => {
|
|
|
|
return state.currentUser.userSetting || {};
|
|
|
|
});
|
2023-08-04 11:27:14 +00:00
|
|
|
|
2023-07-07 13:58:15 +00:00
|
|
|
useEffect(() => {
|
2024-02-08 06:22:44 +00:00
|
|
|
void (async () => {
|
|
|
|
const settings = await UserService.getAppearanceSetting();
|
2023-07-07 13:58:15 +00:00
|
|
|
|
2024-02-08 06:22:44 +00:00
|
|
|
if (!settings) return;
|
|
|
|
dispatch(currentUserActions.setUserSetting(settings));
|
|
|
|
await i18n.changeLanguage(settings.language);
|
|
|
|
})();
|
|
|
|
}, [dispatch, i18n]);
|
2023-07-07 13:58:15 +00:00
|
|
|
|
2024-01-10 11:24:40 +00:00
|
|
|
useEffect(() => {
|
|
|
|
const html = document.documentElement;
|
|
|
|
|
2024-02-08 06:22:44 +00:00
|
|
|
html?.setAttribute('data-dark-mode', String(isDark));
|
|
|
|
}, [isDark]);
|
2024-01-10 11:24:40 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-02-08 06:22:44 +00:00
|
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
|
|
|
|
const handleSystemThemeChange = () => {
|
|
|
|
if (themeMode !== ThemeMode.System) return;
|
|
|
|
dispatch(
|
|
|
|
currentUserActions.setUserSetting({
|
|
|
|
isDark: mediaQuery.matches,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
2024-01-10 11:24:40 +00:00
|
|
|
|
2024-02-08 06:22:44 +00:00
|
|
|
mediaQuery.addEventListener('change', handleSystemThemeChange);
|
|
|
|
|
|
|
|
return () => {
|
2024-01-10 11:24:40 +00:00
|
|
|
mediaQuery.removeEventListener('change', handleSystemThemeChange);
|
|
|
|
};
|
2024-02-08 06:22:44 +00:00
|
|
|
}, [dispatch, themeMode]);
|
2024-01-10 11:24:40 +00:00
|
|
|
|
2024-02-08 06:22:44 +00:00
|
|
|
const muiTheme = useMemo(() => createTheme(getDesignTokens(isDark)), [isDark]);
|
2023-07-07 13:58:15 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
muiTheme,
|
|
|
|
themeMode,
|
|
|
|
themeType,
|
|
|
|
};
|
|
|
|
}
|