Use filtered chapters for none manga bulk downloads

For multiple manga it's not feasible to filter the chapters based on the active chapter list options.

fixes #980
This commit is contained in:
schroda
2025-07-05 17:15:28 +02:00
parent 900f570bb0
commit 85cec6fd8d

View File

@@ -8,11 +8,27 @@
import MenuItem from '@mui/material/MenuItem';
import { useTranslation } from 'react-i18next';
import gql from 'graphql-tag';
import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts';
import { Mangas } from '@/modules/manga/services/Mangas.ts';
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
import {
ChapterOrderBy,
GetChaptersMangaQuery,
GetChaptersMangaQueryVariables,
MangaType,
SortOrder,
} from '@/lib/graphql/generated/graphql.ts';
import { TranslationKey } from '@/Base.types.ts';
import { MANGA_META_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
import { getMangaMetadata } from '@/modules/manga/services/MangaMetadata.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { GET_CHAPTERS_MANGA } from '@/lib/graphql/queries/ChapterQuery.ts';
import { filterChapters } from '@/modules/chapter/utils/ChapterList.util.tsx';
import { Chapters } from '@/modules/chapter/services/Chapters.ts';
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { CHAPTER_ACTION_TO_TRANSLATION } from '@/modules/chapter/Chapter.constants.ts';
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
const DOWNLOAD_OPTIONS: {
title: TranslationKey;
@@ -32,6 +48,65 @@ const DOWNLOAD_OPTIONS: {
{ title: 'chapter.action.download.add.label.all', getCount: () => undefined, onlyUnread: false },
];
const handleDownload = async (
mangaIds: MangaType['id'][],
onlyUnread: boolean,
size: number | undefined,
downloadAhead: boolean,
): Promise<void> => {
const isMultiMangaManga = mangaIds.length > 1;
if (isMultiMangaManga) {
Mangas.performAction('download', mangaIds, {
downloadAhead,
onlyUnread,
size,
}).catch(defaultPromiseErrorHandler('ChaptersDownloadActionMenuItems::handleSelect:multiMangaMode'));
return;
}
const mangaId = mangaIds[0];
const manga = Mangas.getFromCache(
mangaId,
gql`
${MANGA_META_FIELDS}
fragment MangaInLibraryState on MangaType {
id
meta {
...MANGA_META_FIELDS
}
}
`,
'MangaInLibraryState',
)!;
const meta = getMangaMetadata(manga);
const chapters = await requestManager.getChapters<GetChaptersMangaQuery, GetChaptersMangaQueryVariables>(
GET_CHAPTERS_MANGA,
{
condition: { mangaId: Number(mangaId) },
order: [{ by: ChapterOrderBy.SourceOrder, byType: SortOrder.Desc }],
},
).response;
const filteredChapters = filterChapters(chapters.data.chapters.nodes, meta);
const chaptersToDownload = filteredChapters
.filter((chapter) => {
if (onlyUnread && chapter.isRead) {
return false;
}
return !chapter.isDownloaded;
})
.slice(0, size);
if (!chaptersToDownload.length) {
return;
}
Chapters.performAction('download', Chapters.getIds(chaptersToDownload), {}).catch(
defaultPromiseErrorHandler('ChaptersDownloadActionMenuItems::handleSelect::singleMangaMode'),
);
};
export const ChaptersDownloadActionMenuItems = ({
mangaIds,
closeMenu,
@@ -46,11 +121,16 @@ export const ChaptersDownloadActionMenuItems = ({
} = useMetadataServerSettings();
const handleSelect = (size?: number, onlyUnread: boolean = true, downloadAhead: boolean = false) => {
Mangas.performAction('download', mangaIds, {
downloadAhead,
onlyUnread,
size,
}).catch(defaultPromiseErrorHandler('ChaptersDownloadActionMenuItems::handleSelect'));
handleDownload(mangaIds, onlyUnread, size, downloadAhead).catch((e) =>
makeToast(
t(CHAPTER_ACTION_TO_TRANSLATION.download.error, {
count: size,
}),
'error',
getErrorMessage(e),
),
);
closeMenu?.();
};