Convert reader image placeholder styling to vw/vh
This commit is contained in:
@@ -76,6 +76,7 @@ const BaseReaderPage = ({
|
|||||||
onError,
|
onError,
|
||||||
setRef,
|
setRef,
|
||||||
readerNavBarWidth,
|
readerNavBarWidth,
|
||||||
|
isLoaded,
|
||||||
...props
|
...props
|
||||||
}: Omit<ComponentProps<typeof SpinnerImage>, 'ref' | 'spinnerStyle' | 'imgStyle' | 'onLoad' | 'onError'> &
|
}: Omit<ComponentProps<typeof SpinnerImage>, 'ref' | 'spinnerStyle' | 'imgStyle' | 'onLoad' | 'onError'> &
|
||||||
Pick<IReaderSettings, 'readingMode' | 'customFilter' | 'pageScaleMode' | 'shouldStretchPage' | 'readerWidth'> &
|
Pick<IReaderSettings, 'readingMode' | 'customFilter' | 'pageScaleMode' | 'shouldStretchPage' | 'readerWidth'> &
|
||||||
@@ -91,6 +92,7 @@ const BaseReaderPage = ({
|
|||||||
onLoad: ReaderPagerProps['onLoad'];
|
onLoad: ReaderPagerProps['onLoad'];
|
||||||
onError: ReaderPagerProps['onError'];
|
onError: ReaderPagerProps['onError'];
|
||||||
setRef?: (pagesIndex: number, ref: HTMLElement | null) => void;
|
setRef?: (pagesIndex: number, ref: HTMLElement | null) => void;
|
||||||
|
isLoaded?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const { src } = props;
|
const { src } = props;
|
||||||
|
|
||||||
@@ -122,8 +124,8 @@ const BaseReaderPage = ({
|
|||||||
shouldStretchPage,
|
shouldStretchPage,
|
||||||
pageScaleMode,
|
pageScaleMode,
|
||||||
readerWidth,
|
readerWidth,
|
||||||
|
readerNavBarWidth + scrollbarYSize,
|
||||||
scrollbarXSize,
|
scrollbarXSize,
|
||||||
scrollbarYSize,
|
|
||||||
doublePage,
|
doublePage,
|
||||||
isTabletWidth,
|
isTabletWidth,
|
||||||
),
|
),
|
||||||
@@ -142,10 +144,6 @@ const BaseReaderPage = ({
|
|||||||
readerNavBarWidth + scrollbarYSize,
|
readerNavBarWidth + scrollbarYSize,
|
||||||
scrollbarXSize,
|
scrollbarXSize,
|
||||||
),
|
),
|
||||||
display: 'block',
|
|
||||||
...applyStyles(!display, {
|
|
||||||
display: 'none',
|
|
||||||
}),
|
|
||||||
filter: getCustomFilterString(customFilter),
|
filter: getCustomFilterString(customFilter),
|
||||||
objectFit: 'contain',
|
objectFit: 'contain',
|
||||||
objectPosition: position,
|
objectPosition: position,
|
||||||
@@ -154,6 +152,13 @@ const BaseReaderPage = ({
|
|||||||
...applyStyles(marginTop !== undefined, {
|
...applyStyles(marginTop !== undefined, {
|
||||||
mt: `${marginTop}px`,
|
mt: `${marginTop}px`,
|
||||||
}),
|
}),
|
||||||
|
display: 'block',
|
||||||
|
...applyStyles(!display, {
|
||||||
|
display: 'none',
|
||||||
|
}),
|
||||||
|
...applyStyles(!isLoaded, {
|
||||||
|
margin: 'unset',
|
||||||
|
}),
|
||||||
}}
|
}}
|
||||||
hideImgStyle={{
|
hideImgStyle={{
|
||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ const BaseReaderDoublePagedPager = ({
|
|||||||
page,
|
page,
|
||||||
pagesIndex,
|
pagesIndex,
|
||||||
true,
|
true,
|
||||||
|
pageLoadStates[primary.index].loaded,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
shouldLoad,
|
shouldLoad,
|
||||||
@@ -92,6 +93,7 @@ const BaseReaderDoublePagedPager = ({
|
|||||||
{ ...page, primary: { ...page.secondary! } },
|
{ ...page, primary: { ...page.secondary! } },
|
||||||
pagesIndex,
|
pagesIndex,
|
||||||
false,
|
false,
|
||||||
|
pageLoadStates[secondary.index].loaded,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
shouldLoad,
|
shouldLoad,
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const BaseReaderHorizontalPager = ({
|
|||||||
page,
|
page,
|
||||||
pagesIndex,
|
pagesIndex,
|
||||||
true,
|
true,
|
||||||
|
pageLoadStates[page.primary.index].loaded,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
shouldLoad,
|
shouldLoad,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const BaseReaderPagedPager = ({
|
|||||||
page,
|
page,
|
||||||
pagesIndex,
|
pagesIndex,
|
||||||
true,
|
true,
|
||||||
|
pageLoadStates[page.primary.index].loaded,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
shouldLoad,
|
shouldLoad,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const BaseReaderVerticalPager = ({
|
|||||||
page,
|
page,
|
||||||
pagesIndex,
|
pagesIndex,
|
||||||
true,
|
true,
|
||||||
|
pageLoadStates[page.primary.index].loaded,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
shouldLoad,
|
shouldLoad,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
} from '@/modules/reader/types/Reader.types.ts';
|
} from '@/modules/reader/types/Reader.types.ts';
|
||||||
import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts';
|
import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts';
|
||||||
import {
|
import {
|
||||||
|
getSetReaderWidth,
|
||||||
isContinuousReadingMode,
|
isContinuousReadingMode,
|
||||||
isContinuousVerticalReadingMode,
|
isContinuousVerticalReadingMode,
|
||||||
shouldApplyReaderWidth,
|
shouldApplyReaderWidth,
|
||||||
@@ -31,6 +32,7 @@ import { getPage } from '@/modules/reader/utils/ReaderProgressBar.utils.tsx';
|
|||||||
import { DirectionOffset } from '@/Base.types.ts';
|
import { DirectionOffset } from '@/Base.types.ts';
|
||||||
import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts';
|
import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts';
|
||||||
import { READING_DIRECTION_TO_THEME_DIRECTION } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
import { READING_DIRECTION_TO_THEME_DIRECTION } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
|
||||||
|
import { coerceIn } from '@/lib/HelperFunctions.ts';
|
||||||
|
|
||||||
type CSSObject = ReturnType<Theme['applyStyles']>;
|
type CSSObject = ReturnType<Theme['applyStyles']>;
|
||||||
|
|
||||||
@@ -61,53 +63,69 @@ export const getImagePlaceholderStyling = (
|
|||||||
shouldStretchPage: IReaderSettings['shouldStretchPage'],
|
shouldStretchPage: IReaderSettings['shouldStretchPage'],
|
||||||
pageScaleMode: IReaderSettings['pageScaleMode'],
|
pageScaleMode: IReaderSettings['pageScaleMode'],
|
||||||
readerWidth: IReaderSettings['readerWidth'],
|
readerWidth: IReaderSettings['readerWidth'],
|
||||||
scrollbarXSize: number,
|
widthOffset: number,
|
||||||
scrollbarYSize: number,
|
heightOffset: number,
|
||||||
isDoublePage?: boolean,
|
isDoublePage?: boolean,
|
||||||
isTabletWidth?: boolean,
|
isTabletWidth?: boolean,
|
||||||
): CSSObject => {
|
): CSSObject => {
|
||||||
const DEFAULT_SINGLE_PAGE_WIDTH = isTabletWidth ? '100vw' : '40vw';
|
const OVER_9000 = 9000;
|
||||||
const DEFAULT_SINGLE_PAGE_HEIGHT = isTabletWidth ? '100vh' : '85vh';
|
|
||||||
|
const getMaxWidth = (width: string) => {
|
||||||
|
if (width === '100vw') {
|
||||||
|
return `calc(${width} - ${widthOffset}px)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return width;
|
||||||
|
};
|
||||||
|
const getDesktopWidth = (width: number, readerWidthValue?: number) =>
|
||||||
|
getMaxWidth(`${coerceIn(readerWidthValue ?? width, Math.min(width, readerWidthValue ?? OVER_9000), width)}vw`);
|
||||||
|
|
||||||
|
const setReaderWidth = getSetReaderWidth(readerWidth, pageScaleMode);
|
||||||
|
const fullWidth = getMaxWidth(`${Math.min(100, setReaderWidth ?? OVER_9000)}vw`);
|
||||||
|
const fullHeight = `calc(100vh - ${heightOffset}px)`;
|
||||||
|
|
||||||
|
const DEFAULT_SINGLE_PAGE_WIDTH = isTabletWidth ? fullWidth : getDesktopWidth(40, setReaderWidth);
|
||||||
|
const DEFAULT_SINGLE_PAGE_HEIGHT = isTabletWidth ? fullHeight : '85vh';
|
||||||
|
|
||||||
const READING_MODE_TO_PLACEHOLDER_SIZE: Record<ReadingMode, { minWidth: string; minHeight: string }> = {
|
const READING_MODE_TO_PLACEHOLDER_SIZE: Record<ReadingMode, { minWidth: string; minHeight: string }> = {
|
||||||
[ReadingMode.SINGLE_PAGE]: { minWidth: DEFAULT_SINGLE_PAGE_WIDTH, minHeight: DEFAULT_SINGLE_PAGE_HEIGHT },
|
[ReadingMode.SINGLE_PAGE]: { minWidth: DEFAULT_SINGLE_PAGE_WIDTH, minHeight: DEFAULT_SINGLE_PAGE_HEIGHT },
|
||||||
[ReadingMode.DOUBLE_PAGE]: { minWidth: isTabletWidth ? '50vw' : '35vw', minHeight: DEFAULT_SINGLE_PAGE_HEIGHT },
|
[ReadingMode.DOUBLE_PAGE]: {
|
||||||
|
minWidth: isTabletWidth ? '50vw' : getDesktopWidth(35, setReaderWidth ? setReaderWidth / 2 : undefined),
|
||||||
|
minHeight: DEFAULT_SINGLE_PAGE_HEIGHT,
|
||||||
|
},
|
||||||
[ReadingMode.CONTINUOUS_VERTICAL]: {
|
[ReadingMode.CONTINUOUS_VERTICAL]: {
|
||||||
minWidth: `calc(${DEFAULT_SINGLE_PAGE_WIDTH} - ${scrollbarYSize}px)`,
|
minWidth: DEFAULT_SINGLE_PAGE_WIDTH,
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
},
|
},
|
||||||
[ReadingMode.CONTINUOUS_HORIZONTAL]: {
|
[ReadingMode.CONTINUOUS_HORIZONTAL]: {
|
||||||
minWidth: DEFAULT_SINGLE_PAGE_WIDTH,
|
minWidth: DEFAULT_SINGLE_PAGE_WIDTH,
|
||||||
minHeight: `calc(${DEFAULT_SINGLE_PAGE_HEIGHT} - ${scrollbarXSize}px)`,
|
minHeight: DEFAULT_SINGLE_PAGE_HEIGHT,
|
||||||
},
|
},
|
||||||
[ReadingMode.WEBTOON]: {
|
[ReadingMode.WEBTOON]: {
|
||||||
minWidth: `calc(${DEFAULT_SINGLE_PAGE_WIDTH} - ${scrollbarYSize}px)`,
|
minWidth: DEFAULT_SINGLE_PAGE_WIDTH,
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const defaultStyling = READING_MODE_TO_PLACEHOLDER_SIZE[readingMode];
|
const defaultStyling = {
|
||||||
const minWidthForStretch = isDoublePage ? '50%' : '100%';
|
...READING_MODE_TO_PLACEHOLDER_SIZE[readingMode],
|
||||||
|
// the SpinnerImage placeholder has a default height of 100%, this causes the placeholder to take always take up 100% of the viewport
|
||||||
|
height: 'unset',
|
||||||
|
};
|
||||||
|
const minWidthForStretch = isDoublePage ? `calc(${getMaxWidth(`${setReaderWidth ?? 100}vw`)} / 2)` : fullWidth;
|
||||||
|
|
||||||
switch (pageScaleMode) {
|
switch (pageScaleMode) {
|
||||||
case ReaderPageScaleMode.WIDTH:
|
case ReaderPageScaleMode.WIDTH:
|
||||||
return {
|
return {
|
||||||
...defaultStyling,
|
...defaultStyling,
|
||||||
...applyStyles(shouldApplyReaderWidth(readerWidth, pageScaleMode), {
|
|
||||||
minWidth: minWidthForStretch,
|
|
||||||
}),
|
|
||||||
...applyStyles(shouldStretchPage, {
|
...applyStyles(shouldStretchPage, {
|
||||||
minWidth: minWidthForStretch,
|
minWidth: minWidthForStretch,
|
||||||
}),
|
}),
|
||||||
// the SpinnerImage placeholder has a default height of 100%, this caused the placeholder due take up 100% of the readers full scrollable height instead of only 100% of the viewport
|
|
||||||
...applyStyles(isContinuousVerticalReadingMode(readingMode), {
|
|
||||||
height: 'unset',
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
case ReaderPageScaleMode.HEIGHT:
|
case ReaderPageScaleMode.HEIGHT:
|
||||||
return {
|
return {
|
||||||
...defaultStyling,
|
...defaultStyling,
|
||||||
...applyStyles(shouldStretchPage, {
|
...applyStyles(shouldStretchPage, {
|
||||||
minHeight: `calc(100vh - ${scrollbarXSize}px)`,
|
minHeight: fullHeight,
|
||||||
...applyStyles(isContinuousVerticalReadingMode(readingMode), {
|
...applyStyles(isContinuousVerticalReadingMode(readingMode), {
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
}),
|
}),
|
||||||
@@ -116,12 +134,9 @@ export const getImagePlaceholderStyling = (
|
|||||||
case ReaderPageScaleMode.SCREEN:
|
case ReaderPageScaleMode.SCREEN:
|
||||||
return {
|
return {
|
||||||
...defaultStyling,
|
...defaultStyling,
|
||||||
...applyStyles(shouldApplyReaderWidth(readerWidth, pageScaleMode), {
|
|
||||||
minWidth: minWidthForStretch,
|
|
||||||
}),
|
|
||||||
...applyStyles(shouldStretchPage, {
|
...applyStyles(shouldStretchPage, {
|
||||||
minWidth: minWidthForStretch,
|
minWidth: minWidthForStretch,
|
||||||
minHeight: `calc(100vh - ${scrollbarXSize}px)`,
|
minHeight: fullHeight,
|
||||||
...applyStyles(isContinuousVerticalReadingMode(readingMode), {
|
...applyStyles(isContinuousVerticalReadingMode(readingMode), {
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
}),
|
}),
|
||||||
@@ -264,6 +279,7 @@ export const createReaderPage = (
|
|||||||
{ primary: { index, alt, url } }: ReaderStatePages['pages'][number],
|
{ primary: { index, alt, url } }: ReaderStatePages['pages'][number],
|
||||||
pagesIndex: number,
|
pagesIndex: number,
|
||||||
isPrimaryPage: boolean,
|
isPrimaryPage: boolean,
|
||||||
|
isLoaded: boolean,
|
||||||
onLoad: ComponentProps<typeof ReaderPage>['onLoad'],
|
onLoad: ComponentProps<typeof ReaderPage>['onLoad'],
|
||||||
onError: ComponentProps<typeof ReaderPage>['onError'],
|
onError: ComponentProps<typeof ReaderPage>['onError'],
|
||||||
shouldLoad: boolean,
|
shouldLoad: boolean,
|
||||||
@@ -293,6 +309,7 @@ export const createReaderPage = (
|
|||||||
shouldLoad={shouldLoad}
|
shouldLoad={shouldLoad}
|
||||||
retryKeyPrefix={retryKeyPrefix}
|
retryKeyPrefix={retryKeyPrefix}
|
||||||
marginTop={marginTop}
|
marginTop={marginTop}
|
||||||
|
isLoaded={isLoaded}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,17 @@ export const shouldApplyReaderWidth = (
|
|||||||
pageScaleMode: IReaderSettings['pageScaleMode'],
|
pageScaleMode: IReaderSettings['pageScaleMode'],
|
||||||
): boolean => !!readerWidth?.enabled && isReaderWidthEditable(pageScaleMode);
|
): boolean => !!readerWidth?.enabled && isReaderWidthEditable(pageScaleMode);
|
||||||
|
|
||||||
|
export const getSetReaderWidth = (
|
||||||
|
readerWidth: IReaderSettings['readerWidth'] | undefined,
|
||||||
|
pageScaleMode: IReaderSettings['pageScaleMode'],
|
||||||
|
): number | undefined => {
|
||||||
|
if (!shouldApplyReaderWidth(readerWidth, pageScaleMode)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return readerWidth?.value;
|
||||||
|
};
|
||||||
|
|
||||||
export const isContinuousReadingMode = (readingMode: IReaderSettings['readingMode']): boolean =>
|
export const isContinuousReadingMode = (readingMode: IReaderSettings['readingMode']): boolean =>
|
||||||
[ReadingMode.CONTINUOUS_VERTICAL, ReadingMode.CONTINUOUS_HORIZONTAL, ReadingMode.WEBTOON].includes(readingMode);
|
[ReadingMode.CONTINUOUS_VERTICAL, ReadingMode.CONTINUOUS_HORIZONTAL, ReadingMode.WEBTOON].includes(readingMode);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user