Fix page resume in continuous pagers

The image refs weren't always set by the time the last read page got resumed.
Thus, the last read page never got scrolled into view
This commit is contained in:
schroda
2024-12-31 04:01:42 +01:00
parent f808614e6c
commit 9ab6ec89c7

View File

@@ -6,7 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
import { MutableRefObject, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { MutableRefObject, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { Direction } from '@mui/material/styles'; import { Direction } from '@mui/material/styles';
import { import {
ReaderPageSpreadState, ReaderPageSpreadState,
@@ -33,6 +33,7 @@ import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types
import { ReaderControls } from '@/modules/reader/services/ReaderControls.ts'; import { ReaderControls } from '@/modules/reader/services/ReaderControls.ts';
import { coerceIn } from '@/lib/HelperFunctions.ts'; import { coerceIn } from '@/lib/HelperFunctions.ts';
import { TReaderTapZoneContext } from '@/modules/reader/types/TapZoneLayout.types.ts'; import { TReaderTapZoneContext } from '@/modules/reader/types/TapZoneLayout.types.ts';
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
export const getInitialReaderPageIndex = ( export const getInitialReaderPageIndex = (
resumeMode: ReaderResumeMode, resumeMode: ReaderResumeMode,
@@ -231,29 +232,33 @@ export const useReaderHandlePageSelection = (
readingDirection: ReadingDirection, readingDirection: ReadingDirection,
scrollElementRef: MutableRefObject<HTMLDivElement | null>, scrollElementRef: MutableRefObject<HTMLDivElement | null>,
) => { ) => {
useLayoutEffect(() => { const pageToScrollTo = useMemo(() => getPage(pageToScrollToIndex ?? 0, pages), [pageToScrollToIndex, pages]);
const imageRef = imageRefs.current[pageToScrollTo.pagesIndex];
const ref = isContinuousReadingModeActive ? imageRef : scrollElementRef;
useResizeObserver(
ref,
useCallback(
(entries, observer) => {
if (pageToScrollToIndex == null) { if (pageToScrollToIndex == null) {
return; return;
} }
const pageToScrollTo = getPage(pageToScrollToIndex, pages); const element = entries[0].target as HTMLElement;
if (isContinuousReadingModeActive) { if (isContinuousReadingModeActive) {
const directionOffset = const directionOffset =
pageToScrollToIndex > currentPageIndex ? DirectionOffset.PREVIOUS : DirectionOffset.NEXT; pageToScrollToIndex > currentPageIndex ? DirectionOffset.PREVIOUS : DirectionOffset.NEXT;
const imageRef = imageRefs.current[pageToScrollTo.pagesIndex];
imageRef?.scrollIntoView({ element.scrollIntoView({
block: 'start', block: 'start',
inline: getScrollIntoViewInlineOption(directionOffset, themeDirection, readingDirection), inline: getScrollIntoViewInlineOption(directionOffset, themeDirection, readingDirection),
}); });
} }
if (!isContinuousReadingModeActive) { if (!isContinuousReadingModeActive) {
scrollElementRef.current?.scrollTo( element.scrollTo(getScrollToXForReadingDirection(element, themeDirection, readingDirection), 0);
getScrollToXForReadingDirection(scrollElementRef.current, themeDirection, readingDirection),
0,
);
} }
const newPageIndex = getNextIndexFromPage(pageToScrollTo); const newPageIndex = getNextIndexFromPage(pageToScrollTo);
@@ -261,7 +266,12 @@ export const useReaderHandlePageSelection = (
setPageToScrollToIndex(null); setPageToScrollToIndex(null);
updateCurrentPageIndex(newPageIndex, !isLastPage); updateCurrentPageIndex(newPageIndex, !isLastPage);
}, [pageToScrollToIndex]);
observer.disconnect();
},
[pageToScrollToIndex],
),
);
}; };
export const useReaderHideCursorOnInactivity = (scrollElementRef: MutableRefObject<HTMLDivElement | null>) => { export const useReaderHideCursorOnInactivity = (scrollElementRef: MutableRefObject<HTMLDivElement | null>) => {