Fix page shift when toggling "offset double spreads" setting
The pages should get shifted to - the left when enabling - the right when disabling the setting. Currently, the "page push" is inverted. This can cause the page that is most likely being read to get pushed out of the screen. Which then requires the user to change the page. Example: Active page: 1+2 Enable setting: -> 2 (currently) instead of -> 1
This commit is contained in:
@@ -26,6 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
- (**Library**) Fix total library size chip color in light mode
|
||||
- (**Browse**) Fix missing pinned sources in the source language filter
|
||||
- (**Browse**) Fix incorrectly showing "local source" source in the source language filter (the local source can't be disabled)
|
||||
- (**Reader**) Fix page shift when toggling the "offset double spreads" setting (currently: enable: shift to the right; disable: shift to the left – now: inverted)
|
||||
|
||||
## [20251230.01] (r2937) - 2025-12-30
|
||||
|
||||
|
||||
@@ -306,7 +306,11 @@ export interface ReaderStatePages {
|
||||
setPageToScrollToIndex: (total: number | null) => void;
|
||||
pageUrls: string[];
|
||||
setPageUrls: (urls: string[]) => void;
|
||||
pageLoadStates: { url: string; loaded: boolean; error?: boolean }[];
|
||||
pageSpreadStates: ReaderPageSpreadState[];
|
||||
setPageSpreadStates: (
|
||||
set: ((prevStates: ReaderPageSpreadState[]) => ReaderPageSpreadState[]) | ReaderPageSpreadState[],
|
||||
) => void;
|
||||
pageLoadStates: ReaderPageLoadState[];
|
||||
setPageLoadStates: (
|
||||
set: ((prevStates: ReaderPageLoadState[]) => ReaderPageLoadState[]) | ReaderPageLoadState[],
|
||||
) => void;
|
||||
|
||||
@@ -149,10 +149,7 @@ export const ReaderHotkeys = ({
|
||||
ReaderService.updateSetting('shouldStretchPage', !getReaderSettingsStore().shouldStretchPage.value),
|
||||
);
|
||||
useHotkeys(hotkeys[ReaderHotkey.OFFSET_SPREAD_PAGES], () =>
|
||||
ReaderService.updateSetting(
|
||||
'shouldOffsetDoubleSpreads',
|
||||
!getReaderSettingsStore().shouldOffsetDoubleSpreads.value,
|
||||
),
|
||||
ReaderService.setOffsetDoubleSpreads(!getReaderSettingsStore().shouldOffsetDoubleSpreads.value),
|
||||
);
|
||||
useHotkeys(hotkeys[ReaderHotkey.CYCLE_READING_MODE], () => {
|
||||
updateSettingCycleThrough(
|
||||
|
||||
@@ -43,9 +43,7 @@ const BaseReaderNavBarDesktopQuickSettings = ({ openSettings }: Pick<ReaderNavBa
|
||||
<ReaderNavBarDesktopOffsetDoubleSpread
|
||||
readingMode={readingMode.value}
|
||||
shouldOffsetDoubleSpreads={shouldOffsetDoubleSpreads.value}
|
||||
setShouldOffsetDoubleSpreads={(value) =>
|
||||
ReaderService.updateSetting('shouldOffsetDoubleSpreads', value)
|
||||
}
|
||||
setShouldOffsetDoubleSpreads={(value) => ReaderService.setOffsetDoubleSpreads(value)}
|
||||
/>
|
||||
<ReaderNavBarDesktopPageScale
|
||||
pageScaleMode={pageScaleMode}
|
||||
|
||||
@@ -47,12 +47,14 @@ import { getMetadataKey } from '@/features/metadata/Metadata.utils.ts';
|
||||
import { DirectionOffset } from '@/base/Base.types.ts';
|
||||
import {
|
||||
getReaderChaptersStore,
|
||||
getReaderPagesStore,
|
||||
getReaderSettingsStore,
|
||||
getReaderStore,
|
||||
useReaderSettingsStore,
|
||||
} from '@/features/reader/stores/ReaderStore.ts';
|
||||
import { ReactRouter } from '@/lib/react-router/ReactRouter.ts';
|
||||
import { ReaderChaptersStoreSlice } from '@/features/reader/stores/ReaderChaptersStore.ts';
|
||||
import { getPage } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx';
|
||||
|
||||
const DIRECTION_TO_INVERTED: Record<Direction, Direction> = {
|
||||
ltr: 'rtl',
|
||||
@@ -237,6 +239,41 @@ export class ReaderService {
|
||||
: DIRECTION_TO_INVERTED[direction];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the setting and updated the current page index accordingly.
|
||||
*
|
||||
* In case the current page is a spread page, the page index won't get changed.
|
||||
*
|
||||
* Enable:
|
||||
* Push pages to the left
|
||||
*
|
||||
* Page 3+2 -> Page 2+1 - the third page gets pushed to the left, out of the screen
|
||||
*
|
||||
* Disable:
|
||||
* Push pages to the right
|
||||
*
|
||||
* Page 3+2 -> Page 4+3 - the second page gets pushed to the right, out of the screen
|
||||
*/
|
||||
static setOffsetDoubleSpreads(shouldOffset: boolean): void {
|
||||
const { pages, currentPageIndex, pageSpreadStates } = getReaderPagesStore();
|
||||
const { readingMode } = getReaderSettingsStore();
|
||||
|
||||
const isDoublePageMode = readingMode.value === ReadingMode.DOUBLE_PAGE;
|
||||
const isSpreadPage = !!pageSpreadStates[currentPageIndex]?.isSpread;
|
||||
|
||||
const updatePageIndex = isDoublePageMode && !isSpreadPage;
|
||||
if (!updatePageIndex) {
|
||||
ReaderService.updateSetting('shouldOffsetDoubleSpreads', shouldOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
const page = getPage(currentPageIndex, pages);
|
||||
const updatedPageIndex = shouldOffset ? page.primary.index : currentPageIndex;
|
||||
|
||||
getReaderPagesStore().setCurrentPageIndex(updatedPageIndex);
|
||||
ReaderService.updateSetting('shouldOffsetDoubleSpreads', shouldOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the change immediately to the cache and sends a mutation in case "commit" is true.
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ export const READER_DEFAULT_PAGES_STATE: Omit<
|
||||
| 'setPageToScrollToIndex'
|
||||
| 'setTotalPages'
|
||||
| 'setPageUrls'
|
||||
| 'setPageSpreadStates'
|
||||
| 'setPageLoadStates'
|
||||
| 'setPages'
|
||||
| 'setTransitionPageMode'
|
||||
@@ -32,6 +33,7 @@ export const READER_DEFAULT_PAGES_STATE: Omit<
|
||||
currentPageIndex: 0,
|
||||
pageToScrollToIndex: null,
|
||||
pageUrls: [],
|
||||
pageSpreadStates: [{ url: '', isSpread: false }],
|
||||
pageLoadStates: [{ url: '', loaded: false }],
|
||||
pages: [
|
||||
{
|
||||
@@ -85,6 +87,19 @@ export const createReaderPagesStoreSlice = <T extends ReaderPagesStoreSlice>(
|
||||
undefined,
|
||||
createActionName('setPageUrls'),
|
||||
),
|
||||
setPageSpreadStates: (spreadStates) =>
|
||||
set(
|
||||
(draft) => {
|
||||
if (typeof spreadStates === 'function') {
|
||||
draft.pages.pageSpreadStates = spreadStates(get().pages.pageSpreadStates);
|
||||
return;
|
||||
}
|
||||
|
||||
draft.pages.pageSpreadStates = spreadStates;
|
||||
},
|
||||
undefined,
|
||||
createActionName('setPageSpreadStates'),
|
||||
),
|
||||
setPageLoadStates: (loadStates) =>
|
||||
set(
|
||||
(draft) => {
|
||||
|
||||
@@ -50,6 +50,7 @@ const BaseReaderChapterViewer = ({
|
||||
currentPageIndex,
|
||||
setPages: setContextPages,
|
||||
setPageUrls: setContextPageUrls,
|
||||
setPageSpreadStates: setContextPageSpreadStates,
|
||||
setPageLoadStates: setContextPageLoadStates,
|
||||
setTotalPages: setContextTotalPages,
|
||||
setCurrentPageIndex: setContextCurrentPageIndex,
|
||||
@@ -93,6 +94,7 @@ const BaseReaderChapterViewer = ({
|
||||
| 'currentPageIndex'
|
||||
| 'setPages'
|
||||
| 'setPageUrls'
|
||||
| 'setPageSpreadStates'
|
||||
| 'setPageLoadStates'
|
||||
| 'setTotalPages'
|
||||
| 'setCurrentPageIndex'
|
||||
@@ -140,7 +142,7 @@ const BaseReaderChapterViewer = ({
|
||||
READER_DEFAULT_PAGES_STATE.pageLoadStates,
|
||||
);
|
||||
const [pagesToSpreadState, setPagesToSpreadState] = useState<ReaderPageSpreadState[]>(
|
||||
pageLoadStates.map(({ url }) => ({ url, isSpread: false })),
|
||||
READER_DEFAULT_PAGES_STATE.pageSpreadStates,
|
||||
);
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
@@ -201,7 +203,13 @@ const BaseReaderChapterViewer = ({
|
||||
() =>
|
||||
createUpdateReaderPageLoadState(
|
||||
actualPages,
|
||||
setPagesToSpreadState,
|
||||
(value) => {
|
||||
if (isCurrentChapterRef.current) {
|
||||
setContextPageSpreadStates(value);
|
||||
}
|
||||
|
||||
setPagesToSpreadState(value);
|
||||
},
|
||||
(value) => {
|
||||
if (isCurrentChapterRef.current) {
|
||||
setContextPageLoadStates(value);
|
||||
@@ -270,7 +278,7 @@ const BaseReaderChapterViewer = ({
|
||||
(value) => updateState(value, setPages, setContextPages),
|
||||
(value) => updateState(value, setPageUrls, setContextPageUrls),
|
||||
(value) => updateState(value, setPageLoadStates, setContextPageLoadStates),
|
||||
(value) => updateState(value, setPagesToSpreadState, noOp),
|
||||
(value) => updateState(value, setPagesToSpreadState, setContextPageSpreadStates),
|
||||
(value) => updateState(value, noOp, setContextCurrentPageIndex),
|
||||
(value) => {
|
||||
if ((isInitialChapter && !arePagesFetched) || scrollIntoView) {
|
||||
|
||||
@@ -82,6 +82,7 @@ const BaseReaderViewer = ({
|
||||
totalPages,
|
||||
setPages,
|
||||
setPageUrls,
|
||||
setPageSpreadStates,
|
||||
setPageLoadStates,
|
||||
setTotalPages,
|
||||
setCurrentPageIndex,
|
||||
@@ -96,6 +97,7 @@ const BaseReaderViewer = ({
|
||||
totalPages: state.pages.totalPages,
|
||||
setPages: state.pages.setPages,
|
||||
setPageUrls: state.pages.setPageUrls,
|
||||
setPageSpreadStates: state.pages.setPageSpreadStates,
|
||||
setPageLoadStates: state.pages.setPageLoadStates,
|
||||
setTotalPages: state.pages.setTotalPages,
|
||||
setCurrentPageIndex: state.pages.setCurrentPageIndex,
|
||||
@@ -381,6 +383,7 @@ const BaseReaderViewer = ({
|
||||
imageRefs={imageRefs}
|
||||
setPages={setPages}
|
||||
setPageUrls={setPageUrls}
|
||||
setPageSpreadStates={setPageSpreadStates}
|
||||
setPageLoadStates={setPageLoadStates}
|
||||
setTotalPages={setTotalPages}
|
||||
setCurrentPageIndex={setCurrentPageIndex}
|
||||
|
||||
Reference in New Issue
Block a user