Preload previous/next chapter in reader

This commit is contained in:
schroda
2025-02-10 01:05:35 +01:00
parent 16c1edaa52
commit 174d850093
14 changed files with 185 additions and 44 deletions

View File

@@ -78,6 +78,7 @@ const BaseReaderChapterViewer = ({
isNextChapter,
isLeadingChapter,
isTrailingChapter,
isPreloadMode,
imageRefs: globalImageRefs,
scrollIntoView,
setReaderStateChapters,
@@ -172,7 +173,15 @@ const BaseReaderChapterViewer = ({
const Pager = useMemo(() => getPagerForReadingMode(readingMode), [readingMode]);
const isLtrReadingDirection = readingDirection === ReadingDirection.LTR;
const isContinuousReadingModeActive = isContinuousReadingMode(readingMode);
const shouldHideChapter = !isContinuousReadingModeActive && !isCurrentChapter;
const shouldHideChapter = (!isContinuousReadingModeActive && !isCurrentChapter) || isPreloadMode;
const isCurrentChapterInSinglePager = !isContinuousReadingModeActive && isCurrentChapter;
const showPreviousTransitionPage =
!shouldHideChapter &&
(isCurrentChapterInSinglePager || (isContinuousReadingModeActive && (isInitialChapter || isLeadingChapter)));
const showNextTransitionPage =
!shouldHideChapter &&
(isCurrentChapterInSinglePager || (isContinuousReadingModeActive && (isInitialChapter || isTrailingChapter)));
isCurrentChapterRef.current = isCurrentChapter;
if (isCurrentChapter) {
@@ -240,7 +249,7 @@ const BaseReaderChapterViewer = ({
),
);
const updatePageState = <T,>(
const updateState = <T,>(
value: T,
setLocalState: (value: T) => void,
setGlobalState: (value: T) => void,
@@ -264,13 +273,13 @@ const BaseReaderChapterViewer = ({
pagesToSpreadState,
arePagesFetched,
setArePagesFetched,
setReaderStateChapters,
(value) => updatePageState(value, setTotalPages, setContextTotalPages),
(value) => updatePageState(value, setPages, setContextPages),
(value) => updatePageState(value, setPageUrls, noOp),
(value) => updatePageState(value, setPageLoadStates, setContextPageLoadStates),
(value) => updatePageState(value, setPagesToSpreadState, noOp),
(value) => updatePageState(value, noOp, setContextCurrentPageIndex),
(value) => updateState(value, noOp, setReaderStateChapters),
(value) => updateState(value, setTotalPages, setContextTotalPages),
(value) => updateState(value, setPages, setContextPages),
(value) => updateState(value, setPageUrls, noOp),
(value) => updateState(value, setPageLoadStates, setContextPageLoadStates),
(value) => updateState(value, setPagesToSpreadState, noOp),
(value) => updateState(value, noOp, setContextCurrentPageIndex),
(value) => {
if ((isInitialChapter && !arePagesFetched) || scrollIntoView) {
setPageToScrollToIndex(value);
@@ -280,16 +289,16 @@ const BaseReaderChapterViewer = ({
}));
}
},
(value) => updatePageState(value, noOp, setTransitionPageMode),
(value) => updateState(value, noOp, setTransitionPageMode),
);
useReaderConvertPagesForReadingMode(
currentPageIndex,
actualPages,
pageUrls,
(value) => updatePageState(value, setPages, setContextPages, true),
(value) => updatePageState(value, setPagesToSpreadState, noOp, true),
(value) => updatePageState(value, noOp, updateCurrentPageIndex),
(value) => updateState(value, setPages, setContextPages, true),
(value) => updateState(value, setPagesToSpreadState, noOp, true),
(value) => updateState(value, noOp, updateCurrentPageIndex),
readingMode,
);
@@ -396,19 +405,20 @@ const BaseReaderChapterViewer = ({
}),
}}
>
<ReaderInfiniteScrollUpdateChapter
readingMode={readingMode}
readingDirection={readingDirection}
chapterId={chapterId}
previousChapterId={previousChapterId}
nextChapterId={nextChapterId}
isCurrentChapter={isCurrentChapter}
isPreviousChapterVisible={isPreviousChapterVisible}
isNextChapterVisible={isNextChapterVisible}
imageWrapper={pagerRef.current}
/>
{((!isContinuousReadingModeActive && isCurrentChapter) ||
(isContinuousReadingModeActive && (isInitialChapter || isLeadingChapter))) && (
{!isPreloadMode && (
<ReaderInfiniteScrollUpdateChapter
readingMode={readingMode}
readingDirection={readingDirection}
chapterId={chapterId}
previousChapterId={previousChapterId}
nextChapterId={nextChapterId}
isCurrentChapter={isCurrentChapter}
isPreviousChapterVisible={isPreviousChapterVisible}
isNextChapterVisible={isNextChapterVisible}
imageWrapper={pagerRef.current}
/>
)}
{showPreviousTransitionPage && (
<ReaderTransitionPage chapterId={chapterId} type={ReaderTransitionPageMode.PREVIOUS} />
)}
<Pager
@@ -436,9 +446,9 @@ const BaseReaderChapterViewer = ({
scrollbarXSize={scrollbarXSize}
scrollbarYSize={scrollbarYSize}
readerNavBarWidth={readerNavBarWidth}
isPreloadMode={isPreloadMode}
/>
{((!isContinuousReadingModeActive && isCurrentChapter) ||
(isContinuousReadingModeActive && (isInitialChapter || isTrailingChapter))) && (
{showNextTransitionPage && (
<ReaderTransitionPage chapterId={chapterId} type={ReaderTransitionPageMode.NEXT} />
)}
</Stack>

View File

@@ -314,6 +314,24 @@ const BaseReaderViewer = forwardRef(
const isNextChapter = chapter.id === chaptersToRender[currentChapterIndex - 1]?.id;
const isLeadingChapter = initialChapter.sourceOrder > chapter.sourceOrder;
const isTrailingChapter = initialChapter.sourceOrder < chapter.sourceOrder;
const isLastLeadingChapter = visibleChapters.lastLeadingChapterSourceOrder === chapter.sourceOrder;
const isLastTrailingChapter =
visibleChapters.lastTrailingChapterSourceOrder === chapter.sourceOrder;
const isPreloadMode =
(isLastLeadingChapter && visibleChapters.isLeadingChapterPreloadMode) ||
(isLastTrailingChapter && visibleChapters.isTrailingChapterPreloadMode);
const isPreviousChapterLoaded = !!chaptersToRender[currentChapterIndex + 1];
const isPreviousChapterLastLeadingChapter = chapterIndex + 1 >= chaptersToRender.length - 1;
const isPreviousChapterPreloading =
isPreviousChapterLastLeadingChapter && visibleChapters.isLeadingChapterPreloadMode;
const isPreviousChapterVisible = isPreviousChapterLoaded && !isPreviousChapterPreloading;
const isNextChapterLoaded = !!chaptersToRender[chapterIndex - 1];
const isNextChapterLastTrailingChapter = chapterIndex - 1 < 0;
const isNextChapterPreloading =
isNextChapterLastTrailingChapter && visibleChapters.isTrailingChapterPreloadMode;
const isNextChapterVisible = isNextChapterLoaded && !isNextChapterPreloading;
return (
<ReaderChapterViewer
@@ -321,8 +339,8 @@ const BaseReaderViewer = forwardRef(
chapterId={chapter.id}
previousChapterId={previousChapter?.id}
nextChapterId={nextChapter?.id}
isPreviousChapterVisible={!!chaptersToRender[chapterIndex + 1]}
isNextChapterVisible={!!chaptersToRender[chapterIndex - 1]}
isPreviousChapterVisible={isPreviousChapterVisible}
isNextChapterVisible={isNextChapterVisible}
lastPageRead={chapter.lastPageRead}
currentPageIndex={getReaderChapterViewerCurrentPageIndex(
currentPageIndex,
@@ -340,6 +358,7 @@ const BaseReaderViewer = forwardRef(
isNextChapter={isNextChapter}
isLeadingChapter={isLeadingChapter}
isTrailingChapter={isTrailingChapter}
isPreloadMode={isPreloadMode}
imageRefs={imageRefs}
setPages={setPages}
setPageLoadStates={setPageLoadStates}

View File

@@ -16,7 +16,7 @@ import { isContinuousReadingMode } from '@/modules/reader/utils/ReaderSettings.u
const BaseBasePager = forwardRef<
HTMLDivElement,
Omit<ReaderPagerProps, 'pageLoadStates' | 'retryFailedPagesKeyPrefix'> &
Omit<ReaderPagerProps, 'pageLoadStates' | 'retryFailedPagesKeyPrefix' | 'isPreloadMode'> &
Pick<IReaderSettings, 'readingMode' | 'imagePreLoadAmount'> & {
createPage: (
page: ReaderStatePages['pages'][number],

View File

@@ -44,7 +44,7 @@ const getPagePosition = (
const BaseReaderDoublePagedPager = forwardRef<
HTMLDivElement,
ReaderPagerProps & Pick<IReaderSettings, 'readingDirection' | 'pageScaleMode'>
>(({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, ...props }, ref) => {
>(({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, isPreloadMode, ...props }, ref) => {
const { currentPageIndex, pages, totalPages, readingDirection, pageScaleMode } = props;
const { direction: themeDirection } = useTheme();
@@ -72,6 +72,7 @@ const BaseReaderDoublePagedPager = forwardRef<
pagesIndex,
true,
pageLoadStates[primary.index].loaded,
isPreloadMode,
onLoad,
onError,
shouldLoad,
@@ -89,6 +90,7 @@ const BaseReaderDoublePagedPager = forwardRef<
pagesIndex,
false,
pageLoadStates[secondary.index].loaded,
isPreloadMode,
onLoad,
onError,
shouldLoad,

View File

@@ -16,7 +16,7 @@ import { createReaderPage } from '@/modules/reader/utils/ReaderPager.utils.tsx';
const BaseReaderHorizontalPager = forwardRef<
HTMLDivElement,
ReaderPagerProps & Pick<IReaderSettings, 'pageGap' | 'readingDirection'>
>(({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, ...props }, ref) => {
>(({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, isPreloadMode, ...props }, ref) => {
const { currentPageIndex, totalPages, pageGap, readingDirection } = props;
const { direction: themeDirection } = useTheme();
@@ -33,10 +33,11 @@ const BaseReaderHorizontalPager = forwardRef<
pagesIndex,
true,
pageLoadStates[page.primary.index].loaded,
isPreloadMode,
onLoad,
onError,
shouldLoad,
true,
!isPreloadMode,
currentPageIndex,
totalPages,
...baseProps,

View File

@@ -12,7 +12,7 @@ import { ReaderPagerProps } from '@/modules/reader/types/Reader.types.ts';
import { createReaderPage } from '@/modules/reader/utils/ReaderPager.utils.tsx';
const BaseReaderPagedPager = forwardRef<HTMLDivElement, ReaderPagerProps>(
({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, ...props }, ref) => {
({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, isPreloadMode, ...props }, ref) => {
const { currentPageIndex, totalPages } = props;
return (
@@ -25,6 +25,7 @@ const BaseReaderPagedPager = forwardRef<HTMLDivElement, ReaderPagerProps>(
pagesIndex,
true,
pageLoadStates[page.primary.index].loaded,
isPreloadMode,
onLoad,
onError,
shouldLoad,

View File

@@ -12,7 +12,7 @@ import { ReaderPagerProps, ReadingMode } from '@/modules/reader/types/Reader.typ
import { createReaderPage } from '@/modules/reader/utils/ReaderPager.utils.tsx';
const BaseReaderVerticalPager = forwardRef<HTMLDivElement, ReaderPagerProps>(
({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, ...props }, ref) => {
({ onLoad, onError, pageLoadStates, retryFailedPagesKeyPrefix, isPreloadMode, ...props }, ref) => {
const { currentPageIndex, totalPages, readingMode, pageGap } = props;
const isWebtoonMode = readingMode === ReadingMode.WEBTOON;
@@ -28,10 +28,11 @@ const BaseReaderVerticalPager = forwardRef<HTMLDivElement, ReaderPagerProps>(
pagesIndex,
true,
pageLoadStates[page.primary.index].loaded,
isPreloadMode,
onLoad,
onError,
shouldLoad,
true,
!isPreloadMode,
currentPageIndex,
totalPages,
...baseProps,