diff --git a/src/modules/reader/components/viewer/ReaderPage.tsx b/src/modules/reader/components/viewer/ReaderPage.tsx index e10b0d09..054bf2f4 100644 --- a/src/modules/reader/components/viewer/ReaderPage.tsx +++ b/src/modules/reader/components/viewer/ReaderPage.tsx @@ -24,6 +24,8 @@ import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { useReaderScrollbarContext } from '@/modules/reader/contexts/ReaderScrollbarContext.tsx'; import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx'; import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx'; +import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; +import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts'; const getCustomFilterString = (customFilter: ReaderCustomFilter): string => Object.keys(customFilter) @@ -73,10 +75,12 @@ const BaseReaderPage = ({ onLoad, onError, setRef, + readerNavBarWidth, ...props }: Omit, 'ref' | 'spinnerStyle' | 'imgStyle' | 'onLoad' | 'onError'> & Pick & - Pick & { + Pick & + Pick & { pageIndex: number; pagesIndex: number; isPrimaryPage: boolean; @@ -129,7 +133,15 @@ const BaseReaderPage = ({ ...getImageMarginStyling(doublePage, position), }} imgStyle={{ - ...getReaderImageStyling(readingMode, shouldStretchPage, pageScaleMode, doublePage, readerWidth), + ...getReaderImageStyling( + readingMode, + shouldStretchPage, + pageScaleMode, + doublePage, + readerWidth, + readerNavBarWidth + scrollbarYSize, + scrollbarXSize, + ), display: 'block', ...applyStyles(!display, { display: 'none', @@ -156,7 +168,7 @@ const BaseReaderPage = ({ export const ReaderPage = withPropsFrom( memo(BaseReaderPage), - [ReaderService.useSettingsWithoutDefaultFlag, useReaderScrollbarContext], + [ReaderService.useSettingsWithoutDefaultFlag, useReaderScrollbarContext, useNavBarContext], [ 'readingMode', 'customFilter', @@ -165,5 +177,6 @@ export const ReaderPage = withPropsFrom( 'readerWidth', 'scrollbarXSize', 'scrollbarYSize', + 'readerNavBarWidth', ], ); diff --git a/src/modules/reader/components/viewer/pager/BasePager.tsx b/src/modules/reader/components/viewer/pager/BasePager.tsx index f5cff5fe..b229c544 100644 --- a/src/modules/reader/components/viewer/pager/BasePager.tsx +++ b/src/modules/reader/components/viewer/pager/BasePager.tsx @@ -9,7 +9,7 @@ import { memo, ReactNode, useCallback, useEffect, useMemo, useRef } from 'react'; import Box, { BoxProps } from '@mui/material/Box'; import { ReaderService } from '@/modules/reader/services/ReaderService.ts'; -import { getPageIndexesToLoad, getReaderImageWrapperStyling } from '@/modules/reader/utils/ReaderPager.utils.tsx'; +import { getPageIndexesToLoad } from '@/modules/reader/utils/ReaderPager.utils.tsx'; import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types.ts'; import { IReaderSettings, ReaderPagerProps, ReaderTransitionPageMode } from '@/modules/reader/types/Reader.types.ts'; import { ReaderTransitionPage } from '@/modules/reader/components/viewer/ReaderTransitionPage.tsx'; @@ -23,15 +23,9 @@ const BaseBasePager = ({ createPage, slots, readingMode, - pageScaleMode, - shouldStretchPage, - readerWidth, imagePreLoadAmount, }: Omit & - Pick< - IReaderSettings, - 'readingMode' | 'pageScaleMode' | 'shouldStretchPage' | 'readerWidth' | 'imagePreLoadAmount' - > & { + Pick & { createPage: ( page: ReaderStatePages['pages'][number], pagesIndex: number, @@ -68,10 +62,7 @@ const BaseBasePager = ({ return ( {pages.map((page, pagesIndex) => @@ -91,5 +82,5 @@ const BaseBasePager = ({ export const BasePager = withPropsFrom( memo(BaseBasePager), [ReaderService.useSettingsWithoutDefaultFlag], - ['readingMode', 'pageScaleMode', 'shouldStretchPage', 'readerWidth', 'imagePreLoadAmount'], + ['readingMode', 'imagePreLoadAmount'], ); diff --git a/src/modules/reader/components/viewer/pager/ReaderDoublePagedPager.tsx b/src/modules/reader/components/viewer/pager/ReaderDoublePagedPager.tsx index c2142a6d..3ab43c2d 100644 --- a/src/modules/reader/components/viewer/pager/ReaderDoublePagedPager.tsx +++ b/src/modules/reader/components/viewer/pager/ReaderDoublePagedPager.tsx @@ -10,7 +10,12 @@ import { Direction, useTheme } from '@mui/material/styles'; import { Fragment, memo, useMemo } from 'react'; import { BasePager } from '@/modules/reader/components/viewer/pager/BasePager.tsx'; import { ReaderService } from '@/modules/reader/services/ReaderService.ts'; -import { IReaderSettings, ReaderPagerProps, ReadingDirection } from '@/modules/reader/types/Reader.types.ts'; +import { + IReaderSettings, + ReaderPagerProps, + ReaderPageScaleMode, + ReadingDirection, +} from '@/modules/reader/types/Reader.types.ts'; import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { createReaderPage } from '@/modules/reader/utils/ReaderPager.utils.tsx'; import { getNextIndexFromPage, getPage } from '@/modules/reader/utils/ReaderProgressBar.utils.tsx'; @@ -44,8 +49,9 @@ const BaseReaderDoublePagedPager = ({ pageLoadStates, retryFailedPagesKeyPrefix, readingDirection, + pageScaleMode, ...props -}: ReaderPagerProps & Pick) => { +}: ReaderPagerProps & Pick) => { const { currentPageIndex, pages, totalPages } = props; const { direction: themeDirection } = useTheme(); @@ -102,7 +108,13 @@ const BaseReaderDoublePagedPager = ({ slots={{ boxProps: { sx: { - margin: 'auto', + ...applyStyles(pageScaleMode === ReaderPageScaleMode.ORIGINAL, { + margin: 'auto', + }), + width: '100%', + minWidth: 'fit-content', + height: '100%', + minHeight: 'fit-content', display: 'flex', flexDirection: 'row', flexWrap: 'nowrap', @@ -122,5 +134,5 @@ const BaseReaderDoublePagedPager = ({ export const ReaderDoublePagedPager = withPropsFrom( memo(BaseReaderDoublePagedPager), [ReaderService.useSettingsWithoutDefaultFlag], - ['readingDirection'], + ['readingDirection', 'pageScaleMode'], ); diff --git a/src/modules/reader/utils/ReaderPager.utils.tsx b/src/modules/reader/utils/ReaderPager.utils.tsx index b2a4695c..e3d21366 100644 --- a/src/modules/reader/utils/ReaderPager.utils.tsx +++ b/src/modules/reader/utils/ReaderPager.utils.tsx @@ -38,20 +38,22 @@ const getPageWidth = ( pageScaleMode: IReaderSettings['pageScaleMode'], isDoublePage: boolean, readerWidth: IReaderSettings['readerWidth'], - shouldStretchPage: IReaderSettings['shouldStretchPage'], isImage: boolean, ): string => { - // only return 50% in case pages should get stretched, otherwise, pages might unintentionally shrink in size (e.g. 2 pages with different dimensions, the bigger page will shrink due to taking up more than 50%) - if (isImage && isDoublePage && shouldStretchPage) { - return '50%'; + if (shouldApplyReaderWidth(readerWidth, pageScaleMode)) { + const width = readerWidth.value; + if (isImage && isDoublePage) { + return `${width / 2}vw`; + } + + return `${width}vw`; } - // the image wrapper gets applied the reader width limit and therefore the images can take up 100% - if (!isImage && shouldApplyReaderWidth(readerWidth, pageScaleMode)) { - return `${readerWidth?.value}%`; + if (isImage && isDoublePage) { + return `50vw`; } - return '100%'; + return `100vw`; }; export const getImagePlaceholderStyling = ( @@ -142,7 +144,13 @@ const getReaderDimensionStyling = ( readingMode: IReaderSettings['readingMode'], shouldStretchPage: IReaderSettings['shouldStretchPage'], pageScaleMode: IReaderSettings['pageScaleMode'], + widthOffset: number, + heightOffset: number, ): CSSObject => { + const finalWidthOffset = readingMode === ReadingMode.DOUBLE_PAGE ? widthOffset / 2 : widthOffset; + const fullWidth = `calc(${width} - ${finalWidthOffset}px)`; + const fullHeight = `calc(100vh - ${heightOffset}px)`; + switch (pageScaleMode) { case ReaderPageScaleMode.WIDTH: return { @@ -151,9 +159,9 @@ const getReaderDimensionStyling = ( minWidth: 'unset', }), ...applyStyles(shouldStretchPage, { - minWidth: width, + minWidth: fullWidth, }), - maxWidth: width, + maxWidth: fullWidth, }; case ReaderPageScaleMode.HEIGHT: return { @@ -162,9 +170,9 @@ const getReaderDimensionStyling = ( minHeight: 'unset', }), ...applyStyles(shouldStretchPage, { - minHeight: '100%', + minHeight: fullHeight, }), - maxHeight: `100%`, + maxHeight: fullHeight, }; case ReaderPageScaleMode.SCREEN: return { @@ -175,19 +183,19 @@ const getReaderDimensionStyling = ( minHeight: 'unset', }), ...applyStyles(shouldStretchPage, { - minWidth: width, - minHeight: '100%', + minWidth: fullWidth, + minHeight: fullHeight, ...applyStyles(readingMode === ReadingMode.CONTINUOUS_HORIZONTAL, { minWidth: 'unset', - minHeight: '100%', + minHeight: fullHeight, }), ...applyStyles(isContinuousVerticalReadingMode(readingMode), { - minWidth: width, + minWidth: fullWidth, minHeight: 'unset', }), }), - maxWidth: width, - maxHeight: `100%`, + maxWidth: fullWidth, + maxHeight: fullHeight, }; case ReaderPageScaleMode.ORIGINAL: return {}; @@ -196,56 +204,25 @@ const getReaderDimensionStyling = ( } }; -export const getReaderImageWrapperStyling = ( - readingMode: IReaderSettings['readingMode'], - shouldStretchPage: IReaderSettings['shouldStretchPage'], - pageScaleMode: IReaderSettings['pageScaleMode'], - readerWidth: IReaderSettings['readerWidth'], -): CSSObject => { - const width = getPageWidth(pageScaleMode, false, readerWidth, shouldStretchPage, false); - const readerImageStyling = getReaderDimensionStyling(width, readingMode, shouldStretchPage, pageScaleMode); - - switch (pageScaleMode) { - case ReaderPageScaleMode.WIDTH: - case ReaderPageScaleMode.SCREEN: - return { - ...readerImageStyling, - ...applyStyles(shouldStretchPage, { - width: '100%', - }), - // setting the "width" of the wrapper is required for being able to properly size the image placeholders - ...applyStyles(shouldApplyReaderWidth(readerWidth, pageScaleMode), { - width, - }), - }; - case ReaderPageScaleMode.HEIGHT: - case ReaderPageScaleMode.ORIGINAL: - return { - ...readerImageStyling, - }; - default: - throw new Error(`Unexpected "PageScaleMode" (${pageScaleMode})`); - } -}; - export const getReaderImageStyling = ( readingMode: IReaderSettings['readingMode'], shouldStretchPage: IReaderSettings['shouldStretchPage'], pageScaleMode: IReaderSettings['pageScaleMode'], isDoublePage: boolean, readerWidth: IReaderSettings['readerWidth'], + widthOffset: number, + heightOffset: number, ): CSSObject => { - const width = getPageWidth(pageScaleMode, isDoublePage, readerWidth, shouldStretchPage, true); - return getReaderDimensionStyling(width, readingMode, shouldStretchPage, pageScaleMode); + const width = getPageWidth(pageScaleMode, isDoublePage, readerWidth, true); + return getReaderDimensionStyling(width, readingMode, shouldStretchPage, pageScaleMode, widthOffset, heightOffset); }; export const getImageMarginStyling = (doublePage: boolean, objectFitPosition?: 'left' | 'right'): CSSObject => ({ m: 'auto', ...applyStyles(doublePage, { - m: 'unset', - // the applied margin is the opposite of the objectFitPosition - ...applyStyles(objectFitPosition === 'right', { ml: 'auto ' }), - ...applyStyles(objectFitPosition === 'left', { mr: 'auto ' }), + // the margin on the object fit position needs to be removed so that there is no space between both images + ...applyStyles(objectFitPosition === 'right', { mr: 'unset ' }), + ...applyStyles(objectFitPosition === 'left', { ml: 'unset ' }), }), });