feat: add option to config reading progress format (#1761)

* feat: added percentage option and set by default

* feat: added decimal percentaje

* fix: fixed issue that the function of format didn't look for typeof

* fix: Added revision fixes

* fix: Added revision fixes and changes

* fix: solved about styling code

* fix: solved about styling code on book.ts and translation.json

* fix: changed lines useEffect line that is escencial to Layoutpanel.tsx, and ProgressInfo.tsx has correct render like last version (Loc.) nd its separator

* fix: correct SUPPORTED_LANGS key and disable style reapplication in saveViewSettings

* i18n for the progress style config

---------

Co-authored-by: Huang Xin <chrox.huang@gmail.com>
This commit is contained in:
Andres Puello
2025-08-08 23:23:18 -05:00
committed by GitHub
parent f46be89036
commit 09e65211b4
26 changed files with 177 additions and 83 deletions
@@ -1,10 +1,11 @@
import clsx from 'clsx';
import React from 'react';
import { Insets } from '@/types/misc';
import { PageInfo, TimeInfo } from '@/types/book';
import { useEnv } from '@/context/EnvContext';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { PageInfo, TimeInfo } from '@/types/book';
import { formatReadingProgress } from '@/utils/progress';
interface PageInfoProps {
bookKey: string;
@@ -36,18 +37,19 @@ const ProgressInfoView: React.FC<PageInfoProps> = ({
const showDoubleBorder = viewSettings.vertical && viewSettings.doubleBorder;
const isScrolled = viewSettings.scrolled;
const isVertical = viewSettings.vertical;
const pageInfo = ['PDF', 'CBZ'].includes(bookFormat)
? section
const { progressStyle: readingProgressStyle } = viewSettings;
const formatTemplate =
readingProgressStyle === 'fraction'
? isVertical
? `${section.current + 1} · ${section.total}`
: `${section.current + 1} / ${section.total}`
: ''
: pageinfo && pageinfo.current >= 0 && pageinfo.total > 0
? _(isVertical ? '{{currentPage}} · {{totalPage}}' : 'Loc. {{currentPage}} / {{totalPage}}', {
currentPage: pageinfo.current + 1,
totalPage: pageinfo.total,
})
: '';
? '{current} · {total}'
: '{current} / {total}'
: '{percent}%';
const progressInfo = ['PDF', 'CBZ'].includes(bookFormat)
? formatReadingProgress(section?.current, section?.total, formatTemplate)
: formatReadingProgress(pageinfo?.current, pageinfo?.total, formatTemplate);
const timeLeft = timeinfo
? _('{{time}} min left in chapter', { time: Math.round(timeinfo.section) })
: '';
@@ -85,7 +87,7 @@ const ProgressInfoView: React.FC<PageInfoProps> = ({
) : viewSettings.showRemainingPages ? (
<span className='text-start'>{pageLeft}</span>
) : null}
{viewSettings.showPageNumber && <span className='ms-auto text-end'>{pageInfo}</span>}
{viewSettings.showProgressInfo && <span className='ms-auto text-end'>{progressInfo}</span>}
</div>
);
};
@@ -18,6 +18,7 @@ import { saveViewSettings } from '../../utils/viewSettingsHelper';
import { getBookDirFromWritingMode, getBookLangCode } from '@/utils/book';
import { MIGHT_BE_RTL_LANGS } from '@/services/constants';
import { SettingsPanelPanelProp } from './SettingsDialog';
import Select from '@/components/Select';
import NumberInput from './NumberInput';
const LayoutPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterReset }) => {
@@ -66,9 +67,9 @@ const LayoutPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRese
const [showBarsOnScroll, setShowBarsOnScroll] = useState(viewSettings.showBarsOnScroll!);
const [showRemainingTime, setShowRemainingTime] = useState(viewSettings.showRemainingTime!);
const [showRemainingPages, setShowRemainingPages] = useState(viewSettings.showRemainingPages!);
const [showPageNumber, setShowPageNumber] = useState(viewSettings.showPageNumber!);
const [showProgressInfo, setShowProgressInfo] = useState(viewSettings.showProgressInfo!);
const [progressStyle, setProgressStyle] = useState(viewSettings.progressStyle);
const [screenOrientation, setScreenOrientation] = useState(viewSettings.screenOrientation!);
const resetToDefaults = useResetViewSettings();
const handleReset = () => {
@@ -100,7 +101,7 @@ const LayoutPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRese
showBarsOnScroll: setShowBarsOnScroll,
showRemainingTime: setShowRemainingTime,
showRemainingPages: setShowRemainingPages,
showPageNumber: setShowPageNumber,
showProgressInfo: setShowProgressInfo,
});
};
@@ -319,9 +320,13 @@ const LayoutPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRese
}, [showRemainingPages]);
useEffect(() => {
saveViewSettings(envConfig, bookKey, 'showPageNumber', showPageNumber, false, false);
saveViewSettings(envConfig, bookKey, 'showProgressInfo', showProgressInfo, false, false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showPageNumber]);
}, [showProgressInfo]);
useEffect(() => {
saveViewSettings(envConfig, bookKey, 'progressStyle', progressStyle, false, false);
}, [progressStyle]);
useEffect(() => {
if (showHeader === viewSettings.showHeader) return;
@@ -654,13 +659,25 @@ const LayoutPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRese
/>
</div>
<div className='config-item'>
<span className=''>{_('Show Page Number')}</span>
<span className=''>{_('Show Reading Progress')}</span>
<input
type='checkbox'
className='toggle'
checked={showPageNumber}
checked={showProgressInfo}
disabled={!showFooter}
onChange={() => setShowPageNumber(!showPageNumber)}
onChange={() => setShowProgressInfo(!showProgressInfo)}
/>
</div>
<div className='config-item'>
<span className=''>{_('Reading Progress Style')}</span>
<Select
value={progressStyle}
onChange={(e) => setProgressStyle(e.target.value as 'percentage' | 'fraction')}
options={[
{ value: 'fraction', label: _('Page Number') },
{ value: 'percentage', label: _('Percentage') },
]}
disabled={!showProgressInfo}
/>
</div>
<div className='config-item'>