From 7b20f08f5161fc394d30d26fd289c203f98e842c Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Tue, 5 May 2026 00:51:47 +0200 Subject: [PATCH] Align chapter "download ahead" download option for single and bulk selection For the bulk selection the "download ahead" option only downloaded chapter in case there weren't enough downloaded chapters. In the single mode, this wasn't the case. There was "logic" to make this happen; however, it was not working as expected --- CHANGELOG.md | 1 + .../ChaptersDownloadActionMenuItems.tsx | 114 ++---------------- 2 files changed, 8 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67e550b6..8d8268e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - (**Reader**) Fix scroll position jumping on chapter resume in the continuous horizontal mode - (**Reader**) Fix page load retry button in continuous reading modes - (**Manga**) Fix dynamic manga page color theme not getting reset after leaving the manga page +- (**Download**) Fix "download ahead" option in the library for a single manga or in the manga page chapter list triggering downloads while there are already enough unread downloaded chapters ## [20251230.01] (r2937) - 2025-12-30 diff --git a/src/features/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx b/src/features/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx index 584f0b29..35a33584 100644 --- a/src/features/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx +++ b/src/features/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx @@ -8,27 +8,12 @@ import type { MessageDescriptor } from '@lingui/core'; import MenuItem from '@mui/material/MenuItem'; -import gql from 'graphql-tag'; import { msg } from '@lingui/core/macro'; import { useMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts'; import { Mangas } from '@/features/manga/services/Mangas.ts'; -import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; -import type { - GetChaptersMangaQuery, - GetChaptersMangaQueryVariables, - MangaType, -} from '@/lib/graphql/generated/graphql.ts'; -import { ChapterOrderBy, SortOrder } from '@/lib/graphql/generated/graphql.ts'; -import { MANGA_META_FIELDS } from '@/lib/graphql/manga/MangaFragments.ts'; -import { getMangaMetadata } from '@/features/manga/services/MangaMetadata.ts'; -import { requestManager } from '@/lib/requests/RequestManager.ts'; -import { GET_CHAPTERS_MANGA } from '@/lib/graphql/chapter/ChapterQuery.ts'; -import { filterChapters } from '@/features/chapter/utils/ChapterList.util.tsx'; -import { Chapters } from '@/features/chapter/services/Chapters.ts'; -import { makeToast } from '@/base/utils/Toast.ts'; -import { CHAPTER_ACTION_TO_TRANSLATION } from '@/features/chapter/Chapter.constants.ts'; -import { getErrorMessage } from '@/lib/HelperFunctions.ts'; +import type { MangaType } from '@/lib/graphql/generated/graphql.ts'; import { i18n } from '@/i18n'; +import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; const DOWNLOAD_OPTIONS: { title: MessageDescriptor; @@ -70,85 +55,6 @@ const DOWNLOAD_OPTIONS: { }, ]; -const handleDownload = async ( - mangaIds: MangaType['id'][], - onlyUnread: boolean, - size: number | undefined, - downloadAhead: boolean, -): Promise => { - const isMultiMangaManga = mangaIds.length > 1; - if (isMultiMangaManga) { - Mangas.performAction('download', mangaIds, { - downloadAhead, - onlyUnread, - size, - }).catch(defaultPromiseErrorHandler('ChaptersDownloadActionMenuItems::handleSelect:multiMangaMode')); - return; - } - - const [mangaId] = mangaIds; - 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( - GET_CHAPTERS_MANGA, - { - // Align conditions/filters with the query from ChapterList to potentially be able to reuse the cache - condition: { mangaId: Number(mangaId) }, - order: [{ by: ChapterOrderBy.SourceOrder, byType: SortOrder.Desc }], - }, - ).response; - - if (!chapters.data) { - return; - } - - const filteredChapters = filterChapters(chapters.data.chapters.nodes, meta); - - const doNecessaryDownloadAheadDownloadsExist = - downloadAhead && - Chapters.removeDuplicates(filteredChapters.slice(-1)[0], filteredChapters) - .slice(-(size ?? 0)) - .every((chapter) => !Chapters.isRead(chapter) && Chapters.isDownloaded(chapter)); - if (doNecessaryDownloadAheadDownloadsExist) { - return; - } - - const unreadUndownloadedChapters = filteredChapters.filter((chapter) => { - if (onlyUnread && chapter.isRead) { - return false; - } - - return !chapter.isDownloaded; - }); - - const uniqueChapters = Chapters.removeDuplicates( - unreadUndownloadedChapters.slice(-1)[0], - unreadUndownloadedChapters, - ); - const chaptersToDownload = uniqueChapters.slice(-(size ?? 0)); - const chaptersToDownloadWithDuplicates = Chapters.addDuplicates(chaptersToDownload, unreadUndownloadedChapters); - - if (!chaptersToDownloadWithDuplicates.length) { - return; - } - - Chapters.performAction('download', Chapters.getIds(chaptersToDownloadWithDuplicates), {}).catch( - defaultPromiseErrorHandler('ChaptersDownloadActionMenuItems::handleSelect::singleMangaMode'), - ); -}; - export const ChaptersDownloadActionMenuItems = ({ mangaIds, closeMenu, @@ -161,17 +67,11 @@ export const ChaptersDownloadActionMenuItems = ({ } = useMetadataServerSettings(); const handleSelect = (size?: number, onlyUnread: boolean = true, downloadAhead: boolean = false) => { - handleDownload(mangaIds, onlyUnread, size, downloadAhead).catch((e) => - makeToast( - /* lingui-extract-ignore */ - i18n.t({ - ...CHAPTER_ACTION_TO_TRANSLATION.download.error, - values: { count: size }, - }), - 'error', - getErrorMessage(e), - ), - ); + Mangas.performAction('download', mangaIds, { + downloadAhead, + onlyUnread, + size, + }).catch(defaultPromiseErrorHandler('ChaptersDownloadActionMenuItems::handleSelect')); closeMenu?.(); };