Move download status subscription to "ChapterCard"

Only re-render chapters whose download status has changed instead of the whole list everytime a download status change was received
This commit is contained in:
schroda
2025-01-12 15:05:09 +01:00
parent f7b26767a3
commit 257c0c8e10
11 changed files with 107 additions and 205 deletions

View File

@@ -8,53 +8,33 @@
import { Virtuoso, VirtuosoProps } from 'react-virtuoso';
import { useMemo } from 'react';
import { IChapterWithMeta } from '@/modules/chapter/components/ChapterList.tsx';
import { ChapterCard } from '@/modules/chapter/components/cards/ChapterCard.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
import { Chapters } from '@/modules/chapter/services/Chapters';
export const ReaderChapterList = ({
currentChapter,
chapters,
style,
}: Pick<ReaderStateChapters, 'chapters' | 'currentChapter'> & Pick<VirtuosoProps<any, any>, 'style'>) => {
const downloadSubscription = requestManager.useDownloadSubscription();
const currentChapterIndex = useMemo(
() => currentChapter && chapters.findIndex((chapter) => chapter.id === currentChapter.id),
[currentChapter, chapters],
);
const chaptersWithMeta: IChapterWithMeta[] = useMemo(
() =>
chapters.map((chapter) => {
const downloadChapter = Chapters.getDownloadStatusFromCache(chapter.id);
return {
chapter,
downloadChapter,
selected: null,
};
}),
[downloadSubscription.data?.downloadStatusChanged, chapters],
);
return (
<Virtuoso
style={{
height: `calc(${chaptersWithMeta.length} * 100px)`,
height: `calc(${chapters.length} * 100px)`,
...style,
}}
initialTopMostItemIndex={currentChapterIndex ?? 0}
totalCount={chaptersWithMeta.length}
computeItemKey={(index) => chaptersWithMeta[index].chapter.id}
totalCount={chapters.length}
computeItemKey={(index) => chapters[index].id}
itemContent={(index) => (
<ChapterCard
key={chaptersWithMeta[index].chapter.id}
key={chapters[index].id}
mode="reader"
chapter={chaptersWithMeta[index].chapter}
downloadChapter={chaptersWithMeta[index].downloadChapter}
chapter={chapters[index]}
allChapters={chapters}
showChapterNumber={false}
selected={null}

View File

@@ -19,20 +19,17 @@ import { memo, useMemo, useRef } from 'react';
import DeleteIcon from '@mui/icons-material/Delete';
import { actionToTranslationKey, ChapterAction, Chapters } from '@/modules/chapter/services/Chapters.ts';
import { ReaderStateChapters } from '@/modules/reader/types/Reader.types.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { DownloadStateIndicator } from '@/modules/core/components/DownloadStateIndicator.tsx';
import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types.ts';
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
import { useReaderStateChaptersContext } from '@/modules/reader/contexts/state/ReaderStateChaptersContext.tsx';
import { userReaderStatePagesContext } from '@/modules/reader/contexts/state/ReaderStatePagesContext.tsx';
import { ChapterWithMetaType } from '@/modules/chapter/services/ChaptersWithMeta.ts';
const DownloadButton = ({
currentChapter,
downloadChapter,
}: Required<Pick<ReaderStateChapters, 'currentChapter'>> & Pick<ChapterWithMetaType, 'downloadChapter'>) => {
const DownloadButton = ({ currentChapter }: Required<Pick<ReaderStateChapters, 'currentChapter'>>) => {
const { t } = useTranslation();
const downloadChapter = Chapters.getDownloadStatusFromCache(currentChapter?.id ?? -1);
if (currentChapter && Chapters.isDownloaded(currentChapter)) {
return (
<Tooltip title={t(actionToTranslationKey.delete.action.single)}>
@@ -44,7 +41,7 @@ const DownloadButton = ({
}
if (downloadChapter) {
return <DownloadStateIndicator download={downloadChapter} />;
return <DownloadStateIndicator chapterId={downloadChapter.chapter.id} />;
}
return (
@@ -74,16 +71,6 @@ const BaseReaderNavBarDesktopActions = memo(
const pageRetryKeyPrefix = useRef<number>(0);
const downloadSubscription = requestManager.useDownloadSubscription();
const downloadChapter = useMemo(() => {
if (!currentChapter) {
return null;
}
return Chapters.getDownloadStatusFromCache(currentChapter?.id);
}, [downloadSubscription.data?.downloadStatusChanged, id]);
const haveSomePagesFailedToLoad = useMemo(
() => pageLoadStates.some((pageLoadState) => pageLoadState.error),
[pageLoadStates],
@@ -118,7 +105,7 @@ const BaseReaderNavBarDesktopActions = memo(
<ReplayIcon />
</IconButton>
</Tooltip>
<DownloadButton currentChapter={currentChapter} downloadChapter={downloadChapter} />
<DownloadButton currentChapter={currentChapter} />
<Tooltip title={t('chapter.action.label.open_on_source')}>
<IconButton
disabled={!realUrl}