refactor: move useTheme hook into separate store, also closes #528 (#529)

This commit is contained in:
Huang Xin
2025-03-08 16:12:36 +08:00
committed by GitHub
parent dfc6cc9c8a
commit 0b72ab156d
20 changed files with 189 additions and 176 deletions
@@ -3,24 +3,24 @@ import { MdOutlineLightMode, MdOutlineDarkMode } from 'react-icons/md';
import { MdRadioButtonUnchecked, MdRadioButtonChecked } from 'react-icons/md';
import { TbSunMoon } from 'react-icons/tb';
import { useTheme } from '@/hooks/useTheme';
import { themes } from '@/styles/themes';
import { getStyles } from '@/utils/style';
import { useThemeStore } from '@/store/themeStore';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
const ColorPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const _ = useTranslation();
const { themeMode, themeColor, themeCode, isDarkMode, updateThemeMode, updateThemeColor } =
useTheme();
const { themeMode, themeColor, themeCode, isDarkMode, setThemeMode, setThemeColor } =
useThemeStore();
const { getViews, getViewSettings } = useReaderStore();
const viewSettings = getViewSettings(bookKey)!;
const iconSize24 = useResponsiveSize(24);
useEffect(() => {
getViews().forEach((view) => {
view.renderer.setStyles?.(getStyles(viewSettings!, themeCode));
view.renderer.setStyles?.(getStyles(viewSettings!));
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [themeCode]);
@@ -29,11 +29,11 @@ const ColorPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='my-4 w-full space-y-6'>
<div className='flex items-center justify-between'>
<h2 className='font-medium'>{_('Theme Mode')}</h2>
<div className='flex gap-2'>
<div className='flex gap-4'>
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('Auto Mode')}>
<button
className={`btn btn-ghost btn-circle ${themeMode === 'auto' ? 'btn-active bg-base-300' : ''}`}
onClick={() => updateThemeMode('auto')}
className={`btn btn-ghost btn-circle btn-sm ${themeMode === 'auto' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setThemeMode('auto')}
>
<TbSunMoon />
</button>
@@ -41,8 +41,8 @@ const ColorPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('Light Mode')}>
<button
className={`btn btn-ghost btn-circle ${themeMode === 'light' ? 'btn-active bg-base-300' : ''}`}
onClick={() => updateThemeMode('light')}
className={`btn btn-ghost btn-circle btn-sm ${themeMode === 'light' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setThemeMode('light')}
>
<MdOutlineLightMode />
</button>
@@ -50,8 +50,8 @@ const ColorPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('Dark Mode')}>
<button
className={`btn btn-ghost btn-circle ${themeMode === 'dark' ? 'btn-active bg-base-300' : ''}`}
onClick={() => updateThemeMode('dark')}
className={`btn btn-ghost btn-circle btn-sm ${themeMode === 'dark' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setThemeMode('dark')}
>
<MdOutlineDarkMode />
</button>
@@ -78,7 +78,7 @@ const ColorPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
name='theme'
value={name}
checked={themeColor === name}
onChange={() => updateThemeColor(name)}
onChange={() => setThemeColor(name)}
className='hidden'
/>
{themeColor === name ? (
@@ -16,7 +16,6 @@ import {
import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useTheme } from '@/hooks/useTheme';
import { useEnv } from '@/context/EnvContext';
import { getStyles } from '@/utils/style';
import { getOSPlatform } from '@/utils/misc';
@@ -66,7 +65,6 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const { getView, getViewSettings, setViewSettings } = useReaderStore();
const view = getView(bookKey);
const viewSettings = getViewSettings(bookKey)!;
const { themeCode } = useTheme();
const fontFamilyOptions = [
{
@@ -126,7 +124,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.defaultFont = defaultFont;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultFont]);
@@ -137,7 +135,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.defaultFontSize = defaultFontSize;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultFontSize]);
@@ -148,7 +146,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.minimumFontSize = minFontSize;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [minFontSize]);
@@ -159,7 +157,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.fontWeight = fontWeight;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fontWeight]);
@@ -170,7 +168,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.serifFont = serifFont;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [serifFont]);
@@ -181,7 +179,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.sansSerifFont = sansSerifFont;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sansSerifFont]);
@@ -192,7 +190,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.monospaceFont = monospaceFont;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [monospaceFont]);
@@ -203,7 +201,7 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.overrideFont = overrideFont;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [overrideFont]);
@@ -7,7 +7,6 @@ import { useSettingsStore } from '@/store/settingsStore';
import { useReaderStore } from '@/store/readerStore';
import { useBookDataStore } from '@/store/bookDataStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useTheme } from '@/hooks/useTheme';
import { getStyles } from '@/utils/style';
import { getMaxInlineSize } from '@/utils/config';
import { getBookDirFromWritingMode, getBookLangCode } from '@/utils/book';
@@ -21,7 +20,6 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const view = getView(bookKey);
const bookData = getBookData(bookKey)!;
const viewSettings = getViewSettings(bookKey)!;
const { themeCode } = useTheme();
const [paragraphMargin, setParagraphMargin] = useState(viewSettings.paragraphMargin!);
const [lineHeight, setLineHeight] = useState(viewSettings.lineHeight!);
@@ -45,7 +43,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.paragraphMargin = paragraphMargin;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [paragraphMargin]);
@@ -56,7 +54,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.lineHeight = lineHeight;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [lineHeight]);
@@ -67,7 +65,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.wordSpacing = wordSpacing;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wordSpacing]);
@@ -78,7 +76,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.letterSpacing = letterSpacing;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [letterSpacing]);
@@ -89,7 +87,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.textIndent = textIndent;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [textIndent]);
@@ -100,7 +98,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.fullJustification = fullJustification;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fullJustification]);
@@ -111,7 +109,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.hyphenation = hyphenation;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hyphenation]);
@@ -180,7 +178,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
viewSettings.writingMode = writingMode;
setViewSettings(bookKey, viewSettings);
if (view) {
view.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view.renderer.setStyles?.(getStyles(viewSettings));
view.book.dir = getBookDirFromWritingMode(writingMode);
}
if (
@@ -199,7 +197,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
settings.globalViewSettings.overrideLayout = overrideLayout;
setSettings(settings);
}
view?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [overrideLayout]);
@@ -213,10 +211,10 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='w-full'>
<div className='flex items-center justify-between'>
<h2 className='font-medium'>{_('Writing Mode')}</h2>
<div className='flex gap-2'>
<div className='flex gap-4'>
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('Default')}>
<button
className={`btn btn-ghost btn-circle ${writingMode === 'auto' ? 'btn-active bg-base-300' : ''}`}
className={`btn btn-ghost btn-circle btn-sm ${writingMode === 'auto' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setWritingMode('auto')}
>
<MdOutlineAutoMode />
@@ -225,7 +223,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('Horizontal Direction')}>
<button
className={`btn btn-ghost btn-circle ${writingMode === 'horizontal-tb' ? 'btn-active bg-base-300' : ''}`}
className={`btn btn-ghost btn-circle btn-sm ${writingMode === 'horizontal-tb' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setWritingMode('horizontal-tb')}
>
<MdOutlineTextRotationNone />
@@ -234,7 +232,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('Vertical Direction')}>
<button
className={`btn btn-ghost btn-circle ${writingMode === 'vertical-rl' ? 'btn-active bg-base-300' : ''}`}
className={`btn btn-ghost btn-circle btn-sm ${writingMode === 'vertical-rl' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setWritingMode('vertical-rl')}
>
<MdTextRotateVertical />
@@ -243,7 +241,7 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
<div className='lg:tooltip lg:tooltip-bottom' data-tip={_('RTL Direction')}>
<button
className={`btn btn-ghost btn-circle ${writingMode === 'horizontal-rl' ? 'btn-active bg-base-300' : ''}`}
className={`btn btn-ghost btn-circle btn-sm ${writingMode === 'horizontal-rl' ? 'btn-active bg-base-300' : ''}`}
onClick={() => setWritingMode('horizontal-rl')}
>
<TbTextDirectionRtl />
@@ -4,7 +4,6 @@ import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { getStyles } from '@/utils/style';
import { useTheme } from '@/hooks/useTheme';
import cssbeautify from 'cssbeautify';
import cssValidate from '@/utils/css';
@@ -13,7 +12,6 @@ const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore();
const { getView, getViewSettings, setViewSettings } = useReaderStore();
const viewSettings = getViewSettings(bookKey)!;
const { themeCode } = useTheme();
const [animated, setAnimated] = useState(viewSettings.animated!);
const [isDisableClick, setIsDisableClick] = useState(viewSettings.disableClick!);
@@ -60,7 +58,7 @@ const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
setSettings(settings);
}
getView(bookKey)?.renderer.setStyles?.(getStyles(viewSettings, themeCode));
getView(bookKey)?.renderer.setStyles?.(getStyles(viewSettings));
};
const handleInput = (e: React.FormEvent<HTMLTextAreaElement>) => {