Improve "chapter list" render performance
affected components: - ChapterList - ReaderChapterList
This commit is contained in:
@@ -144,6 +144,11 @@ export const ChapterList = ({
|
||||
const noChaptersFound = chapters.length === 0;
|
||||
const noChaptersMatchingFilter = !noChaptersFound && visibleChapters.length === 0;
|
||||
|
||||
const onSelect = useCallback(
|
||||
(id: number, selected: boolean, selectRange?: boolean) => handleSelection(id, selected, { selectRange }),
|
||||
[],
|
||||
);
|
||||
|
||||
if (isLoading || (noChaptersFound && isRefreshing)) {
|
||||
return (
|
||||
<Stack sx={{ justifyContent: 'center', alignItems: 'center', position: 'relative', flexGrow: 1 }}>
|
||||
@@ -238,11 +243,8 @@ export const ChapterList = ({
|
||||
<ChapterCard
|
||||
chapter={chapters[index]}
|
||||
selected={!areNoItemsSelected ? selectedItemIds.includes(chapters[index].id) : null}
|
||||
allChapters={chapters}
|
||||
showChapterNumber={options.showChapterNumber}
|
||||
onSelect={(selected, selectRange) =>
|
||||
handleSelection(chapters[index].id, selected, { selectRange })
|
||||
}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
)}
|
||||
useWindowScroll={isMobileWidth}
|
||||
|
||||
@@ -38,6 +38,9 @@ import {
|
||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||
import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts';
|
||||
import { ChapterCard } from '@/modules/chapter/components/cards/ChapterCard.tsx';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { GetChaptersMangaQuery } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { GET_CHAPTERS_MANGA } from '@/lib/graphql/queries/ChapterQuery.ts';
|
||||
|
||||
type BaseProps = { onClose: () => void; selectable?: boolean };
|
||||
|
||||
@@ -50,7 +53,6 @@ type TChapter = ChapterIdInfo &
|
||||
|
||||
type SingleModeProps = {
|
||||
chapter: TChapter;
|
||||
allChapters: TChapter[];
|
||||
handleSelection?: SelectableCollectionReturnType<TChapter['id']>['handleSelection'];
|
||||
canBeDownloaded: boolean;
|
||||
};
|
||||
@@ -65,7 +67,6 @@ type Props =
|
||||
|
||||
export const ChapterActionMenuItems = ({
|
||||
chapter,
|
||||
allChapters,
|
||||
handleSelection,
|
||||
canBeDownloaded = false,
|
||||
selectedChapters = [],
|
||||
@@ -77,6 +78,16 @@ export const ChapterActionMenuItems = ({
|
||||
const isSingleMode = !!chapter;
|
||||
const { isDownloaded, isRead, isBookmarked } = chapter ?? {};
|
||||
|
||||
const mangaChaptersResponse = requestManager.useGetMangaChapters<GetChaptersMangaQuery>(
|
||||
GET_CHAPTERS_MANGA,
|
||||
chapter?.mangaId ?? -1,
|
||||
{
|
||||
skip: !chapter,
|
||||
fetchPolicy: 'cache-only',
|
||||
},
|
||||
);
|
||||
const allChapters = mangaChaptersResponse.data?.chapters.nodes ?? [];
|
||||
|
||||
const {
|
||||
settings: { deleteChaptersWithBookmark },
|
||||
} = useMetadataServerSettings();
|
||||
|
||||
@@ -17,7 +17,7 @@ import CardContent from '@mui/material/CardContent';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import React, { MouseEvent, TouchEvent, useRef } from 'react';
|
||||
import React, { memo, MouseEvent, TouchEvent, useRef } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state';
|
||||
@@ -51,15 +51,14 @@ type TChapter = ChapterIdInfo &
|
||||
interface IProps {
|
||||
mode?: 'manga.page' | 'reader';
|
||||
chapter: TChapter;
|
||||
allChapters: TChapter[];
|
||||
showChapterNumber: boolean;
|
||||
onSelect: (selected: boolean, isShiftKey?: boolean) => void;
|
||||
onSelect: (id: number, selected: boolean, isShiftKey?: boolean) => void;
|
||||
selected: boolean | null;
|
||||
selectable?: boolean;
|
||||
isActiveChapter?: boolean; // reader
|
||||
}
|
||||
|
||||
export const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
export const ChapterCard = memo((props: IProps) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -68,7 +67,6 @@ export const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
const {
|
||||
mode = 'manga.page',
|
||||
chapter,
|
||||
allChapters,
|
||||
showChapterNumber,
|
||||
onSelect,
|
||||
selected,
|
||||
@@ -84,7 +82,7 @@ export const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
onSelect(!selected, event.shiftKey);
|
||||
onSelect(chapter.id, !selected, event.shiftKey);
|
||||
};
|
||||
|
||||
const handleClickOpenMenu = (
|
||||
@@ -204,8 +202,7 @@ export const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
<ChapterActionMenuItems
|
||||
onClose={onClose}
|
||||
chapter={chapter}
|
||||
allChapters={allChapters}
|
||||
handleSelection={() => onSelect(true)}
|
||||
handleSelection={() => onSelect(chapter.id, true)}
|
||||
canBeDownloaded={Chapters.isDownloadable(chapter)}
|
||||
selectable={selectable}
|
||||
/>
|
||||
@@ -216,4 +213,4 @@ export const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
)}
|
||||
</PopupState>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -11,6 +11,8 @@ import { useMemo } from 'react';
|
||||
import { ChapterCard } from '@/modules/chapter/components/cards/ChapterCard.tsx';
|
||||
import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
|
||||
|
||||
const onSelectNoop = () => {};
|
||||
|
||||
export const ReaderChapterList = ({
|
||||
currentChapter,
|
||||
chapters,
|
||||
@@ -35,10 +37,9 @@ export const ReaderChapterList = ({
|
||||
key={chapters[index].id}
|
||||
mode="reader"
|
||||
chapter={chapters[index]}
|
||||
allChapters={chapters}
|
||||
showChapterNumber={false}
|
||||
selected={null}
|
||||
onSelect={() => undefined}
|
||||
onSelect={onSelectNoop}
|
||||
selectable={false}
|
||||
isActiveChapter={index === currentChapterIndex}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user