From c53f29b6e75182812f10c3d5d225cf9fa4c9ad10 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Wed, 20 May 2026 16:48:57 +0200 Subject: [PATCH] Fix respecting chapter list filters for downloads Regression 7b20f08f5161fc394d30d26fd289c203f98e842c --- src/features/manga/services/Mangas.ts | 44 +++++++++++++++++++++++---- src/lib/graphql/generated/graphql.ts | 13 ++++++++ src/lib/graphql/manga/MangaQuery.ts | 13 ++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/features/manga/services/Mangas.ts b/src/features/manga/services/Mangas.ts index 3f4c2064..b281536e 100644 --- a/src/features/manga/services/Mangas.ts +++ b/src/features/manga/services/Mangas.ts @@ -11,15 +11,17 @@ import { t } from '@lingui/core/macro'; import { i18n } from '@/i18n'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import type { + GetMangaMetaQuery, GetMangasBaseQuery, GetMangasBaseQueryVariables, GetMangasChapterIdsWithStateQuery, + GetMangasChapterIdsWithStateQueryVariables, MangaBaseFieldsFragment, } from '@/lib/graphql/generated/graphql.ts'; import { Chapters } from '@/features/chapter/services/Chapters.ts'; import { makeToast } from '@/base/utils/Toast.ts'; import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts'; -import { GET_MANGAS_BASE } from '@/lib/graphql/manga/MangaQuery.ts'; +import { GET_MANGA_META, GET_MANGAS_BASE } from '@/lib/graphql/manga/MangaQuery.ts'; import { MANGA_BASE_FIELDS, MANGA_MIGRATION_FIELDS } from '@/lib/graphql/manga/MangaFragments.ts'; import type { MangaAction, @@ -56,6 +58,8 @@ import { type UpdateMangaCategoriesPatchInput, } from '@/lib/graphql/generated/graphql-base.types.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'; const I18N_PLURAL = 9999; @@ -183,13 +187,18 @@ export class Mangas { static async getChapterIdsWithState( mangaIds: number[], - state: Pick, + { + excludedScanlators, + ...state + }: Pick & { + excludedScanlators?: string[]; + }, ): Promise { const { data } = await requestManager.getChapters< GetMangasChapterIdsWithStateQuery, GetMangasChapterIdsWithStateQueryVariables >(GET_MANGAS_CHAPTER_IDS_WITH_STATE, { - filter: { mangaId: { in: mangaIds } }, + filter: { mangaId: { in: mangaIds }, scanlator: { notIncludesInsensitiveAny: excludedScanlators } }, condition: { ...state }, order: [{ by: ChapterOrderBy.SourceOrder }], }).response; @@ -206,14 +215,34 @@ export class Mangas { 'download', I18N_PLURAL, 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 + const mangaResponse = await (isSingleManga + ? requestManager.getManga(GET_MANGA_META, mangaIds[0]).response + : Promise.resolve(null)); + + const meta = mangaResponse?.data?.manga ? getMangaMetadata(mangaResponse.data.manga) : null; + const [chaptersToConsider, unReadDownloadedChapters] = await Promise.all([ Mangas.getChapterIdsWithState(mangaIds, { isRead: onlyUnread ? false : undefined, isDownloaded: false, }), - downloadAhead ? Mangas.getChapterIdsWithState(mangaIds, { isRead: false, isDownloaded: true }) : [], + downloadAhead + ? Mangas.getChapterIdsWithState(mangaIds, { + isRead: false, + isDownloaded: true, + }) + : [], ]); + // TODO - Filter for scanlators directly in getChapterIdsWithState once fixed on the server + const filteredChaptersToConsider = meta ? filterChapters(chaptersToConsider, meta) : chaptersToConsider; + const filteredUnReadDownloadedChapters = meta + ? filterChapters(unReadDownloadedChapters, meta) + : unReadDownloadedChapters; + type MangaIdToDownloadSize = [MangaId: string, DownloadSize: number | undefined]; const mangaIdToDefaultDownloadSize = mangaIds.map((mangaId) => [ @@ -221,9 +250,12 @@ export class Mangas { size, ]) satisfies MangaIdToDownloadSize[]; - const mangaIdToChaptersToConsider = Object.groupBy(chaptersToConsider, ({ mangaId }) => mangaId); + const mangaIdToChaptersToConsider = Object.groupBy( + filteredChaptersToConsider, + ({ mangaId }) => mangaId, + ); const mangaIdToUnReadDownloadedChapters = Object.groupBy( - unReadDownloadedChapters, + filteredUnReadDownloadedChapters, ({ mangaId }) => mangaId, ); diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts index 3812e187..b5013e15 100644 --- a/src/lib/graphql/generated/graphql.ts +++ b/src/lib/graphql/generated/graphql.ts @@ -2117,6 +2117,19 @@ export type UpdateMangaMetadataMutation = { } | null; }; +export type GetMangaMetaQueryVariables = Exact<{ + id: number; +}>; + +export type GetMangaMetaQuery = { + __typename: 'Query'; + manga: { + __typename: 'MangaType'; + id: number; + meta: Array<{ __typename: 'MangaMetaType'; mangaId: number; key: string; value: string }>; + }; +}; + export type GetMangaScreenQueryVariables = Exact<{ id: number; }>; diff --git a/src/lib/graphql/manga/MangaQuery.ts b/src/lib/graphql/manga/MangaQuery.ts index f81045bf..81ddeb40 100644 --- a/src/lib/graphql/manga/MangaQuery.ts +++ b/src/lib/graphql/manga/MangaQuery.ts @@ -20,6 +20,19 @@ import { import { CHAPTER_META_FIELDS } from '@/lib/graphql/chapter/ChapterFragments.ts'; import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/tracker/TrackRecordFragments.ts'; +export const GET_MANGA_META = gql` + ${MANGA_META_FIELDS} + + query GET_MANGA_META($id: Int!) { + manga(id: $id) { + id + meta { + ...MANGA_META_FIELDS + } + } + } +`; + // returns the current manga from the database export const GET_MANGA_SCREEN = gql` ${MANGA_SCREEN_FIELDS}