Improve scroll preservation on window resize

The previous logic just preserved the scroll position on any resize event regardless of if the resize (width or height change) caused the scroll position to get lost or not.

E.g., when the "page scale mode" respected only the width and the resize only changed the window height, it still preserved the scroll position, while the scroll position did not get lost.
This commit is contained in:
schroda
2025-04-28 02:21:23 +02:00
parent ef3538d762
commit 36fa8dbe38
2 changed files with 36 additions and 7 deletions

View File

@@ -9,12 +9,33 @@
import { RefObject, useEffect, useLayoutEffect, useRef } from 'react';
import { ReaderPageScaleMode, ReadingDirection, ReadingMode } from '@/modules/reader/types/Reader.types.ts';
import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types';
import { isReaderWidthEditable } from '@/modules/reader/utils/ReaderSettings.utils.tsx';
import {
isContinuousVerticalReadingMode,
isHeightPageScaleMode,
isReaderWidthEditable,
} from '@/modules/reader/utils/ReaderSettings.utils.tsx';
const shouldPreserveOnResizeChange = (
isContinuousReadingModeActive: boolean,
readingMode: ReadingMode,
pageScaleMode: ReaderPageScaleMode,
): boolean => isContinuousReadingModeActive && isReaderWidthEditable(pageScaleMode);
previousWidth: number,
previousHeight: number,
): boolean => {
const isEditableReaderWidth = isReaderWidthEditable(pageScaleMode);
const isHeightPageScaleModeActive = isHeightPageScaleMode(pageScaleMode);
const didWidthChange = previousWidth !== window.innerWidth;
const didHeightChange = previousHeight !== window.innerHeight;
const handleWidthChange = isEditableReaderWidth && didWidthChange;
const handleHeightChange = isHeightPageScaleModeActive && didHeightChange;
if (!isContinuousVerticalReadingMode(readingMode) && didWidthChange) {
return true;
}
return handleWidthChange || handleHeightChange;
};
const usePreserveOnValueChange = (
value: unknown,
@@ -27,14 +48,19 @@ const usePreserveOnValueChange = (
};
const usePreserveOnWindowResize = (
isContinuousReadingModeActive: boolean,
readingMode: ReadingMode,
pageScaleMode: ReaderPageScaleMode,
setPageToScrollToIndex: React.Dispatch<React.SetStateAction<number | null>>,
pageIndex: number,
) => {
const previousDimensionsRef = useRef({ width: window.innerWidth, height: window.innerHeight });
useEffect(() => {
const handleResize = () => {
if (!shouldPreserveOnResizeChange(isContinuousReadingModeActive, pageScaleMode)) {
const { width, height } = previousDimensionsRef.current;
previousDimensionsRef.current = { width: window.innerWidth, height: window.innerHeight };
if (!shouldPreserveOnResizeChange(readingMode, pageScaleMode, width, height)) {
return;
}
@@ -43,7 +69,7 @@ const usePreserveOnWindowResize = (
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, [isContinuousReadingModeActive, pageScaleMode, pageIndex]);
}, [readingMode, pageScaleMode, pageIndex]);
};
const usePreserveOnReaderViewerElementMutation = (
@@ -172,7 +198,7 @@ export const useReaderPreserveScrollPosition = (
pageScaleMode: ReaderPageScaleMode,
) => {
usePreserveOnReaderViewerElementMutation(scrollElementRef, isContinuousReadingModeActive);
usePreserveOnWindowResize(isContinuousReadingModeActive, pageScaleMode, setPageToScrollToIndex, pageIndex);
usePreserveOnWindowResize(readingMode, pageScaleMode, setPageToScrollToIndex, pageIndex);
usePreserveOnValueChange(readingDirection, pageIndex, setPageToScrollToIndex);
usePreserveOnValueChange(readingMode, pageIndex, setPageToScrollToIndex);
};

View File

@@ -29,6 +29,9 @@ export const isOffsetDoubleSpreadPagesEditable = (readingMode: IReaderSettings['
export const isReaderWidthEditable = (pageScaleMode: IReaderSettings['pageScaleMode']): boolean =>
[ReaderPageScaleMode.WIDTH, ReaderPageScaleMode.SCREEN].includes(pageScaleMode);
export const isHeightPageScaleMode = (pageScaleMode: ReaderPageScaleMode): boolean =>
[ReaderPageScaleMode.HEIGHT, ReaderPageScaleMode.SCREEN].includes(pageScaleMode);
export const shouldApplyReaderWidth = (
readerWidth: IReaderSettings['readerWidth'] | undefined,
pageScaleMode: IReaderSettings['pageScaleMode'],