Improve memoization of "MobileReaderProgressBar"

This commit is contained in:
schroda
2024-12-26 01:41:36 +01:00
parent 635f294184
commit a2ac2971f6
4 changed files with 125 additions and 131 deletions

View File

@@ -49,7 +49,7 @@ const BaseReaderBottomBarMobile = ({
return ( return (
<> <>
<Slide direction="up" in={isVisible} mountOnEnter unmountOnExit> <Slide direction="up" in={isVisible}>
<Stack <Stack
sx={{ sx={{
position: 'fixed', position: 'fixed',

View File

@@ -8,25 +8,22 @@
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import Tooltip from '@mui/material/Tooltip'; import Tooltip from '@mui/material/Tooltip';
import { ReactNode } from 'react'; import { memo, ReactNode } from 'react';
import { ReaderProgressBarSlotProps } from '@/modules/reader/types/ReaderProgressBar.types.ts'; import { ReaderProgressBarSlotProps } from '@/modules/reader/types/ReaderProgressBar.types.ts';
import { READER_PROGRESS_BAR_POSITION_TO_PLACEMENT } from '@/modules/reader/constants/ReaderSettings.constants.tsx'; import { READER_PROGRESS_BAR_POSITION_TO_PLACEMENT } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
export const ReaderProgressBarSlot = ({ export const ReaderProgressBarSlot = memo(
pageName, ({ pageName, progressBarPosition, slotProps, children }: ReaderProgressBarSlotProps & { children?: ReactNode }) => (
progressBarPosition, <Tooltip
slotProps, {...slotProps?.tooltip}
children, key={pageName}
}: ReaderProgressBarSlotProps & { children?: ReactNode }) => ( title={pageName}
<Tooltip placement={READER_PROGRESS_BAR_POSITION_TO_PLACEMENT[progressBarPosition]}
{...slotProps?.tooltip} >
key={pageName} <Box {...slotProps?.box} sx={{ width: '100%', height: '100%', ...slotProps?.box?.sx }}>
title={pageName} {children}
placement={READER_PROGRESS_BAR_POSITION_TO_PLACEMENT[progressBarPosition]} </Box>
> </Tooltip>
<Box {...slotProps?.box} sx={{ width: '100%', height: '100%', ...slotProps?.box?.sx }}> ),
{children}
</Box>
</Tooltip>
); );

View File

@@ -7,47 +7,46 @@
*/ */
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import { ComponentProps, memo } from 'react';
import { ProgressBarPosition } from '@/modules/reader/types/Reader.types.ts'; import { ProgressBarPosition } from '@/modules/reader/types/Reader.types.ts';
import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts';
import { ReaderProgressBarSlot } from '@/modules/reader/components/overlay/progress-bar/ReaderProgressBarSlot'; import { ReaderProgressBarSlot } from '@/modules/reader/components/overlay/progress-bar/ReaderProgressBarSlot';
export const ReaderProgressBarSlotMobile = ({ const SLOT_SX_PROP: NonNullable<NonNullable<ComponentProps<typeof ReaderProgressBarSlot>['slotProps']>['box']>['sx'] = {
pageName, display: 'flex',
isTrailingPage, alignItems: 'center',
}: { justifyContent: 'end',
pageName: string; position: 'relative',
isTrailingPage: boolean; backgroundColor: 'background.default',
}) => ( };
<ReaderProgressBarSlot
pageName={pageName} const ProgressBarPagePoint = memo(({ isTrailingPage }: { isTrailingPage: boolean }) => (
progressBarPosition={ProgressBarPosition.BOTTOM} <Box
slotProps={{ sx={{
box: { position: 'absolute',
sx: { top: '50%',
display: 'flex', transform: 'translateY(-50%)',
alignItems: 'center', right: '2px',
justifyContent: 'end', width: '2px',
position: 'relative', height: '2px',
backgroundColor: 'background.default', borderRadius: 100,
}, backgroundColor: 'background.paper',
}, ...applyStyles(isTrailingPage, {
backgroundColor: 'primary.main',
}),
zIndex: 1,
}} }}
> />
<Box ));
sx={{
position: 'absolute', export const ReaderProgressBarSlotMobile = memo(
top: '50%', ({ pageName, isTrailingPage }: { pageName: string; isTrailingPage: boolean }) => (
transform: 'translateY(-50%)', <ReaderProgressBarSlot
right: '2px', pageName={pageName}
width: '2px', progressBarPosition={ProgressBarPosition.BOTTOM}
height: '2px', slotProps={{ box: { sx: SLOT_SX_PROP } }}
borderRadius: 100, >
backgroundColor: 'background.paper', <ProgressBarPagePoint isTrailingPage={isTrailingPage} />
...applyStyles(isTrailingPage, { </ReaderProgressBarSlot>
backgroundColor: 'primary.main', ),
}),
zIndex: 1,
}}
/>
</ReaderProgressBarSlot>
); );

View File

@@ -28,6 +28,71 @@ import { TReaderOverlayContext } from '@/modules/reader/types/ReaderOverlay.type
import { TReaderProgressBarContext } from '@/modules/reader/types/ReaderProgressBar.types.ts'; import { TReaderProgressBarContext } from '@/modules/reader/types/ReaderProgressBar.types.ts';
import { ReaderProgressBarSlotMobile } from '@/modules/reader/components/overlay/progress-bar/mobile/ReaderProgressBarSlotMobile.tsx'; import { ReaderProgressBarSlotMobile } from '@/modules/reader/components/overlay/progress-bar/mobile/ReaderProgressBarSlotMobile.tsx';
const PROGRESS_BAR_SLOT_PROPS: ComponentProps<typeof ReaderProgressBar>['slotProps'] = {
container: {
sx: {
flexGrow: 1,
position: 'relative',
display: 'flex',
justifyItems: 'center',
alignItems: 'stretch',
backgroundColor: (theme) => alpha(theme.palette.background.paper, 0.85),
borderRadius: 100,
boxShadow: 2,
},
},
progressBarRoot: {
sx: {
flexGrow: 1,
alignItems: 'stretch',
gap: 0,
},
},
progressBarSlotsActionArea: {
sx: {
height: '100%',
alignItems: 'center',
py: 2,
cursor: 'pointer',
},
},
progressBarSlotsContainer: {
sx: {
borderRadius: 100,
},
},
progressBarSlot: {
sx: {
height: '20px',
},
},
progressBarCurrentPageSlot: {
sx: {
display: 'flex',
justifyContent: 'end',
alignItems: 'center',
zIndex: 1,
pointer: 'default',
},
},
progressBarPageTexts: {
base: { px: 1 },
},
};
const PROGRESS_BAR_SLOTS: ComponentProps<typeof ReaderProgressBar>['slots'] = {
progressBarCurrentPage: (
<Box
sx={{
minWidth: '5px',
height: '75%',
backgroundColor: 'primary.main',
borderRadius: 100,
}}
/>
),
};
const BaseMobileReaderProgressBar = ({ const BaseMobileReaderProgressBar = ({
previousChapter, previousChapter,
nextChapter, nextChapter,
@@ -44,23 +109,12 @@ const BaseMobileReaderProgressBar = ({
const openNextChapter = ReaderService.useNavigateToChapter(nextChapter, ReaderResumeMode.START); const openNextChapter = ReaderService.useNavigateToChapter(nextChapter, ReaderResumeMode.START);
const openPreviousChapter = ReaderService.useNavigateToChapter(previousChapter, ReaderResumeMode.END); const openPreviousChapter = ReaderService.useNavigateToChapter(previousChapter, ReaderResumeMode.END);
const createProgressBarSlot: ComponentProps<typeof ReaderProgressBar>['createProgressBarSlot'] = useCallback(
(page, _1, _2, _3, _4, _5, isTrailingPage) => (
<ReaderProgressBarSlotMobile pageName={page.name} isTrailingPage={isTrailingPage} />
),
[],
);
useLayoutEffect(() => { useLayoutEffect(() => {
setIsMaximized(isVisible); setIsMaximized(isVisible);
return () => setIsMaximized(false); return () => setIsMaximized(false);
}, [isVisible]); }, [isVisible]);
if (!isVisible) {
return null;
}
return ( return (
<ReaderProgressBarDirectionWrapper> <ReaderProgressBarDirectionWrapper>
<Stack <Stack
@@ -81,47 +135,14 @@ const BaseMobileReaderProgressBar = ({
<ReaderProgressBar <ReaderProgressBar
progressBarPosition={ProgressBarPosition.BOTTOM} progressBarPosition={ProgressBarPosition.BOTTOM}
{...pagesState} {...pagesState}
createProgressBarSlot={createProgressBarSlot} createProgressBarSlot={useCallback(
(page, _1, _2, _3, _4, _5, isTrailingPage) => (
<ReaderProgressBarSlotMobile pageName={page.name} isTrailingPage={isTrailingPage} />
),
[],
)}
slotProps={{ slotProps={{
container: { ...PROGRESS_BAR_SLOT_PROPS,
sx: {
flexGrow: 1,
position: 'relative',
display: 'flex',
justifyItems: 'center',
alignItems: 'stretch',
backgroundColor: (theme) => alpha(theme.palette.background.paper, 0.85),
borderRadius: 100,
boxShadow: 2,
},
},
progressBarRoot: {
sx: {
flexGrow: 1,
alignItems: 'stretch',
gap: 0,
},
},
progressBarSlotsActionArea: {
sx: {
height: '100%',
alignItems: 'center',
py: 2,
cursor: 'pointer',
},
},
progressBarSlotsContainer: {
sx: {
borderRadius: 100,
},
},
progressBarSlot: {
sx: {
height: '20px',
},
},
progressBarReadPages: { progressBarReadPages: {
sx: { sx: {
height: '20px', height: '20px',
@@ -130,31 +151,8 @@ const BaseMobileReaderProgressBar = ({
width: `calc(${(Math.max(0, getPage(currentPageIndex, pages).pagesIndex) / pages.length) * 100}% + 100% / ${pages.length})`, width: `calc(${(Math.max(0, getPage(currentPageIndex, pages).pagesIndex) / pages.length) * 100}% + 100% / ${pages.length})`,
}, },
}, },
progressBarCurrentPageSlot: {
sx: {
display: 'flex',
justifyContent: 'end',
alignItems: 'center',
zIndex: 1,
pointer: 'default',
},
},
progressBarPageTexts: {
base: { px: 1 },
},
}}
slots={{
progressBarCurrentPage: (
<Box
sx={{
minWidth: '5px',
height: '75%',
backgroundColor: 'primary.main',
borderRadius: 100,
}}
/>
),
}} }}
slots={PROGRESS_BAR_SLOTS}
/> />
<IconButton <IconButton
onClick={openNextChapter} onClick={openNextChapter}