From 19f2d9934543fa288ef9f542b1e68a87ad3fae97 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Wed, 5 Feb 2025 00:34:44 +0100 Subject: [PATCH] Center "ReaderChapterViewers" The viewers can have different sizes which caused theme to not be properly centered. E.g. for the "vertical mode" in case "chapter 1" is greater in width than "chapter 2", the pages of "chapter 2" were not correctly centered due to the "viewers" having different widths. --- .../components/viewer/ReaderChapterViewer.tsx | 26 +++++++++++++++++ .../reader/components/viewer/ReaderViewer.tsx | 28 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/modules/reader/components/viewer/ReaderChapterViewer.tsx b/src/modules/reader/components/viewer/ReaderChapterViewer.tsx index 6e907268..346cb59e 100644 --- a/src/modules/reader/components/viewer/ReaderChapterViewer.tsx +++ b/src/modules/reader/components/viewer/ReaderChapterViewer.tsx @@ -46,6 +46,7 @@ import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder import { getErrorMessage, noOp } from '@/lib/HelperFunctions.ts'; import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx'; import { ReaderInfiniteScrollUpdateChapter } from '@/modules/reader/components/viewer/ReaderInfiniteScrollUpdateChapter.tsx'; +import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx'; const BaseReaderChapterViewer = ({ currentPageIndex, @@ -86,6 +87,9 @@ const BaseReaderChapterViewer = ({ scrollbarXSize, scrollbarYSize, readerNavBarWidth, + onSizeChange, + minWidth, + minHeight, }: Pick< ReaderStatePages, | 'currentPageIndex' @@ -120,6 +124,9 @@ const BaseReaderChapterViewer = ({ imageRefs: MutableRefObject<(HTMLElement | null)[]>; scrollIntoView: boolean; resumeMode: ReaderResumeMode; + onSizeChange: (width: number, height: number) => void; + minWidth: number; + minHeight: number; }) => { const { t } = useTranslation(); const { direction: themeDirection } = useTheme(); @@ -139,6 +146,7 @@ const BaseReaderChapterViewer = ({ pageLoadStates.map(({ url }) => ({ url, isSpread: false })), ); + const ref = useRef(null); const isCurrentChapterRef = useRef(isCurrentChapter); const imageRefs = useRef<(HTMLElement | null)[]>(pages.map(() => null)); @@ -220,6 +228,17 @@ const BaseReaderChapterViewer = ({ doFetchPages(); }, [chapterId]); + useResizeObserver( + ref, + useCallback( + (entries) => { + const { clientWidth, clientHeight } = entries[0].target; + onSizeChange(clientWidth, clientHeight); + }, + [onSizeChange, ref.current], + ), + ); + const updatePageState = ( value: T, setLocalState: (value: T) => void, @@ -343,9 +362,16 @@ const BaseReaderChapterViewer = ({ return ( (pages.map(() => null)); + const chapterViewerSize = useRef({ minChapterViewWidth: 0, minChapterViewHeight: 0 }); + const { minChapterViewWidth, minChapterViewHeight } = chapterViewerSize.current; + + const [, setTriggerReRender] = useState({}); const inViewportType = READING_MODE_TO_IN_VIEWPORT_TYPE[readingMode]; const isLtrReadingDirection = readingDirection === ReadingDirection.LTR; @@ -200,6 +206,25 @@ const BaseReaderViewer = forwardRef( [currentChapter, chaptersToRender], ); + const onChapterViewSizeChange = useCallback( + (width: number, height: number) => { + if (!isContinuousReadingModeActive) { + return; + } + + if (isContinuousVerticalReadingModeActive && minChapterViewWidth < width) { + chapterViewerSize.current.minChapterViewWidth = width; + setTriggerReRender({}); + } + + if (minChapterViewHeight < height) { + chapterViewerSize.current.minChapterViewHeight = height; + setTriggerReRender({}); + } + }, + [isContinuousReadingModeActive, isContinuousVerticalReadingModeActive], + ); + useReaderHandlePageSelection( pageToScrollToIndex, currentPageIndex, @@ -342,6 +367,9 @@ const BaseReaderViewer = forwardRef( scrollbarXSize={scrollbarXSize} scrollbarYSize={scrollbarYSize} readerNavBarWidth={readerNavBarWidth} + onSizeChange={onChapterViewSizeChange} + minWidth={minChapterViewWidth} + minHeight={minChapterViewHeight} /> ); })}