mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-10 17:46:05 +03:00
feat: read local theme on page load (#1114)
Co-authored-by: zqran <uuxnet@gmail.com>
This commit is contained in:
parent
736fbff41a
commit
aa1de57d96
@ -1,5 +1,4 @@
|
||||
import {
|
||||
Theme,
|
||||
ThemeMode,
|
||||
ThemeProviderProps,
|
||||
ThemeProviderValue,
|
||||
@ -17,7 +16,15 @@ import {
|
||||
ThemeProvider as MuiThemeProvider,
|
||||
} from '@mui/material/styles';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
useSyncExternalStore,
|
||||
} from 'react';
|
||||
|
||||
import useCurrentPageMeta from '@/hooks/use-current-page-meta';
|
||||
|
||||
@ -35,16 +42,31 @@ export const ThemeProvider = ({
|
||||
defaultTheme = 'light',
|
||||
children,
|
||||
}: PropsWithChildren<ThemeProviderProps>) => {
|
||||
const [theme, setTheme] = useState<Theme>(defaultTheme);
|
||||
const [mode, setMode] = useState<ThemeMode>('auto');
|
||||
const localStorageThemeMode = useSyncExternalStore<ThemeMode>(
|
||||
useCallback(cb => {
|
||||
localStorageThemeHelper.callback.add(cb);
|
||||
return () => {
|
||||
localStorageThemeHelper.callback.delete(cb);
|
||||
};
|
||||
}, []),
|
||||
useCallback(() => localStorageThemeHelper.get() ?? 'light', []),
|
||||
useCallback(() => defaultTheme, [defaultTheme])
|
||||
);
|
||||
const [mode, setMode] = useState<ThemeMode>(defaultTheme);
|
||||
if (localStorageThemeMode !== mode) {
|
||||
setMode(localStorageThemeMode);
|
||||
}
|
||||
const { mode: editorMode = 'page' } = useCurrentPageMeta() || {};
|
||||
const themeStyle =
|
||||
theme === 'light' ? getLightTheme(editorMode) : getDarkTheme(editorMode);
|
||||
const changeMode = (themeMode: ThemeMode) => {
|
||||
themeMode !== mode && setMode(themeMode);
|
||||
// Remember the theme mode which user selected for next time
|
||||
localStorageThemeHelper.set(themeMode);
|
||||
};
|
||||
mode === 'light' ? getLightTheme(editorMode) : getDarkTheme(editorMode);
|
||||
const changeMode = useCallback(
|
||||
(themeMode: ThemeMode) => {
|
||||
themeMode !== mode && setMode(themeMode);
|
||||
// Remember the theme mode which user selected for next time
|
||||
localStorageThemeHelper.set(themeMode);
|
||||
},
|
||||
[mode]
|
||||
);
|
||||
|
||||
// ===================== A temporary solution, just use system theme and not remember the user selected ====================
|
||||
useEffect(() => {
|
||||
@ -57,9 +79,9 @@ export const ThemeProvider = ({
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setTheme(mode === 'auto' ? theme : mode);
|
||||
}, [mode, setTheme, theme]);
|
||||
// useEffect(() => {
|
||||
// setTheme(mode === 'auto' ? theme : mode);
|
||||
// }, [mode, setTheme, theme]);
|
||||
// ===================== ====================
|
||||
|
||||
// useEffect(() => {
|
||||
@ -93,7 +115,12 @@ export const ThemeProvider = ({
|
||||
return (
|
||||
// Use MuiThemeProvider is just because some Transitions in Mui components need it
|
||||
<MuiThemeProvider theme={muiTheme}>
|
||||
<ThemeContext.Provider value={{ mode, changeMode, theme: themeStyle }}>
|
||||
<ThemeContext.Provider
|
||||
value={useMemo(
|
||||
() => ({ mode, changeMode, theme: themeStyle }),
|
||||
[changeMode, mode, themeStyle]
|
||||
)}
|
||||
>
|
||||
<Global
|
||||
styles={css`
|
||||
:root {
|
||||
|
@ -2,11 +2,13 @@ import { ThemeMode } from '../types';
|
||||
|
||||
export class LocalStorageThemeHelper {
|
||||
name = 'Affine-theme-mode';
|
||||
callback = new Set<() => void>();
|
||||
get = (): ThemeMode | null => {
|
||||
return localStorage.getItem(this.name) as ThemeMode | null;
|
||||
};
|
||||
set = (mode: ThemeMode) => {
|
||||
localStorage.setItem(this.name, mode);
|
||||
this.callback.forEach(cb => cb());
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user