Respect manga chapter filters on library manga bulk download

This commit is contained in:
schroda
2026-06-19 13:56:03 +02:00
parent 4bbf7e4784
commit 675c7284e5
2 changed files with 30 additions and 23 deletions

View File

@@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- (**Reader**) Ignore tap zone clicks while window does not have focus - (**Reader**) Ignore tap zone clicks while window does not have focus
- (**Reader**) Improve preloading pages from the previous/next chapter - (**Reader**) Improve preloading pages from the previous/next chapter
- (**Category**) Require confirmation before deleting a category - (**Category**) Require confirmation before deleting a category
- (**Download**) Respect manga chapter filters on bulk manga download in the library
### Fixed ### Fixed

View File

@@ -58,8 +58,9 @@ import {
type UpdateMangaCategoriesPatchInput, type UpdateMangaCategoriesPatchInput,
} from '@/lib/graphql/generated/graphql-base.types.ts'; } from '@/lib/graphql/generated/graphql-base.types.ts';
import { GET_MANGAS_CHAPTER_IDS_WITH_STATE } from '@/lib/graphql/chapter/ChapterQuery.ts'; import { GET_MANGAS_CHAPTER_IDS_WITH_STATE } from '@/lib/graphql/chapter/ChapterQuery.ts';
import { getMangaMetadata } from '@/features/manga/services/MangaMetadata.ts';
import { filterChapters } from '@/features/chapter/utils/ChapterList.util.tsx'; import { filterChapters } from '@/features/chapter/utils/ChapterList.util.tsx';
import mapValues from 'lodash/fp/mapValues';
import { getMangaMetadata } from '@/features/manga/services/MangaMetadata.ts';
const I18N_PLURAL = 9999; const I18N_PLURAL = 9999;
@@ -229,14 +230,14 @@ export class Mangas {
'download', 'download',
I18N_PLURAL, I18N_PLURAL,
async () => { async () => {
const isSingleManga = mangaIds.length === 1;
// This should be cached by the time this function gets called, so it shouldn't trigger an actual request // This should be cached by the time this function gets called, so it shouldn't trigger an actual request
const mangaResponse = await (isSingleManga const mangaResponses = await Promise.all(
? requestManager.getManga<GetMangaMetaQuery>(GET_MANGA_META, mangaIds[0]).response mangaIds.map((id) => requestManager.getManga<GetMangaMetaQuery>(GET_MANGA_META, id).response),
: Promise.resolve(null)); );
const mangaByMangaId = Object.groupBy(
const meta = mangaResponse?.data?.manga ? getMangaMetadata(mangaResponse.data.manga) : null; mangaResponses.map((response) => response.data?.manga).filter((manga) => manga !== undefined),
(manga) => manga.id,
);
const [chaptersToConsider, unReadDownloadedChapters] = await Promise.all([ const [chaptersToConsider, unReadDownloadedChapters] = await Promise.all([
Mangas.getChapterIdsWithState(mangaIds, { Mangas.getChapterIdsWithState(mangaIds, {
@@ -251,11 +252,25 @@ export class Mangas {
: [], : [],
]); ]);
const chaptersToConsiderByMangaId = Object.groupBy(chaptersToConsider, (chapter) => chapter.mangaId);
const unReadDownloadedChaptersByMangaId = Object.groupBy(
unReadDownloadedChapters,
(chapter) => chapter.mangaId,
);
// TODO - Filter for scanlators directly in getChapterIdsWithState once fixed on the server // TODO - Filter for scanlators directly in getChapterIdsWithState once fixed on the server
const filteredChaptersToConsider = meta ? filterChapters(chaptersToConsider, meta) : chaptersToConsider; const filteredChaptersToConsiderByMangaId = mapValues((chapters) => {
const filteredUnReadDownloadedChapters = meta const { mangaId } = chapters![0]!;
? filterChapters(unReadDownloadedChapters, meta) const manga = mangaByMangaId[mangaId]![0]!;
: unReadDownloadedChapters;
return filterChapters(chapters!, getMangaMetadata(manga));
}, chaptersToConsiderByMangaId);
const filteredUnReadDownloadedChaptersByMangaId = mapValues((chapters) => {
const { mangaId } = chapters![0]!;
const manga = mangaByMangaId[mangaId]![0]!;
return filterChapters(chapters!, getMangaMetadata(manga));
}, unReadDownloadedChaptersByMangaId);
type MangaIdToDownloadSize = [MangaId: string, DownloadSize: number | undefined]; type MangaIdToDownloadSize = [MangaId: string, DownloadSize: number | undefined];
@@ -264,16 +279,7 @@ export class Mangas {
size, size,
]) satisfies MangaIdToDownloadSize[]; ]) satisfies MangaIdToDownloadSize[];
const mangaIdToChaptersToConsider = Object.groupBy( const mangaIdToDownloadSize = Object.entries(filteredUnReadDownloadedChaptersByMangaId).map(
filteredChaptersToConsider,
({ mangaId }) => mangaId,
);
const mangaIdToUnReadDownloadedChapters = Object.groupBy(
filteredUnReadDownloadedChapters,
({ mangaId }) => mangaId,
);
const mangaIdToDownloadSize = Object.entries(mangaIdToUnReadDownloadedChapters).map(
([mangaId, downloadedChapters = []]) => { ([mangaId, downloadedChapters = []]) => {
const downloadAheadSize = Math.max( const downloadAheadSize = Math.max(
0, 0,
@@ -291,7 +297,7 @@ export class Mangas {
const chaptersToDownload = mangaIdToActualDownloadSize const chaptersToDownload = mangaIdToActualDownloadSize
.flatMap(([mangaId, actualSize]) => { .flatMap(([mangaId, actualSize]) => {
const mangaChapters = mangaIdToChaptersToConsider[Number(mangaId)] ?? []; const mangaChapters = filteredChaptersToConsiderByMangaId[Number(mangaId)] ?? [];
if (!mangaChapters.length) { if (!mangaChapters.length) {
return []; return [];