From 36fa8dbe38e2d34f6d5df327efb81f7e7a64adf8 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 28 Apr 2025 02:21:23 +0200 Subject: [PATCH] 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. --- .../hooks/useReaderPreserveScrollPosition.ts | 40 +++++++++++++++---- .../reader/utils/ReaderSettings.utils.tsx | 3 ++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/modules/reader/hooks/useReaderPreserveScrollPosition.ts b/src/modules/reader/hooks/useReaderPreserveScrollPosition.ts index 95394920..0743ea0a 100644 --- a/src/modules/reader/hooks/useReaderPreserveScrollPosition.ts +++ b/src/modules/reader/hooks/useReaderPreserveScrollPosition.ts @@ -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>, 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); }; diff --git a/src/modules/reader/utils/ReaderSettings.utils.tsx b/src/modules/reader/utils/ReaderSettings.utils.tsx index 623917b6..11d73bd8 100644 --- a/src/modules/reader/utils/ReaderSettings.utils.tsx +++ b/src/modules/reader/utils/ReaderSettings.utils.tsx @@ -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'],