Add option to delete downloaded chapters on migration (#655)
This commit is contained in:
@@ -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)}
|
||||
/>
|
||||
<CheckboxInput
|
||||
disabled={isMigrationInProcess}
|
||||
label={t('migrate.dialog.label.delete_downloaded')}
|
||||
checked={deleteChapters}
|
||||
onChange={(_, checked) => setDeleteChapters(checked)}
|
||||
/>
|
||||
</FormGroup>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
|
||||
@@ -615,6 +615,9 @@
|
||||
"show_entry": "Show entry"
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"delete_downloaded": "Delete downloaded"
|
||||
},
|
||||
"title": "Select data to include"
|
||||
},
|
||||
"label": {
|
||||
|
||||
@@ -111,6 +111,7 @@ type MigrateOptions = {
|
||||
mode: MigrateMode;
|
||||
migrateChapters?: boolean;
|
||||
migrateCategories?: boolean;
|
||||
deleteChapters?: boolean;
|
||||
};
|
||||
type PerformActionOptions<Action extends MangaAction> = Action extends 'mark_as_read'
|
||||
? MarkAsReadOptions & PropertiesNever<ChangeCategoriesOptions> & PropertiesNever<MigrateOptions>
|
||||
@@ -279,11 +280,12 @@ export class Mangas {
|
||||
static async migrate(
|
||||
mangaId: number,
|
||||
mangaIdToMigrateTo: number,
|
||||
{ mode, migrateChapters, migrateCategories }: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
||||
{ mode, migrateChapters, migrateCategories, deleteChapters }: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
||||
): Promise<void> {
|
||||
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,
|
||||
|
||||
@@ -383,7 +383,7 @@ export type MangaNodeListFieldPolicy = {
|
||||
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
totalCount?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
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<any> | FieldReadFunction<any>,
|
||||
artist?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -394,6 +394,7 @@ export type MangaTypeFieldPolicy = {
|
||||
chaptersLastFetchedAt?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
description?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
downloadCount?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
firstUnreadChapter?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
genre?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
id?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
inLibrary?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
|
||||
@@ -938,6 +938,7 @@ export type MangaType = {
|
||||
chaptersLastFetchedAt?: Maybe<Scalars['LongString']['output']>;
|
||||
description?: Maybe<Scalars['String']['output']>;
|
||||
downloadCount: Scalars['Int']['output'];
|
||||
firstUnreadChapter?: Maybe<ChapterType>;
|
||||
genre: Array<Scalars['String']['output']>;
|
||||
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'];
|
||||
}>;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1451,17 +1451,19 @@ export class RequestManager {
|
||||
{
|
||||
migrateChapters = false,
|
||||
migrateCategories = false,
|
||||
deleteChapters = false,
|
||||
apolloOptions: options,
|
||||
}: {
|
||||
migrateChapters?: boolean;
|
||||
migrateCategories?: boolean;
|
||||
deleteChapters?: boolean;
|
||||
apolloOptions?: QueryOptions<GetMangaToMigrateQueryVariables, GetMangaToMigrateQuery>;
|
||||
} = {},
|
||||
): AbortabaleApolloQueryResponse<GetMangaToMigrateQuery> {
|
||||
return this.doRequest(
|
||||
GQLMethod.QUERY,
|
||||
GET_MANGA_TO_MIGRATE,
|
||||
{ id: Number(mangaId), migrateChapters, migrateCategories },
|
||||
{ id: Number(mangaId), getChapterData: migrateChapters || deleteChapters, migrateCategories },
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user