diff --git a/src/modules/reader/components/pager/DoublePagedPager.tsx b/src/modules/reader/components/pager/DoublePagedPager.tsx index 8d613cdb61..262d440d6b 100644 --- a/src/modules/reader/components/pager/DoublePagedPager.tsx +++ b/src/modules/reader/components/pager/DoublePagedPager.tsx @@ -6,7 +6,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { MouseEvent, useEffect, useRef, useState } from 'react'; +import { MouseEvent, useEffect, useMemo, useRef, useState } from 'react'; import Box from '@mui/material/Box'; import { Page } from '@/modules/reader/components/page/Page.tsx'; import { IReaderProps } from '@/modules/reader/Reader.types.ts'; @@ -22,11 +22,17 @@ export function DoublePagedPager(props: IReaderProps) { const selfRef = useRef(null); const pagesToDisplayStateRef = useRef([]); - const pageToPrevSpreadPageRef = useRef([]); const [pagesToSpreadState, setPagesToSpreadState] = useState(Array(pages.length).fill(false)); const [pagesLoadState, setPagesLoadState] = useState(Array(pages.length).fill(false)); + // each spread page has to be counted as 2 pages and all trailing page numbers have to be increased by the count + // of leading spread pages + const pageToActualPageIndex = useMemo( + () => pagesToSpreadState.map((_, page) => page + pagesToSpreadState.slice(0, page).filter(Boolean).length), + [pagesToSpreadState], + ); + function nextPage() { const setNextPage = (page: number) => setCurPage(page === -1 ? pages.length - 1 : page); @@ -131,37 +137,46 @@ export function DoublePagedPager(props: IReaderProps) { }} > {pages.map(({ index, src }) => { - const prevSpreadPage = (() => { - let currentIndexOfPrevSpreadPage = pageToPrevSpreadPageRef.current[curPage]; + /* - if (currentIndexOfPrevSpreadPage === undefined) { - currentIndexOfPrevSpreadPage = Math.max(pagesToSpreadState.lastIndexOf(true, curPage), 0); + | = page separator + + = double page + _ = double spread - const areAllPrevPagesLoaded = pagesLoadState.slice(0, curPage).every(Boolean); - if (areAllPrevPagesLoaded) { - pageToPrevSpreadPageRef.current[curPage] = currentIndexOfPrevSpreadPage; - } - } + without double spreads: + without double spread offset: | 0 + 1 | 2 + 3 | 4 + 5 | 6 + 7 | 8 | + with double spread offset : | 0 | 1 + 2 | 3 + 4 | 5 + 6 | 7 + 8 | - return currentIndexOfPrevSpreadPage > 0 - ? currentIndexOfPrevSpreadPage + 1 - : currentIndexOfPrevSpreadPage; - })(); + with double spreads + to handle double spreads: + each double spread has to count as 2 pages, thus, each page number after a double spread has to increase + by the number of leading double spreads - // index of first page after a spread page will be 0 - const normalizedCurPageIndexForSpreadPages = curPage - prevSpreadPage; + without double spread offset: | 0 + 1 | 2 | _3/4_ | 5 + 6 | 7 + 8 | _9/10_ | 11 + 12 | 13 + 14 | + with double spread offset : | 0 | 1 + 2 | _3/4_ | 5 + 6 | 7 + 8 | _9/10_ | 11 + 12 | 13 + 14 | - const isFirstPage = curPage === 0; - // only offset pages before the first spread page, after the first spread page handle as if "offsetFirstPage" is disabled - const firstPageOffset = - Number(settings.offsetFirstPage) + - Number(settings.offsetFirstPage && !normalizedCurPageIndexForSpreadPages && !isFirstPage); + thus, to get the second page: + without offset: second page = current page number even ? +1 : -1 + with offset : second page = current page number even ? +1 : -1 + + the second page has to be ignored in case: + - double spreads are offset, and the current page is the first page + - either the current or second page is a double spread + */ - const normalizedCurPageIndex = normalizedCurPageIndexForSpreadPages - firstPageOffset; + const normalizedCurPage = pageToActualPageIndex[curPage]; + const isCurPageEven = !(normalizedCurPage % 2); - const isCurPageEven = !(normalizedCurPageIndex % 2); - const secondPage = curPage + (isCurPageEven ? 1 : -1); + const secondPageOffset = (() => { + const invert = settings.offsetFirstPage ? -1 : 1; + const offset = isCurPageEven ? 1 : -1; + return offset * invert; + })(); + + const secondPage = curPage + secondPageOffset; + + const isFirstPage = curPage === 0; const isCurPage = index === curPage; const isSecondPage = index === secondPage; @@ -169,7 +184,9 @@ export function DoublePagedPager(props: IReaderProps) { const isSecondPageSpreadPage = pagesToSpreadState[secondPage]; const hasSpreadPage = isCurrentPageSpreadPage || isSecondPageSpreadPage; - const displaySecondPage = isSecondPage && !hasSpreadPage; + const ignoreSecondPageDueToOffset = isFirstPage && settings.offsetFirstPage; + + const displaySecondPage = isSecondPage && !hasSpreadPage && !ignoreSecondPageDueToOffset; const displayPage = isCurPage || displaySecondPage; pagesToDisplayStateRef.current[index] = displayPage;