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 { import {
IReaderSettings, IReaderSettings,
PageInViewportType, PageInViewportType,
ReaderPageSpreadState,
ReadingMode, ReadingMode,
TReaderScrollbarContext, TReaderScrollbarContext,
} from '@/modules/reader/types/Reader.types.ts'; } from '@/modules/reader/types/Reader.types.ts';
@@ -131,7 +132,9 @@ const BaseReaderViewer = forwardRef(
const handleClick = ReaderControls.useHandleClick(scrollElementRef.current); 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)); const imageRefs = useRef<(HTMLElement | null)[]>(pages.map(() => null));
@@ -194,7 +197,6 @@ const BaseReaderViewer = forwardRef(
useReaderConvertPagesForReadingMode( useReaderConvertPagesForReadingMode(
currentPageIndex, currentPageIndex,
totalPages,
actualPages, actualPages,
pageUrls, pageUrls,
setPages, setPages,

View File

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

View File

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