Fix respecting chapter list filters for downloads

Regression 7b20f08f51
This commit is contained in:
schroda
2026-05-20 16:48:57 +02:00
parent 19962df378
commit c53f29b6e7
3 changed files with 64 additions and 6 deletions

View File

@@ -11,15 +11,17 @@ import { t } from '@lingui/core/macro';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import type { import type {
GetMangaMetaQuery,
GetMangasBaseQuery, GetMangasBaseQuery,
GetMangasBaseQueryVariables, GetMangasBaseQueryVariables,
GetMangasChapterIdsWithStateQuery, GetMangasChapterIdsWithStateQuery,
GetMangasChapterIdsWithStateQueryVariables,
MangaBaseFieldsFragment, MangaBaseFieldsFragment,
} from '@/lib/graphql/generated/graphql.ts'; } from '@/lib/graphql/generated/graphql.ts';
import { Chapters } from '@/features/chapter/services/Chapters.ts'; import { Chapters } from '@/features/chapter/services/Chapters.ts';
import { makeToast } from '@/base/utils/Toast.ts'; import { makeToast } from '@/base/utils/Toast.ts';
import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.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 { MANGA_BASE_FIELDS, MANGA_MIGRATION_FIELDS } from '@/lib/graphql/manga/MangaFragments.ts';
import type { import type {
MangaAction, MangaAction,
@@ -56,6 +58,8 @@ 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';
const I18N_PLURAL = 9999; const I18N_PLURAL = 9999;
@@ -183,13 +187,18 @@ export class Mangas {
static async getChapterIdsWithState( static async getChapterIdsWithState(
mangaIds: number[], mangaIds: number[],
state: Pick<ChapterConditionInput, 'isRead' | 'isDownloaded' | 'isBookmarked'>, {
excludedScanlators,
...state
}: Pick<ChapterConditionInput, 'isRead' | 'isDownloaded' | 'isBookmarked'> & {
excludedScanlators?: string[];
},
): Promise<GetMangasChapterIdsWithStateQuery['chapters']['nodes']> { ): Promise<GetMangasChapterIdsWithStateQuery['chapters']['nodes']> {
const { data } = await requestManager.getChapters< const { data } = await requestManager.getChapters<
GetMangasChapterIdsWithStateQuery, GetMangasChapterIdsWithStateQuery,
GetMangasChapterIdsWithStateQueryVariables GetMangasChapterIdsWithStateQueryVariables
>(GET_MANGAS_CHAPTER_IDS_WITH_STATE, { >(GET_MANGAS_CHAPTER_IDS_WITH_STATE, {
filter: { mangaId: { in: mangaIds } }, filter: { mangaId: { in: mangaIds }, scanlator: { notIncludesInsensitiveAny: excludedScanlators } },
condition: { ...state }, condition: { ...state },
order: [{ by: ChapterOrderBy.SourceOrder }], order: [{ by: ChapterOrderBy.SourceOrder }],
}).response; }).response;
@@ -206,14 +215,34 @@ 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
const mangaResponse = await (isSingleManga
? requestManager.getManga<GetMangaMetaQuery>(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([ const [chaptersToConsider, unReadDownloadedChapters] = await Promise.all([
Mangas.getChapterIdsWithState(mangaIds, { Mangas.getChapterIdsWithState(mangaIds, {
isRead: onlyUnread ? false : undefined, isRead: onlyUnread ? false : undefined,
isDownloaded: false, 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]; type MangaIdToDownloadSize = [MangaId: string, DownloadSize: number | undefined];
const mangaIdToDefaultDownloadSize = mangaIds.map((mangaId) => [ const mangaIdToDefaultDownloadSize = mangaIds.map((mangaId) => [
@@ -221,9 +250,12 @@ export class Mangas {
size, size,
]) satisfies MangaIdToDownloadSize[]; ]) satisfies MangaIdToDownloadSize[];
const mangaIdToChaptersToConsider = Object.groupBy(chaptersToConsider, ({ mangaId }) => mangaId); const mangaIdToChaptersToConsider = Object.groupBy(
filteredChaptersToConsider,
({ mangaId }) => mangaId,
);
const mangaIdToUnReadDownloadedChapters = Object.groupBy( const mangaIdToUnReadDownloadedChapters = Object.groupBy(
unReadDownloadedChapters, filteredUnReadDownloadedChapters,
({ mangaId }) => mangaId, ({ mangaId }) => mangaId,
); );

View File

@@ -2117,6 +2117,19 @@ export type UpdateMangaMetadataMutation = {
} | null; } | 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<{ export type GetMangaScreenQueryVariables = Exact<{
id: number; id: number;
}>; }>;

View File

@@ -20,6 +20,19 @@ import {
import { CHAPTER_META_FIELDS } from '@/lib/graphql/chapter/ChapterFragments.ts'; import { CHAPTER_META_FIELDS } from '@/lib/graphql/chapter/ChapterFragments.ts';
import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/tracker/TrackRecordFragments.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 // returns the current manga from the database
export const GET_MANGA_SCREEN = gql` export const GET_MANGA_SCREEN = gql`
${MANGA_SCREEN_FIELDS} ${MANGA_SCREEN_FIELDS}