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 [includeChapters, setIncludeChapters] = useState(true);
|
||||||
const [includeCategories, setIncludeCategories] = useState(true);
|
const [includeCategories, setIncludeCategories] = useState(true);
|
||||||
|
const [deleteChapters, setDeleteChapters] = useState(true);
|
||||||
|
|
||||||
const [isMigrationInProcess, setIsMigrationInProcess] = useState(false);
|
const [isMigrationInProcess, setIsMigrationInProcess] = useState(false);
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat
|
|||||||
mode,
|
mode,
|
||||||
migrateChapters: includeChapters,
|
migrateChapters: includeChapters,
|
||||||
migrateCategories: includeCategories,
|
migrateCategories: includeCategories,
|
||||||
|
deleteChapters,
|
||||||
});
|
});
|
||||||
|
|
||||||
navigate(`/manga/${mangaIdToMigrateTo}`, { replace: true });
|
navigate(`/manga/${mangaIdToMigrateTo}`, { replace: true });
|
||||||
@@ -72,6 +74,12 @@ export const MigrateDialog = ({ mangaIdToMigrateTo, onClose }: { mangaIdToMigrat
|
|||||||
checked={includeCategories}
|
checked={includeCategories}
|
||||||
onChange={(_, checked) => setIncludeCategories(checked)}
|
onChange={(_, checked) => setIncludeCategories(checked)}
|
||||||
/>
|
/>
|
||||||
|
<CheckboxInput
|
||||||
|
disabled={isMigrationInProcess}
|
||||||
|
label={t('migrate.dialog.label.delete_downloaded')}
|
||||||
|
checked={deleteChapters}
|
||||||
|
onChange={(_, checked) => setDeleteChapters(checked)}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
|
|||||||
@@ -615,6 +615,9 @@
|
|||||||
"show_entry": "Show entry"
|
"show_entry": "Show entry"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"label": {
|
||||||
|
"delete_downloaded": "Delete downloaded"
|
||||||
|
},
|
||||||
"title": "Select data to include"
|
"title": "Select data to include"
|
||||||
},
|
},
|
||||||
"label": {
|
"label": {
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ type MigrateOptions = {
|
|||||||
mode: MigrateMode;
|
mode: MigrateMode;
|
||||||
migrateChapters?: boolean;
|
migrateChapters?: boolean;
|
||||||
migrateCategories?: boolean;
|
migrateCategories?: boolean;
|
||||||
|
deleteChapters?: boolean;
|
||||||
};
|
};
|
||||||
type PerformActionOptions<Action extends MangaAction> = Action extends 'mark_as_read'
|
type PerformActionOptions<Action extends MangaAction> = Action extends 'mark_as_read'
|
||||||
? MarkAsReadOptions & PropertiesNever<ChangeCategoriesOptions> & PropertiesNever<MigrateOptions>
|
? MarkAsReadOptions & PropertiesNever<ChangeCategoriesOptions> & PropertiesNever<MigrateOptions>
|
||||||
@@ -279,11 +280,12 @@ export class Mangas {
|
|||||||
static async migrate(
|
static async migrate(
|
||||||
mangaId: number,
|
mangaId: number,
|
||||||
mangaIdToMigrateTo: number,
|
mangaIdToMigrateTo: number,
|
||||||
{ mode, migrateChapters, migrateCategories }: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
{ mode, migrateChapters, migrateCategories, deleteChapters }: Omit<MigrateOptions, 'mangaIdToMigrateTo'>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return Mangas.executeAction('migrate', 1, async () => {
|
return Mangas.executeAction('migrate', 1, async () => {
|
||||||
const [{ data: mangaToMigrateData }, { data: mangaToMigrateToData }] = await Promise.all([
|
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 })
|
requestManager.getMangaToMigrateToFetch(mangaIdToMigrateTo, { migrateChapters, migrateCategories })
|
||||||
.response,
|
.response,
|
||||||
]);
|
]);
|
||||||
@@ -301,6 +303,11 @@ export class Mangas {
|
|||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
migrateChapters ? Mangas.migrateChapters(mangaToMigrateData.manga, mangaToMigrateToData) : undefined,
|
migrateChapters ? Mangas.migrateChapters(mangaToMigrateData.manga, mangaToMigrateToData) : undefined,
|
||||||
|
deleteChapters
|
||||||
|
? requestManager.deleteDownloadedChapters(
|
||||||
|
Chapters.getIds(Chapters.getDownloaded(mangaToMigrateData.manga.chapters?.nodes ?? [])),
|
||||||
|
).response
|
||||||
|
: undefined,
|
||||||
migrateCategories
|
migrateCategories
|
||||||
? Mangas.migrateCategories(mangaToMigrateData.manga, mangaToMigrateToData.fetchManga.manga)
|
? Mangas.migrateCategories(mangaToMigrateData.manga, mangaToMigrateToData.fetchManga.manga)
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|||||||
@@ -383,7 +383,7 @@ export type MangaNodeListFieldPolicy = {
|
|||||||
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
totalCount?: 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 = {
|
export type MangaTypeFieldPolicy = {
|
||||||
age?: FieldPolicy<any> | FieldReadFunction<any>,
|
age?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
artist?: FieldPolicy<any> | FieldReadFunction<any>,
|
artist?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -394,6 +394,7 @@ export type MangaTypeFieldPolicy = {
|
|||||||
chaptersLastFetchedAt?: FieldPolicy<any> | FieldReadFunction<any>,
|
chaptersLastFetchedAt?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
description?: FieldPolicy<any> | FieldReadFunction<any>,
|
description?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
downloadCount?: FieldPolicy<any> | FieldReadFunction<any>,
|
downloadCount?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
firstUnreadChapter?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
genre?: FieldPolicy<any> | FieldReadFunction<any>,
|
genre?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
id?: FieldPolicy<any> | FieldReadFunction<any>,
|
id?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
inLibrary?: FieldPolicy<any> | FieldReadFunction<any>,
|
inLibrary?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
|||||||
@@ -938,6 +938,7 @@ export type MangaType = {
|
|||||||
chaptersLastFetchedAt?: Maybe<Scalars['LongString']['output']>;
|
chaptersLastFetchedAt?: Maybe<Scalars['LongString']['output']>;
|
||||||
description?: Maybe<Scalars['String']['output']>;
|
description?: Maybe<Scalars['String']['output']>;
|
||||||
downloadCount: Scalars['Int']['output'];
|
downloadCount: Scalars['Int']['output'];
|
||||||
|
firstUnreadChapter?: Maybe<ChapterType>;
|
||||||
genre: Array<Scalars['String']['output']>;
|
genre: Array<Scalars['String']['output']>;
|
||||||
id: Scalars['Int']['output'];
|
id: Scalars['Int']['output'];
|
||||||
inLibrary: Scalars['Boolean']['output'];
|
inLibrary: Scalars['Boolean']['output'];
|
||||||
@@ -3057,7 +3058,7 @@ export type GetMangaQuery = { __typename?: 'Query', manga: { __typename?: 'Manga
|
|||||||
|
|
||||||
export type GetMangaToMigrateQueryVariables = Exact<{
|
export type GetMangaToMigrateQueryVariables = Exact<{
|
||||||
id: Scalars['Int']['input'];
|
id: Scalars['Int']['input'];
|
||||||
migrateChapters: Scalars['Boolean']['input'];
|
getChapterData: Scalars['Boolean']['input'];
|
||||||
migrateCategories: Scalars['Boolean']['input'];
|
migrateCategories: Scalars['Boolean']['input'];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ export const GET_MANGA = gql`
|
|||||||
|
|
||||||
// returns the current manga from the database
|
// returns the current manga from the database
|
||||||
export const GET_MANGA_TO_MIGRATE = gql`
|
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) {
|
manga(id: $id) {
|
||||||
id
|
id
|
||||||
inLibrary
|
inLibrary
|
||||||
title
|
title
|
||||||
chapters @include(if: $migrateChapters) {
|
chapters @include(if: $getChapterData) {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
id
|
||||||
manga {
|
manga {
|
||||||
|
|||||||
@@ -1451,17 +1451,19 @@ export class RequestManager {
|
|||||||
{
|
{
|
||||||
migrateChapters = false,
|
migrateChapters = false,
|
||||||
migrateCategories = false,
|
migrateCategories = false,
|
||||||
|
deleteChapters = false,
|
||||||
apolloOptions: options,
|
apolloOptions: options,
|
||||||
}: {
|
}: {
|
||||||
migrateChapters?: boolean;
|
migrateChapters?: boolean;
|
||||||
migrateCategories?: boolean;
|
migrateCategories?: boolean;
|
||||||
|
deleteChapters?: boolean;
|
||||||
apolloOptions?: QueryOptions<GetMangaToMigrateQueryVariables, GetMangaToMigrateQuery>;
|
apolloOptions?: QueryOptions<GetMangaToMigrateQueryVariables, GetMangaToMigrateQuery>;
|
||||||
} = {},
|
} = {},
|
||||||
): AbortabaleApolloQueryResponse<GetMangaToMigrateQuery> {
|
): AbortabaleApolloQueryResponse<GetMangaToMigrateQuery> {
|
||||||
return this.doRequest(
|
return this.doRequest(
|
||||||
GQLMethod.QUERY,
|
GQLMethod.QUERY,
|
||||||
GET_MANGA_TO_MIGRATE,
|
GET_MANGA_TO_MIGRATE,
|
||||||
{ id: Number(mangaId), migrateChapters, migrateCategories },
|
{ id: Number(mangaId), getChapterData: migrateChapters || deleteChapters, migrateCategories },
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user