Prevent TypeError and incorrect state updates for "pagesSpreadState"

Page spread state updates of an already closed chapter caused TypeErrors or incorrect state updates.
This commit is contained in:
schroda
2024-12-30 21:02:12 +01:00
parent 7c98bab43b
commit 95f95e770f
4 changed files with 30 additions and 13 deletions

View File

@@ -24,6 +24,7 @@ import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
import {
IReaderSettings,
PageInViewportType,
ReaderPageSpreadState,
ReadingMode,
TReaderScrollbarContext,
} from '@/modules/reader/types/Reader.types.ts';
@@ -131,7 +132,9 @@ const BaseReaderViewer = forwardRef(
const handleClick = ReaderControls.useHandleClick(scrollElementRef.current);
const [pagesToSpreadState, setPagesToSpreadState] = useState(Array(totalPages).fill(false));
const [pagesToSpreadState, setPagesToSpreadState] = useState<ReaderPageSpreadState[]>(
pageLoadStates.map(({ url }) => ({ url, isSpread: false })),
);
const imageRefs = useRef<(HTMLElement | null)[]>(pages.map(() => null));
@@ -194,7 +197,6 @@ const BaseReaderViewer = forwardRef(
useReaderConvertPagesForReadingMode(
currentPageIndex,
totalPages,
actualPages,
pageUrls,
setPages,

View File

@@ -278,3 +278,5 @@ export type TReaderAutoScrollContext = ReturnType<typeof useAutomaticScrolling>
scrollRef?: MutableRefObject<HTMLElement | null> | (() => void);
setScrollRef: (scrollRef?: MutableRefObject<HTMLElement | null>) => void;
};
export type ReaderPageSpreadState = { url: string; isSpread: boolean };

View File

@@ -8,7 +8,12 @@
import { MutableRefObject, useEffect, useLayoutEffect, useRef, useState } from 'react';
import { Direction } from '@mui/material/styles';
import { ReaderResumeMode, ReadingDirection, ReadingMode } from '@/modules/reader/types/Reader.types.ts';
import {
ReaderPageSpreadState,
ReaderResumeMode,
ReadingDirection,
ReadingMode,
} from '@/modules/reader/types/Reader.types.ts';
import { UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
import { TChapterReader } from '@/modules/chapter/Chapter.types.ts';
import { ChapterIdInfo, Chapters } from '@/modules/chapter/services/Chapters.ts';
@@ -125,8 +130,8 @@ export const getChapterIdsForDownloadAhead = (
export const createUpdateReaderPageLoadState =
(
actualPages: ReaderStatePages['pages'],
pagesToSpreadState: boolean[],
setPagesToSpreadState: React.Dispatch<React.SetStateAction<boolean[]>>,
pagesToSpreadState: ReaderPageSpreadState[],
setPagesToSpreadState: React.Dispatch<React.SetStateAction<ReaderPageSpreadState[]>>,
pageLoadStates: ReaderStatePages['pageLoadStates'],
setPageLoadStates: ReaderStatePages['setPageLoadStates'],
readingMode: ReadingMode,
@@ -143,16 +148,22 @@ export const createUpdateReaderPageLoadState =
const img = new Image();
img.onload = () => {
const isSpreadPageFlag = isSpreadPage(img);
if (!isSpreadPageFlag || pagesToSpreadState[index] === isSpreadPageFlag) {
const pageSpreadState = pagesToSpreadState[index];
if (!isSpreadPageFlag || pageSpreadState.isSpread === isSpreadPageFlag) {
return;
}
setPagesToSpreadState((prevState) => {
if (pagesToSpreadState[index] === isSpreadPageFlag) {
const isOfOutdatedSpreadState = prevState[index] === undefined || prevState[index].url !== url;
if (isOfOutdatedSpreadState) {
return prevState;
}
return prevState.toSpliced(index, 1, isSpreadPageFlag);
if (pageSpreadState.isSpread === isSpreadPageFlag) {
return prevState;
}
return prevState.toSpliced(index, 1, { url, isSpread: isSpreadPageFlag });
});
};
img.src = url;
@@ -179,11 +190,10 @@ export const createUpdateReaderPageLoadState =
export const useReaderConvertPagesForReadingMode = (
currentPageIndex: number,
totalPages: number,
actualPages: ReaderStatePages['pages'],
pageUrls: ReaderStatePages['pageUrls'],
setPages: ReaderStatePages['setPages'],
setPagesToSpreadState: (states: boolean[]) => void,
setPagesToSpreadState: (states: ReaderPageSpreadState[]) => void,
updateCurrentPageIndex: ReturnType<typeof ReaderControls.useUpdateCurrentPageIndex>,
readingMode: ReadingMode,
) => {
@@ -193,8 +203,10 @@ export const useReaderConvertPagesForReadingMode = (
const convertPagesToNormalPageMode = wasDoublePageMode && readingMode !== ReadingMode.DOUBLE_PAGE;
if (convertPagesToNormalPageMode) {
setWasDoublePageMode(false);
setPages(createPagesData(pageUrls));
setPagesToSpreadState(Array(totalPages).fill(false));
const newPageData = createPagesData(pageUrls);
setPages(newPageData);
setPagesToSpreadState(newPageData.map(({ primary: { url } }) => ({ url, isSpread: false })));
return;
}

View File

@@ -12,6 +12,7 @@ import {
IReaderSettings,
PageInViewportType,
ReaderPageScaleMode,
ReaderPageSpreadState,
ReaderTransitionPageMode,
ReadingDirection,
ReadingMode,
@@ -366,7 +367,7 @@ export const isEndOfPageInViewport = (
export const getDoublePageModePages = (
pageUrls: ReaderStatePages['pageUrls'],
pagesToSpreadState: boolean[],
pagesToSpreadState: ReaderPageSpreadState[],
shouldOffsetDoubleSpreads: IReaderSettings['shouldOffsetDoubleSpreads'],
direction: ReadingDirection,
): ReaderStatePages['pages'] => {