From bf5f10e3aa6d2210343f2f3a371a0b0792ce97a5 Mon Sep 17 00:00:00 2001 From: Robert Perez Date: Sun, 26 Nov 2023 16:36:22 -0500 Subject: [PATCH 1/4] page loading works and looks good now to make double page work with it --- src/components/reader/DoublePage.tsx | 52 +++++++++++++++-- .../reader/pager/DoublePagedPager.tsx | 56 ++++++++++--------- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/src/components/reader/DoublePage.tsx b/src/components/reader/DoublePage.tsx index 8bd67034b6..d34255c924 100644 --- a/src/components/reader/DoublePage.tsx +++ b/src/components/reader/DoublePage.tsx @@ -6,9 +6,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { forwardRef } from 'react'; +import { forwardRef, useRef } from 'react'; import { Box, styled } from '@mui/material'; import { IReaderSettings } from '@/typings'; +import { SpinnerImage } from '@/components/util/SpinnerImage'; const Image = styled('img')({ marginBottom: 0, @@ -19,15 +20,30 @@ const Image = styled('img')({ objectFit: 'contain', }); +const imgStyles = { + display: 'block', + marginBottom: 0, + width: 'auto', + minHeight: '99vh', + height: 'auto', + maxHeight: '99vh', + objectFit: 'contain', +}; + interface IProps { index: number; image1src: string; image2src: string; + onImageLoad: () => void; settings: IReaderSettings; } export const DoublePage = forwardRef((props: IProps, ref: any) => { - const { image1src, image2src, index, settings } = props; + const { image1src, image2src, index, onImageLoad, settings } = props; + + const imgRef = useRef(null); + + // const imgStyle = imageStyle(settings); return ( { overflowX: 'scroll', }} > - {`Page - {`Page + + ); }); diff --git a/src/components/reader/pager/DoublePagedPager.tsx b/src/components/reader/pager/DoublePagedPager.tsx index 5d6be26e21..fcc7ca4ded 100644 --- a/src/components/reader/pager/DoublePagedPager.tsx +++ b/src/components/reader/pager/DoublePagedPager.tsx @@ -40,26 +40,29 @@ export function DoublePagedPager(props: IReaderProps) { const spreadPage = useRef(Array(pages.length).fill(false)); function setPagesToDisplay() { - pagesDisplayed.current = 0; - if (curPage < pages.length && pagesRef.current[curPage]) { - if (pageLoaded.current[curPage]) { - pagesDisplayed.current = 1; - if (spreadPage.current[curPage]) return; - } - } - if (curPage + 1 < pages.length && pagesRef.current[curPage + 1]) { - if (pageLoaded.current[curPage + 1]) { - if (isSinglePage(curPage, spreadPage.current, settings.offsetFirstPage)) return; - pagesDisplayed.current = 2; - } - } + // pagesDisplayed.current = 0; + // if (curPage < pages.length && pagesRef.current[curPage]) { + // if (pageLoaded.current[curPage]) { + // pagesDisplayed.current = 1; + // if (spreadPage.current[curPage]) return; + // } + // } + // if (curPage + 1 < pages.length && pagesRef.current[curPage + 1]) { + // if (pageLoaded.current[curPage + 1]) { + // if (isSinglePage(curPage, spreadPage.current, settings.offsetFirstPage)) return; + // pagesDisplayed.current = 2; + // } + // } + pagesDisplayed.current = 2; } function displayPages() { + console.log('displaying pages'); const container = document.getElementById('display'); const root = createRoot(container!); if (pagesDisplayed.current === 2) { + console.log('rendering two'); root.render( { - const retryDisplay = setInterval(() => { - const isLastPage = curPage === pages.length - 1; - if ( - (!isLastPage && pageLoaded.current[curPage] && pageLoaded.current[curPage + 1]) || - pageLoaded.current[curPage] - ) { - setPagesToDisplay(); - displayPages(); - clearInterval(retryDisplay); - } - }, 50); + console.log("using effect!") + // const retryDisplay = setInterval(() => { + // const isLastPage = curPage === pages.length - 1; + // if ( + // (!isLastPage && pageLoaded.current[curPage] && pageLoaded.current[curPage + 1]) || + // pageLoaded.current[curPage] + // ) { + // setPagesToDisplay(); + // displayPages(); + // clearInterval(retryDisplay); + // } + // }, 50); + setPagesToDisplay(); + displayPages(); document.addEventListener('keydown', keyboardControl); selfRef.current?.addEventListener('click', clickControl); return () => { - clearInterval(retryDisplay); + // clearInterval(retryDisplay); document.removeEventListener('keydown', keyboardControl); selfRef.current?.removeEventListener('click', clickControl); }; From d13c31044353e3b5434d01338c604f24d4f70a7f Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sun, 14 Jan 2024 21:12:40 +0100 Subject: [PATCH 2/4] Update double page spinner styling --- src/components/reader/DoublePage.tsx | 43 +++++++++------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/components/reader/DoublePage.tsx b/src/components/reader/DoublePage.tsx index d34255c924..41fd16711f 100644 --- a/src/components/reader/DoublePage.tsx +++ b/src/components/reader/DoublePage.tsx @@ -6,21 +6,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { forwardRef, useRef } from 'react'; -import { Box, styled } from '@mui/material'; +import { CSSProperties, forwardRef, useRef } from 'react'; +import { Box, SxProps, Theme } from '@mui/material'; import { IReaderSettings } from '@/typings'; import { SpinnerImage } from '@/components/util/SpinnerImage'; -const Image = styled('img')({ - marginBottom: 0, - width: 'auto', - minHeight: '99vh', - height: 'auto', - maxHeight: '99vh', - objectFit: 'contain', -}); - -const imgStyles = { +const imgStyles: CSSProperties = { display: 'block', marginBottom: 0, width: 'auto', @@ -30,11 +21,17 @@ const imgStyles = { objectFit: 'contain', }; +const spinnerStyle: SxProps = { + ...imgStyles, + width: 'calc((100vw - 300px) * 0.5)', + backgroundColor: '#525252', +}; + interface IProps { index: number; image1src: string; image2src: string; - onImageLoad: () => void; + onImageLoad?: () => void; settings: IReaderSettings; } @@ -43,8 +40,6 @@ export const DoublePage = forwardRef((props: IProps, ref: any) => { const imgRef = useRef(null); - // const imgStyle = imageStyle(settings); - return ( { onImageLoad={onImageLoad} alt={`Page #${index}`} imgRef={imgRef} - spinnerStyle={{ - ...imgStyles, - height: '100vh', - width: '35vw', - padding: '50px 18vw', - backgroundColor: '#525252', - marginBottom: 10, - }} + spinnerStyle={spinnerStyle} imgStyle={imgStyles} /> { alt={`Page #${index + 1}`} imgRef={imgRef} spinnerStyle={{ - ...imgStyles, - height: '100vh', - width: '35vw', - padding: '50px 18vw', - backgroundColor: '#525252', - marginBottom: 10, + ...spinnerStyle, + width: 'calc((100vw - 300px - 5px) * 0.5)', + marginLeft: '5px', }} imgStyle={imgStyles} /> From dd6467768cb07ac7841153fdde49aafc8d037d08 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sun, 14 Jan 2024 22:12:11 +0100 Subject: [PATCH 3/4] Render pages everytime the component gets rendered - remove refs because they do not trigger a rerender - remove initial render interval - remove page rendering via portal During the initial render nothing got rendered (pages or placeholder) because for that to happen, the images had to be loaded. Thus, the loading placeholder never got shown. --- .../reader/pager/DoublePagedPager.tsx | 116 +++++++----------- 1 file changed, 44 insertions(+), 72 deletions(-) diff --git a/src/components/reader/pager/DoublePagedPager.tsx b/src/components/reader/pager/DoublePagedPager.tsx index fcc7ca4ded..f1ff1a1b3b 100644 --- a/src/components/reader/pager/DoublePagedPager.tsx +++ b/src/components/reader/pager/DoublePagedPager.tsx @@ -6,9 +6,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Box } from '@mui/material'; -import { createRoot } from 'react-dom/client'; import { IReaderProps } from '@/typings'; import { Page } from '@/components/reader/Page'; import { DoublePage } from '@/components/reader/DoublePage'; @@ -35,59 +34,30 @@ export function DoublePagedPager(props: IReaderProps) { const selfRef = useRef(null); const pagesRef = useRef([]); - const pagesDisplayed = useRef(0); - const pageLoaded = useRef(Array(pages.length).fill(false)); - const spreadPage = useRef(Array(pages.length).fill(false)); - - function setPagesToDisplay() { - // pagesDisplayed.current = 0; - // if (curPage < pages.length && pagesRef.current[curPage]) { - // if (pageLoaded.current[curPage]) { - // pagesDisplayed.current = 1; - // if (spreadPage.current[curPage]) return; - // } - // } - // if (curPage + 1 < pages.length && pagesRef.current[curPage + 1]) { - // if (pageLoaded.current[curPage + 1]) { - // if (isSinglePage(curPage, spreadPage.current, settings.offsetFirstPage)) return; - // pagesDisplayed.current = 2; - // } - // } - pagesDisplayed.current = 2; - } + const [pagesToSpreadState, setPagesToSpreadState] = useState(Array(pages.length).fill(false)); + const [pagesLoadState, setPagesLoadState] = useState(Array(pages.length).fill(false)); - function displayPages() { - console.log('displaying pages'); - const container = document.getElementById('display'); - const root = createRoot(container!); - - if (pagesDisplayed.current === 2) { - console.log('rendering two'); - root.render( - , - ); - } else { - root.render( - {}} - settings={settings} - />, - ); + function getPagesToDisplay(): number { + let pagesToDisplay = 0; + if (curPage < pages.length && pagesRef.current[curPage]) { + if (pagesLoadState[curPage]) { + pagesToDisplay = 1; + if (pagesToSpreadState[curPage]) return pagesToDisplay; + } + } + if (curPage + 1 < pages.length && pagesRef.current[curPage + 1]) { + if (pagesLoadState[curPage + 1]) { + if (isSinglePage(curPage, pagesToSpreadState, settings.offsetFirstPage)) return pagesToDisplay; + pagesToDisplay = 2; + } } + + return pagesToDisplay; } function pagesToGoBack() { // If previous page is single page, go only one page pack - if (isSinglePage(curPage - 2, spreadPage.current, settings.offsetFirstPage)) { + if (isSinglePage(curPage - 2, pagesToSpreadState, settings.offsetFirstPage)) { return 1; } @@ -97,7 +67,7 @@ export function DoublePagedPager(props: IReaderProps) { function nextPage() { if (curPage < pages.length - 1) { - const nextCurPage = curPage + pagesDisplayed.current; + const nextCurPage = curPage + getPagesToDisplay(); setCurPage(nextCurPage >= pages.length ? pages.length - 1 : nextCurPage); } else if (settings.loadNextOnEnding) { nextChapter(); @@ -156,37 +126,21 @@ export function DoublePagedPager(props: IReaderProps) { function handleImageLoad(index: number) { return () => { - pageLoaded.current[index] = true; + setPagesLoadState((prevState) => prevState.toSpliced(index, 1, true)); const image = pagesRef.current[index]; - spreadPage.current[index] = isSpreadPage(image); + setPagesToSpreadState((prevState) => prevState.toSpliced(index, 1, isSpreadPage(image))); }; } useEffect(() => { - console.log("using effect!") - // const retryDisplay = setInterval(() => { - // const isLastPage = curPage === pages.length - 1; - // if ( - // (!isLastPage && pageLoaded.current[curPage] && pageLoaded.current[curPage + 1]) || - // pageLoaded.current[curPage] - // ) { - // setPagesToDisplay(); - // displayPages(); - // clearInterval(retryDisplay); - // } - // }, 50); - setPagesToDisplay(); - displayPages(); - document.addEventListener('keydown', keyboardControl); selfRef.current?.addEventListener('click', clickControl); return () => { - // clearInterval(retryDisplay); document.removeEventListener('keydown', keyboardControl); selfRef.current?.removeEventListener('click', clickControl); }; - }, [selfRef, curPage, settings.readerType, prevChapter, nextChapter]); + }, [selfRef, curPage, settings.readerType, prevChapter, nextChapter, pagesLoadState, pagesToSpreadState]); useEffect(() => { setCurPage(initialPage); @@ -194,10 +148,10 @@ export function DoublePagedPager(props: IReaderProps) { useEffect(() => { if (settings.offsetFirstPage) { - if (pagesDisplayed.current === 2) { + if (getPagesToDisplay() === 2) { setCurPage(curPage + 1); } - } else if (curPage > 0 && !isSinglePage(curPage - 1, spreadPage.current, settings.offsetFirstPage)) { + } else if (curPage > 0 && !isSinglePage(curPage - 1, pagesToSpreadState, settings.offsetFirstPage)) { setCurPage(curPage - 1); } }, [settings.offsetFirstPage]); @@ -228,7 +182,25 @@ export function DoublePagedPager(props: IReaderProps) { height: 'auto', overflowX: 'scroll', }} - /> + > + {getPagesToDisplay() === 2 ? ( + + ) : ( + {}} + settings={settings} + /> + )} + ); } From 493d8065ec9fdccd2c43ef44a5cbbb9b1a8d769f Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 15 Jan 2024 00:27:40 +0100 Subject: [PATCH 4/4] Enable skipping forward while pages are loading --- src/components/reader/pager/DoublePagedPager.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/reader/pager/DoublePagedPager.tsx b/src/components/reader/pager/DoublePagedPager.tsx index f1ff1a1b3b..5436e9a204 100644 --- a/src/components/reader/pager/DoublePagedPager.tsx +++ b/src/components/reader/pager/DoublePagedPager.tsx @@ -38,7 +38,7 @@ export function DoublePagedPager(props: IReaderProps) { const [pagesLoadState, setPagesLoadState] = useState(Array(pages.length).fill(false)); function getPagesToDisplay(): number { - let pagesToDisplay = 0; + let pagesToDisplay = 1; // has to be at least one so skipping forward while pages are still loading is possible if (curPage < pages.length && pagesRef.current[curPage]) { if (pagesLoadState[curPage]) { pagesToDisplay = 1;