From 318c4a50407c3202949fd3216cb209889aacfeca Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sat, 16 Mar 2024 13:45:54 +0100 Subject: [PATCH] Add option to delete downloaded chapters on migration (#655) --- src/components/MigrateDialog.tsx | 8 ++++++++ src/i18n/locale/en.json | 3 +++ src/lib/data/Mangas.ts | 11 +++++++++-- src/lib/graphql/generated/apollo-helpers.ts | 3 ++- src/lib/graphql/generated/graphql.ts | 3 ++- src/lib/graphql/queries/MangaQuery.ts | 4 ++-- src/lib/requests/RequestManager.ts | 4 +++- 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/components/MigrateDialog.tsx b/src/components/MigrateDialog.tsx index b7fc351b..d7f0a012 100644 --- a/src/components/MigrateDialog.tsx +++ b/src/components/MigrateDialog.tsx @@ -30,6 +30,7 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat const [includeChapters, setIncludeChapters] = useState(true); const [includeCategories, setIncludeCategories] = useState(true); + const [deleteChapters, setDeleteChapters] = useState(true); const [isMigrationInProcess, setIsMigrationInProcess] = useState(false); @@ -47,6 +48,7 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat mode, migrateChapters: includeChapters, migrateCategories: includeCategories, + deleteChapters, }); navigate(`/manga/${mangaIdToMigrateTo}`, { replace: true }); @@ -72,6 +74,12 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat checked={includeCategories} onChange={(_, checked) => setIncludeCategories(checked)} /> + setDeleteChapters(checked)} + /> diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index e6c7e662..1781c108 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -615,6 +615,9 @@ "show_entry": "Show entry" } }, + "label": { + "delete_downloaded": "Delete downloaded" + }, "title": "Select data to include" }, "label": { diff --git a/src/lib/data/Mangas.ts b/src/lib/data/Mangas.ts index 424a7b05..92eabdee 100644 --- a/src/lib/data/Mangas.ts +++ b/src/lib/data/Mangas.ts @@ -111,6 +111,7 @@ type MigrateOptions = { mode: MigrateMode; migrateChapters?: boolean; migrateCategories?: boolean; + deleteChapters?: boolean; }; type PerformActionOptions = Action extends 'mark_as_read' ? MarkAsReadOptions & PropertiesNever & PropertiesNever @@ -279,11 +280,12 @@ export class Mangas { static async migrate( mangaId: number, mangaIdToMigrateTo: number, - { mode, migrateChapters, migrateCategories }: Omit, + { mode, migrateChapters, migrateCategories, deleteChapters }: Omit, ): Promise { return Mangas.executeAction('migrate', 1, async () => { const [{ data: mangaToMigrateData }, { data: mangaToMigrateToData }] = await Promise.all([ - requestManager.getMangaToMigrate(mangaId, { migrateChapters, migrateCategories }).response, + requestManager.getMangaToMigrate(mangaId, { migrateChapters, migrateCategories, deleteChapters }) + .response, requestManager.getMangaToMigrateToFetch(mangaIdToMigrateTo, { migrateChapters, migrateCategories }) .response, ]); @@ -301,6 +303,11 @@ export class Mangas { await Promise.all([ migrateChapters ? Mangas.migrateChapters(mangaToMigrateData.manga, mangaToMigrateToData) : undefined, + deleteChapters + ? requestManager.deleteDownloadedChapters( + Chapters.getIds(Chapters.getDownloaded(mangaToMigrateData.manga.chapters?.nodes ?? [])), + ).response + : undefined, migrateCategories ? Mangas.migrateCategories(mangaToMigrateData.manga, mangaToMigrateToData.fetchManga.manga) : undefined, diff --git a/src/lib/graphql/generated/apollo-helpers.ts b/src/lib/graphql/generated/apollo-helpers.ts index db7e6db5..67ae5af1 100644 --- a/src/lib/graphql/generated/apollo-helpers.ts +++ b/src/lib/graphql/generated/apollo-helpers.ts @@ -383,7 +383,7 @@ export type MangaNodeListFieldPolicy = { pageInfo?: FieldPolicy | FieldReadFunction, totalCount?: FieldPolicy | FieldReadFunction }; -export type MangaTypeKeySpecifier = ('age' | 'artist' | 'author' | 'categories' | 'chapters' | 'chaptersAge' | 'chaptersLastFetchedAt' | 'description' | 'downloadCount' | 'genre' | 'id' | 'inLibrary' | 'inLibraryAt' | 'initialized' | 'lastFetchedAt' | 'lastReadChapter' | 'latestFetchedChapter' | 'latestReadChapter' | 'latestUploadedChapter' | 'meta' | 'realUrl' | 'source' | 'sourceId' | 'status' | 'thumbnailUrl' | 'thumbnailUrlLastFetched' | 'title' | 'trackRecords' | 'unreadCount' | 'updateStrategy' | 'url' | MangaTypeKeySpecifier)[]; +export type MangaTypeKeySpecifier = ('age' | 'artist' | 'author' | 'categories' | 'chapters' | 'chaptersAge' | 'chaptersLastFetchedAt' | 'description' | 'downloadCount' | 'firstUnreadChapter' | 'genre' | 'id' | 'inLibrary' | 'inLibraryAt' | 'initialized' | 'lastFetchedAt' | 'lastReadChapter' | 'latestFetchedChapter' | 'latestReadChapter' | 'latestUploadedChapter' | 'meta' | 'realUrl' | 'source' | 'sourceId' | 'status' | 'thumbnailUrl' | 'thumbnailUrlLastFetched' | 'title' | 'trackRecords' | 'unreadCount' | 'updateStrategy' | 'url' | MangaTypeKeySpecifier)[]; export type MangaTypeFieldPolicy = { age?: FieldPolicy | FieldReadFunction, artist?: FieldPolicy | FieldReadFunction, @@ -394,6 +394,7 @@ export type MangaTypeFieldPolicy = { chaptersLastFetchedAt?: FieldPolicy | FieldReadFunction, description?: FieldPolicy | FieldReadFunction, downloadCount?: FieldPolicy | FieldReadFunction, + firstUnreadChapter?: FieldPolicy | FieldReadFunction, genre?: FieldPolicy | FieldReadFunction, id?: FieldPolicy | FieldReadFunction, inLibrary?: FieldPolicy | FieldReadFunction, diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts index 25262be7..2fd2ebae 100644 --- a/src/lib/graphql/generated/graphql.ts +++ b/src/lib/graphql/generated/graphql.ts @@ -938,6 +938,7 @@ export type MangaType = { chaptersLastFetchedAt?: Maybe; description?: Maybe; downloadCount: Scalars['Int']['output']; + firstUnreadChapter?: Maybe; genre: Array; id: Scalars['Int']['output']; inLibrary: Scalars['Boolean']['output']; @@ -3057,7 +3058,7 @@ export type GetMangaQuery = { __typename?: 'Query', manga: { __typename?: 'Manga export type GetMangaToMigrateQueryVariables = Exact<{ id: Scalars['Int']['input']; - migrateChapters: Scalars['Boolean']['input']; + getChapterData: Scalars['Boolean']['input']; migrateCategories: Scalars['Boolean']['input']; }>; diff --git a/src/lib/graphql/queries/MangaQuery.ts b/src/lib/graphql/queries/MangaQuery.ts index 8da3af80..53ab16ff 100644 --- a/src/lib/graphql/queries/MangaQuery.ts +++ b/src/lib/graphql/queries/MangaQuery.ts @@ -22,12 +22,12 @@ export const GET_MANGA = gql` // returns the current manga from the database export const GET_MANGA_TO_MIGRATE = gql` - query GET_MANGA_TO_MIGRATE($id: Int!, $migrateChapters: Boolean!, $migrateCategories: Boolean!) { + query GET_MANGA_TO_MIGRATE($id: Int!, $getChapterData: Boolean!, $migrateCategories: Boolean!) { manga(id: $id) { id inLibrary title - chapters @include(if: $migrateChapters) { + chapters @include(if: $getChapterData) { nodes { id manga { diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index 67000472..bb6d1ab9 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -1451,17 +1451,19 @@ export class RequestManager { { migrateChapters = false, migrateCategories = false, + deleteChapters = false, apolloOptions: options, }: { migrateChapters?: boolean; migrateCategories?: boolean; + deleteChapters?: boolean; apolloOptions?: QueryOptions; } = {}, ): AbortabaleApolloQueryResponse { return this.doRequest( GQLMethod.QUERY, GET_MANGA_TO_MIGRATE, - { id: Number(mangaId), migrateChapters, migrateCategories }, + { id: Number(mangaId), getChapterData: migrateChapters || deleteChapters, migrateCategories }, options, ); }