AppFlowy/frontend/appflowy_tauri/src/appflowy_app/AppMain.hooks.ts

69 lines
2.3 KiB
TypeScript
Raw Normal View History

2023-07-07 13:58:15 +00:00
import { useAppDispatch, useAppSelector } from '$app/stores/store';
import { useCallback, useEffect, useMemo } from 'react';
2023-07-07 13:58:15 +00:00
import { currentUserActions } from '$app_reducers/current-user/slice';
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';
import { useTranslation } from 'react-i18next';
import { ThemeModePB } from '@/services/backend';
import { UserService } from '$app/application/user/user.service';
2023-07-07 13:58:15 +00:00
export function useUserSetting() {
const dispatch = useAppDispatch();
const { i18n } = useTranslation();
2023-07-07 13:58:15 +00:00
const handleSystemThemeChange = useCallback(() => {
const mode = window.matchMedia('(prefers-color-scheme: dark)').matches ? ThemeMode.Dark : ThemeMode.Light;
dispatch(currentUserActions.setUserSetting({ themeMode: mode }));
}, [dispatch]);
2023-07-07 13:58:15 +00:00
const loadUserSetting = useCallback(async () => {
const settings = await UserService.getAppearanceSetting();
if (!settings) return;
dispatch(currentUserActions.setUserSetting(settings));
if (settings.themeMode === ThemeModePB.System) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
handleSystemThemeChange();
mediaQuery.addEventListener('change', handleSystemThemeChange);
}
await i18n.changeLanguage(settings.language);
}, [dispatch, handleSystemThemeChange, i18n]);
2023-07-07 13:58:15 +00:00
useEffect(() => {
void loadUserSetting();
}, [loadUserSetting]);
2023-07-07 13:58:15 +00:00
const { themeMode = ThemeMode.Light, theme: themeType = ThemeType.Default } = useAppSelector((state) => {
return state.currentUser.userSetting || {};
});
useEffect(() => {
const html = document.documentElement;
html?.setAttribute('data-dark-mode', String(themeMode === ThemeMode.Dark));
html?.setAttribute('data-theme', themeType);
}, [themeType, themeMode]);
useEffect(() => {
return () => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.removeEventListener('change', handleSystemThemeChange);
};
}, [dispatch, handleSystemThemeChange]);
2023-07-07 13:58:15 +00:00
const muiTheme = useMemo(() => createTheme(getDesignTokens(themeMode)), [themeMode]);
return {
muiTheme,
themeMode,
themeType,
};
}