refactor: always save when changes are made with settings, also closes #626 (#630)

This commit is contained in:
Huang Xin
2025-03-18 19:58:01 +08:00
committed by GitHub
parent 72e6c058f5
commit 359fa8df35
12 changed files with 130 additions and 212 deletions
@@ -81,18 +81,24 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
/>
<FoliateViewer bookKey={bookKey} bookDoc={bookDoc} config={config} />
<FootnotePopup bookKey={bookKey} bookDoc={bookDoc} />
<div
className='bg-base-100 absolute left-0 top-0 h-full'
style={{
width: `${horizontalGapPercent}%`,
}}
/>
<div
className='bg-base-100 absolute right-0 top-0 h-full'
style={{
width: `${horizontalGapPercent}%`,
}}
/>
{viewSettings.vertical && (
<>
<div
className='bg-base-100 absolute left-0 top-0 h-full'
style={{
width: `calc(${horizontalGapPercent}%)`,
height: `calc(100% - ${verticalMarginPixels}px)`,
}}
/>
<div
className='bg-base-100 absolute right-0 top-0 h-full'
style={{
width: `calc(${horizontalGapPercent}%)`,
height: `calc(100% - ${verticalMarginPixels}px)`,
}}
/>
</>
)}
{viewSettings.vertical && viewSettings.doubleBorder && (
<DoubleBorder
showHeader={viewSettings.showHeader}
@@ -105,6 +111,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
{viewSettings.showHeader && (
<SectionInfo
section={sectionLabel}
showDoubleBorder={viewSettings.vertical && viewSettings.doubleBorder}
isVertical={viewSettings.vertical}
horizontalGap={horizontalGapPercent}
verticalMargin={verticalMarginPixels}
@@ -112,6 +119,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
)}
<HintInfo
bookKey={bookKey}
showDoubleBorder={viewSettings.vertical && viewSettings.doubleBorder}
isVertical={viewSettings.vertical}
horizontalGap={horizontalGapPercent}
verticalMargin={verticalMarginPixels}
@@ -121,6 +129,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
bookFormat={book.format}
section={section}
pageinfo={pageinfo}
showDoubleBorder={viewSettings.vertical && viewSettings.doubleBorder}
isVertical={viewSettings.vertical}
horizontalGap={horizontalGapPercent}
verticalMargin={verticalMarginPixels}
@@ -4,6 +4,7 @@ import { eventDispatcher } from '@/utils/event';
interface SectionInfoProps {
bookKey: string;
showDoubleBorder: boolean;
isVertical: boolean;
horizontalGap: number;
verticalMargin: number;
@@ -11,6 +12,7 @@ interface SectionInfoProps {
const HintInfo: React.FC<SectionInfoProps> = ({
bookKey,
showDoubleBorder,
isVertical,
horizontalGap,
verticalMargin,
@@ -47,15 +49,16 @@ const HintInfo: React.FC<SectionInfoProps> = ({
className={clsx(
'hintinfo absolute flex items-center justify-end overflow-hidden',
hintMessage ? 'bg-base-100' : 'bg-transparent',
isVertical ? 'writing-vertical-rl max-h-[50%] w-[30px]' : 'top-0 h-[44px] max-w-[50%]',
isVertical ? 'writing-vertical-rl max-h-[50%]' : 'top-0 h-[44px] max-w-[50%]',
)}
style={
isVertical
? {
bottom: `${verticalMargin * 1.5}px`,
left: `calc(100% - ${horizontalGap}%)`,
width: showDoubleBorder ? '30px' : `${horizontalGap}%`,
}
: { right: `${horizontalGap}%` }
: { insetInlineEnd: `${horizontalGap}%` }
}
>
<h2 className={clsx('text-neutral-content text-center font-sans text-xs font-light')}>
@@ -7,6 +7,7 @@ interface PageInfoProps {
bookFormat: string;
section?: PageInfo;
pageinfo?: PageInfo;
showDoubleBorder: boolean;
isVertical: boolean;
horizontalGap: number;
verticalMargin: number;
@@ -16,6 +17,7 @@ const PageInfoView: React.FC<PageInfoProps> = ({
bookFormat,
section,
pageinfo,
showDoubleBorder,
isVertical,
horizontalGap,
verticalMargin,
@@ -42,16 +44,17 @@ const PageInfoView: React.FC<PageInfoProps> = ({
<div
className={clsx(
'pageinfo absolute bottom-0 flex items-center justify-end',
isVertical ? 'writing-vertical-rl left-0 w-[32px]' : 'bg-base-100 right-0 h-12 w-full',
isVertical ? 'writing-vertical-rl' : 'bg-base-100 h-12 w-full',
)}
style={
isVertical
? {
bottom: `${verticalMargin * 1.5}px`,
left: `calc(${horizontalGap}% - 32px)`,
left: showDoubleBorder ? `calc(${horizontalGap}% - 32px)` : 0,
width: showDoubleBorder ? '32px' : `${horizontalGap}%`,
height: `calc(100% - ${verticalMargin * 2}px)`,
}
: { paddingRight: `${horizontalGap}%` }
: { insetInlineEnd: `${horizontalGap}%` }
}
>
<h2 className='text-neutral-content text-right font-sans text-xs font-extralight'>
@@ -3,6 +3,7 @@ import React from 'react';
interface SectionInfoProps {
section?: string;
showDoubleBorder: boolean;
isVertical: boolean;
horizontalGap: number;
verticalMargin: number;
@@ -10,6 +11,7 @@ interface SectionInfoProps {
const SectionInfo: React.FC<SectionInfoProps> = ({
section,
showDoubleBorder,
isVertical,
horizontalGap,
verticalMargin,
@@ -18,18 +20,17 @@ const SectionInfo: React.FC<SectionInfoProps> = ({
<div
className={clsx(
'sectioninfo absolute flex items-center overflow-hidden',
isVertical
? 'writing-vertical-rl max-h-[85%] w-[32px]'
: 'bg-base-100 top-0 h-[44px] w-full',
isVertical ? 'writing-vertical-rl max-h-[85%]' : 'bg-base-100 top-0 h-[44px]',
)}
style={
isVertical
? {
top: `${verticalMargin * 1.5}px`,
left: `calc(100% - ${horizontalGap}%)`,
width: showDoubleBorder ? '32px' : `${horizontalGap}%`,
height: `calc(100% - ${verticalMargin * 2}px)`,
}
: { paddingLeft: `${horizontalGap}%` }
: { insetInlineStart: `${horizontalGap}%`, width: `calc(100% - ${horizontalGap * 2}%)` }
}
>
<h2
@@ -14,13 +14,13 @@ import {
WINDOWS_FONTS,
} from '@/services/constants';
import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useEnv } from '@/context/EnvContext';
import { getStyles } from '@/utils/style';
import { getOSPlatform } from '@/utils/misc';
import { getSysFontsList } from '@/utils/font';
import { isTauriAppPlatform } from '@/services/environment';
import { saveViewSettings } from '../../utils/viewSettingsHelper';
interface FontFaceProps {
className?: string;
@@ -60,9 +60,8 @@ const FontFace = ({
const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const _ = useTranslation();
const { appService } = useEnv();
const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore();
const { getView, getViewSettings, setViewSettings } = useReaderStore();
const { envConfig, appService } = useEnv();
const { getView, getViewSettings } = useReaderStore();
const view = getView(bookKey);
const viewSettings = getViewSettings(bookKey)!;
@@ -118,89 +117,49 @@ const FontPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
}, []);
useEffect(() => {
viewSettings.defaultFont = defaultFont;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.defaultFont = defaultFont;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'defaultFont', defaultFont);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultFont]);
useEffect(() => {
viewSettings.defaultFontSize = defaultFontSize;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.defaultFontSize = defaultFontSize;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'defaultFontSize', defaultFontSize);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultFontSize]);
useEffect(() => {
viewSettings.minimumFontSize = minFontSize;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.minimumFontSize = minFontSize;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'minimumFontSize', minFontSize);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [minFontSize]);
useEffect(() => {
viewSettings.fontWeight = fontWeight;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.fontWeight = fontWeight;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'fontWeight', fontWeight);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fontWeight]);
useEffect(() => {
viewSettings.serifFont = serifFont;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.serifFont = serifFont;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'serifFont', serifFont);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [serifFont]);
useEffect(() => {
viewSettings.sansSerifFont = sansSerifFont;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.sansSerifFont = sansSerifFont;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'sansSerifFont', sansSerifFont);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sansSerifFont]);
useEffect(() => {
viewSettings.monospaceFont = monospaceFont;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.monospaceFont = monospaceFont;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'monospaceFont', monospaceFont);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [monospaceFont]);
useEffect(() => {
viewSettings.overrideFont = overrideFont;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.overrideFont = overrideFont;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'overrideFont', overrideFont);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [overrideFont]);
@@ -3,7 +3,7 @@ import { MdOutlineAutoMode } from 'react-icons/md';
import { MdOutlineTextRotationNone, MdTextRotateVertical } from 'react-icons/md';
import { TbTextDirectionRtl } from 'react-icons/tb';
import { useSettingsStore } from '@/store/settingsStore';
import { useEnv } from '@/context/EnvContext';
import { useReaderStore } from '@/store/readerStore';
import { useBookDataStore } from '@/store/bookDataStore';
import { useTranslation } from '@/hooks/useTranslation';
@@ -12,11 +12,12 @@ import { getStyles } from '@/utils/style';
import { getMaxInlineSize } from '@/utils/config';
import { getBookDirFromWritingMode, getBookLangCode } from '@/utils/book';
import { MIGHT_BE_RTL_LANGS } from '@/services/constants';
import { saveViewSettings } from '../../utils/viewSettingsHelper';
import NumberInput from './NumberInput';
const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const _ = useTranslation();
const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore();
const { envConfig } = useEnv();
const { getView, getViewSettings, setViewSettings } = useReaderStore();
const { getBookData } = useBookDataStore();
const view = getView(bookKey);
@@ -44,100 +45,55 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const [showFooter, setShowFooter] = useState(viewSettings.showFooter!);
useEffect(() => {
viewSettings.paragraphMargin = paragraphMargin;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.paragraphMargin = paragraphMargin;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'paragraphMargin', paragraphMargin);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [paragraphMargin]);
useEffect(() => {
viewSettings.lineHeight = lineHeight;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.lineHeight = lineHeight;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'lineHeight', lineHeight);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [lineHeight]);
useEffect(() => {
viewSettings.wordSpacing = wordSpacing;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.wordSpacing = wordSpacing;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'wordSpacing', wordSpacing);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wordSpacing]);
useEffect(() => {
viewSettings.letterSpacing = letterSpacing;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.letterSpacing = letterSpacing;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'letterSpacing', letterSpacing);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [letterSpacing]);
useEffect(() => {
viewSettings.textIndent = textIndent;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.textIndent = textIndent;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'textIndent', textIndent);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [textIndent]);
useEffect(() => {
viewSettings.fullJustification = fullJustification;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.fullJustification = fullJustification;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'fullJustification', fullJustification);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fullJustification]);
useEffect(() => {
viewSettings.hyphenation = hyphenation;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.hyphenation = hyphenation;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'hyphenation', hyphenation);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hyphenation]);
useEffect(() => {
viewSettings.marginPx = marginPx;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.marginPx = marginPx;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'marginPx', marginPx);
view?.renderer.setAttribute('margin', `${marginPx}px`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [marginPx]);
useEffect(() => {
viewSettings.gapPercent = gapPercent;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.gapPercent = gapPercent;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'gapPercent', gapPercent);
view?.renderer.setAttribute('gap', `${gapPercent}%`);
if (viewSettings.scrolled) {
view?.renderer.setAttribute('flow', 'scrolled');
@@ -146,35 +102,20 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
}, [gapPercent]);
useEffect(() => {
viewSettings.maxColumnCount = maxColumnCount;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.maxColumnCount = maxColumnCount;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'maxColumnCount', maxColumnCount);
view?.renderer.setAttribute('max-column-count', maxColumnCount);
view?.renderer.setAttribute('max-inline-size', `${getMaxInlineSize(viewSettings)}px`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxColumnCount]);
useEffect(() => {
viewSettings.maxInlineSize = maxInlineSize;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.maxInlineSize = maxInlineSize;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'maxInlineSize', maxInlineSize);
view?.renderer.setAttribute('max-inline-size', `${getMaxInlineSize(viewSettings)}px`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxInlineSize]);
useEffect(() => {
viewSettings.maxBlockSize = maxBlockSize;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.maxBlockSize = maxBlockSize;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'maxBlockSize', maxBlockSize);
view?.renderer.setAttribute('max-block-size', `${maxBlockSize}px`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxBlockSize]);
@@ -182,11 +123,10 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
useEffect(() => {
// global settings are not supported for writing mode
const prevWritingMode = viewSettings.writingMode;
viewSettings.writingMode = writingMode;
if (writingMode.includes('vertical')) {
viewSettings.vertical = true;
if (!writingMode.includes('vertical')) {
viewSettings.vertical = false;
}
setViewSettings(bookKey, viewSettings);
saveViewSettings(envConfig, bookKey, 'writingMode', writingMode, true);
if (view) {
view.renderer.setStyles?.(getStyles(viewSettings));
view.book.dir = getBookDirFromWritingMode(writingMode);
@@ -202,69 +142,46 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
}, [writingMode]);
useEffect(() => {
viewSettings.overrideLayout = overrideLayout;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.overrideLayout = overrideLayout;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'overrideLayout', overrideLayout);
view?.renderer.setStyles?.(getStyles(viewSettings));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [overrideLayout]);
useEffect(() => {
viewSettings!.scrolled = isScrolledMode;
saveViewSettings(envConfig, bookKey, 'scrolled', isScrolledMode);
getView(bookKey)?.renderer.setAttribute('flow', isScrolledMode ? 'scrolled' : 'paginated');
getView(bookKey)?.renderer.setAttribute(
'max-inline-size',
`${getMaxInlineSize(viewSettings)}px`,
);
getView(bookKey)?.renderer.setStyles?.(getStyles(viewSettings!));
setViewSettings(bookKey, viewSettings!);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.scrolled = isScrolledMode;
setSettings(settings);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isScrolledMode]);
useEffect(() => {
viewSettings.doubleBorder = doubleBorder;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.doubleBorder = doubleBorder;
setSettings(settings);
if (doubleBorder && viewSettings.vertical) {
viewSettings.gapPercent = Math.max(
viewSettings.gapPercent,
Math.ceil(4800 / window.innerWidth),
);
setViewSettings(bookKey, viewSettings);
}
saveViewSettings(envConfig, bookKey, 'doubleBorder', doubleBorder);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [doubleBorder]);
useEffect(() => {
viewSettings.borderColor = borderColor;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.borderColor = borderColor;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'borderColor', borderColor);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [borderColor]);
useEffect(() => {
viewSettings.showHeader = showHeader;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.showHeader = showHeader;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'showHeader', showHeader);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showHeader]);
useEffect(() => {
viewSettings.showFooter = showFooter;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.showFooter = showFooter;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'showFooter', showFooter);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showFooter]);
@@ -473,9 +390,12 @@ const LayoutPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
label={_('Horizontal Margins (%)')}
value={gapPercent}
onChange={setGapPercent}
min={viewSettings.vertical ? 2 : 0}
min={
viewSettings.vertical && (showFooter || showHeader)
? Math.ceil(4800 / window.innerWidth)
: 0
}
max={30}
step={0.5}
/>
<NumberInput
label={_('Maximum Number of Columns')}
@@ -1,14 +1,17 @@
import clsx from 'clsx';
import React, { useEffect, useState } from 'react';
import { useEnv } from '@/context/EnvContext';
import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { getStyles } from '@/utils/style';
import { saveViewSettings } from '../../utils/viewSettingsHelper';
import cssbeautify from 'cssbeautify';
import cssValidate from '@/utils/css';
const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const _ = useTranslation();
const { envConfig } = useEnv();
const { settings, isFontLayoutSettingsGlobal, setSettings } = useSettingsStore();
const { getView, getViewSettings, setViewSettings } = useReaderStore();
const viewSettings = getViewSettings(bookKey)!;
@@ -67,12 +70,7 @@ const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
};
useEffect(() => {
viewSettings.animated = animated;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.animated = animated;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'animated', animated);
if (animated) {
getView(bookKey)?.renderer.setAttribute('animated', '');
} else {
@@ -82,22 +80,12 @@ const MiscPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
}, [animated]);
useEffect(() => {
viewSettings.disableClick = isDisableClick;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.disableClick = isDisableClick;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'disableClick', isDisableClick);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isDisableClick]);
useEffect(() => {
viewSettings.continuousScroll = isContinuousScroll;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal) {
settings.globalViewSettings.continuousScroll = isContinuousScroll;
setSettings(settings);
}
saveViewSettings(envConfig, bookKey, 'continuousScroll', isContinuousScroll);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isContinuousScroll]);
@@ -28,7 +28,9 @@ type TabConfig = {
const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ bookKey }) => {
const _ = useTranslation();
const [activePanel, setActivePanel] = useState<SettingsPanelType>('Font');
const [activePanel, setActivePanel] = useState<SettingsPanelType>(
(localStorage.getItem('lastConfigPanel') || 'Font') as SettingsPanelType,
);
const { setFontLayoutSettingsDialogOpen } = useSettingsStore();
const tabConfig = [
@@ -54,6 +56,11 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo
},
] as TabConfig[];
const handleSetActivePanel = (tab: SettingsPanelType) => {
setActivePanel(tab);
localStorage.setItem('lastConfigPanel', tab);
};
const handleClose = () => {
setFontLayoutSettingsDialogOpen(false);
};
@@ -76,7 +83,7 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo
>
<MdArrowBackIosNew />
</button>
<div className='dialog-tabs flex h-10 max-w-[100%] flex-grow items-center pl-4 gap-2'>
<div className='dialog-tabs flex h-10 max-w-[100%] flex-grow items-center gap-2 pl-4'>
{tabConfig.map(({ tab, icon: Icon, label }) => (
<button
key={tab}
@@ -84,7 +91,7 @@ const SettingsDialog: React.FC<{ bookKey: string; config: BookConfig }> = ({ boo
'btn btn-ghost text-base-content btn-sm',
activePanel === tab ? 'btn-active' : '',
)}
onClick={() => setActivePanel(tab)}
onClick={() => handleSetActivePanel(tab)}
>
<Icon className='mr-0' />
{window.innerWidth >= 500 ? label : ''}
@@ -0,0 +1,29 @@
import { ViewSettings } from '@/types/book';
import { EnvConfigType } from '@/services/environment';
import { useBookDataStore } from '@/store/bookDataStore';
import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
export const saveViewSettings = async <K extends keyof ViewSettings>(
envConfig: EnvConfigType,
bookKey: string,
key: K,
value: ViewSettings[K],
skipGlobal?: boolean,
) => {
const { settings, isFontLayoutSettingsGlobal, setSettings, saveSettings } =
useSettingsStore.getState();
const { getViewSettings, setViewSettings } = useReaderStore.getState();
const { getConfig, saveConfig } = useBookDataStore.getState();
const viewSettings = getViewSettings(bookKey)!;
const config = getConfig(bookKey)!;
viewSettings[key] = value;
setViewSettings(bookKey, viewSettings);
if (isFontLayoutSettingsGlobal && !skipGlobal) {
settings.globalViewSettings[key] = value;
setSettings(settings);
}
await saveConfig(envConfig, bookKey, config, settings);
await saveSettings(envConfig, settings);
};
+1 -1
View File
@@ -71,7 +71,7 @@ export const DEFAULT_BOOK_LAYOUT: BookLayout = {
writingMode: 'auto',
vertical: false,
rtl: false,
doubleBorder: true,
doubleBorder: false,
borderColor: 'red',
showHeader: true,
showFooter: true,
-1
View File
@@ -18,7 +18,6 @@ export const getSysFontsList = async (): Promise<string[]> => {
if (FONT_ENUM_SUPPORTED_OS_PLATFORMS.includes(osPlatform)) {
const fonts = await invoke<string[]>('list_fonts');
cachedSysFonts = [...new Set(fonts.filter((font) => !isSymbolicFontName(font)))].sort();
console.log('Fetched font list:', cachedSysFonts);
return cachedSysFonts;
} else {
console.warn(`Unsupported platform: ${osPlatform}`);