Feature/automatic chapter deletion more options (#484)

* Add missing translations keys

* [Codegen] Update to latest server schema changes

* [VersionMapping] Require server version "r1431" for preview

* Rename "deleteChaptersAutoMarkedRead" metadata setting

* Add more options to auto delete chapters while reading

Makes it possible to delete the last to fifth to last read chapter instead of only being able to delete the last read chapter
This commit is contained in:
schroda
2023-12-05 22:20:13 +01:00
committed by GitHub
parent ee03c56684
commit ad0f072651
15 changed files with 230 additions and 42 deletions

View File

@@ -416,7 +416,6 @@ export const WEBUI_UPDATE_INFO = gql`
fragment WEBUI_UPDATE_INFO on WebUIUpdateInfo {
channel
tag
updateAvailable
}
`;

View File

@@ -10,6 +10,11 @@ export type AboutServerPayloadFieldPolicy = {
revision?: FieldPolicy<any> | FieldReadFunction<any>,
version?: FieldPolicy<any> | FieldReadFunction<any>
};
export type AboutWebUIKeySpecifier = ('channel' | 'tag' | AboutWebUIKeySpecifier)[];
export type AboutWebUIFieldPolicy = {
channel?: FieldPolicy<any> | FieldReadFunction<any>,
tag?: FieldPolicy<any> | FieldReadFunction<any>
};
export type BackupRestoreStatusKeySpecifier = ('mangaProgress' | 'state' | 'totalManga' | BackupRestoreStatusKeySpecifier)[];
export type BackupRestoreStatusFieldPolicy = {
mangaProgress?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -105,6 +110,13 @@ export type CheckForServerUpdatesPayloadFieldPolicy = {
tag?: FieldPolicy<any> | FieldReadFunction<any>,
url?: FieldPolicy<any> | FieldReadFunction<any>
};
export type ClearCachedImagesPayloadKeySpecifier = ('cachedPages' | 'cachedThumbnails' | 'clientMutationId' | 'downloadedThumbnails' | ClearCachedImagesPayloadKeySpecifier)[];
export type ClearCachedImagesPayloadFieldPolicy = {
cachedPages?: FieldPolicy<any> | FieldReadFunction<any>,
cachedThumbnails?: FieldPolicy<any> | FieldReadFunction<any>,
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>,
downloadedThumbnails?: FieldPolicy<any> | FieldReadFunction<any>
};
export type ClearDownloaderPayloadKeySpecifier = ('clientMutationId' | 'downloadStatus' | ClearDownloaderPayloadKeySpecifier)[];
export type ClearDownloaderPayloadFieldPolicy = {
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -390,8 +402,9 @@ export type MultiSelectListPreferenceFieldPolicy = {
title?: FieldPolicy<any> | FieldReadFunction<any>,
visible?: FieldPolicy<any> | FieldReadFunction<any>
};
export type MutationKeySpecifier = ('clearDownloader' | 'createBackup' | 'createCategory' | 'deleteCategory' | 'deleteCategoryMeta' | 'deleteChapterMeta' | 'deleteDownloadedChapter' | 'deleteDownloadedChapters' | 'deleteGlobalMeta' | 'deleteMangaMeta' | 'dequeueChapterDownload' | 'dequeueChapterDownloads' | 'downloadAhead' | 'enqueueChapterDownload' | 'enqueueChapterDownloads' | 'fetchChapterPages' | 'fetchChapters' | 'fetchExtensions' | 'fetchManga' | 'fetchSourceManga' | 'installExternalExtension' | 'reorderChapterDownload' | 'resetSettings' | 'restoreBackup' | 'setCategoryMeta' | 'setChapterMeta' | 'setGlobalMeta' | 'setMangaMeta' | 'setSettings' | 'startDownloader' | 'stopDownloader' | 'updateCategories' | 'updateCategory' | 'updateCategoryManga' | 'updateCategoryOrder' | 'updateChapter' | 'updateChapters' | 'updateExtension' | 'updateExtensions' | 'updateLibraryManga' | 'updateManga' | 'updateMangaCategories' | 'updateMangas' | 'updateMangasCategories' | 'updateSourcePreference' | 'updateStop' | 'updateWebUI' | MutationKeySpecifier)[];
export type MutationKeySpecifier = ('clearCachedImages' | 'clearDownloader' | 'createBackup' | 'createCategory' | 'deleteCategory' | 'deleteCategoryMeta' | 'deleteChapterMeta' | 'deleteDownloadedChapter' | 'deleteDownloadedChapters' | 'deleteGlobalMeta' | 'deleteMangaMeta' | 'dequeueChapterDownload' | 'dequeueChapterDownloads' | 'downloadAhead' | 'enqueueChapterDownload' | 'enqueueChapterDownloads' | 'fetchChapterPages' | 'fetchChapters' | 'fetchExtensions' | 'fetchManga' | 'fetchSourceManga' | 'installExternalExtension' | 'reorderChapterDownload' | 'resetSettings' | 'restoreBackup' | 'setCategoryMeta' | 'setChapterMeta' | 'setGlobalMeta' | 'setMangaMeta' | 'setSettings' | 'startDownloader' | 'stopDownloader' | 'updateCategories' | 'updateCategory' | 'updateCategoryManga' | 'updateCategoryOrder' | 'updateChapter' | 'updateChapters' | 'updateExtension' | 'updateExtensions' | 'updateLibraryManga' | 'updateManga' | 'updateMangaCategories' | 'updateMangas' | 'updateMangasCategories' | 'updateSourcePreference' | 'updateStop' | 'updateWebUI' | MutationKeySpecifier)[];
export type MutationFieldPolicy = {
clearCachedImages?: FieldPolicy<any> | FieldReadFunction<any>,
clearDownloader?: FieldPolicy<any> | FieldReadFunction<any>,
createBackup?: FieldPolicy<any> | FieldReadFunction<any>,
createCategory?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -814,6 +827,12 @@ export type ValidateBackupSourceFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>,
name?: FieldPolicy<any> | FieldReadFunction<any>
};
export type WebUIUpdateCheckKeySpecifier = ('channel' | 'tag' | 'updateAvailable' | WebUIUpdateCheckKeySpecifier)[];
export type WebUIUpdateCheckFieldPolicy = {
channel?: FieldPolicy<any> | FieldReadFunction<any>,
tag?: FieldPolicy<any> | FieldReadFunction<any>,
updateAvailable?: FieldPolicy<any> | FieldReadFunction<any>
};
export type WebUIUpdateInfoKeySpecifier = ('channel' | 'tag' | 'updateAvailable' | WebUIUpdateInfoKeySpecifier)[];
export type WebUIUpdateInfoFieldPolicy = {
channel?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -836,6 +855,10 @@ export type StrictTypedTypePolicies = {
keyFields?: false | AboutServerPayloadKeySpecifier | (() => undefined | AboutServerPayloadKeySpecifier),
fields?: AboutServerPayloadFieldPolicy,
},
AboutWebUI?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | AboutWebUIKeySpecifier | (() => undefined | AboutWebUIKeySpecifier),
fields?: AboutWebUIFieldPolicy,
},
BackupRestoreStatus?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | BackupRestoreStatusKeySpecifier | (() => undefined | BackupRestoreStatusKeySpecifier),
fields?: BackupRestoreStatusFieldPolicy,
@@ -884,6 +907,10 @@ export type StrictTypedTypePolicies = {
keyFields?: false | CheckForServerUpdatesPayloadKeySpecifier | (() => undefined | CheckForServerUpdatesPayloadKeySpecifier),
fields?: CheckForServerUpdatesPayloadFieldPolicy,
},
ClearCachedImagesPayload?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | ClearCachedImagesPayloadKeySpecifier | (() => undefined | ClearCachedImagesPayloadKeySpecifier),
fields?: ClearCachedImagesPayloadFieldPolicy,
},
ClearDownloaderPayload?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | ClearDownloaderPayloadKeySpecifier | (() => undefined | ClearDownloaderPayloadKeySpecifier),
fields?: ClearDownloaderPayloadFieldPolicy,
@@ -1248,6 +1275,10 @@ export type StrictTypedTypePolicies = {
keyFields?: false | ValidateBackupSourceKeySpecifier | (() => undefined | ValidateBackupSourceKeySpecifier),
fields?: ValidateBackupSourceFieldPolicy,
},
WebUIUpdateCheck?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | WebUIUpdateCheckKeySpecifier | (() => undefined | WebUIUpdateCheckKeySpecifier),
fields?: WebUIUpdateCheckFieldPolicy,
},
WebUIUpdateInfo?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | WebUIUpdateInfoKeySpecifier | (() => undefined | WebUIUpdateInfoKeySpecifier),
fields?: WebUIUpdateInfoFieldPolicy,

View File

@@ -28,6 +28,12 @@ export type AboutServerPayload = {
version: Scalars['String']['output'];
};
export type AboutWebUi = {
__typename?: 'AboutWebUI';
channel: Scalars['String']['output'];
tag: Scalars['String']['output'];
};
export enum BackupRestoreState {
Failure = 'FAILURE',
Idle = 'IDLE',
@@ -244,6 +250,21 @@ export type CheckForServerUpdatesPayload = {
url: Scalars['String']['output'];
};
export type ClearCachedImagesInput = {
cachedPages?: InputMaybe<Scalars['Boolean']['input']>;
cachedThumbnails?: InputMaybe<Scalars['Boolean']['input']>;
clientMutationId?: InputMaybe<Scalars['String']['input']>;
downloadedThumbnails?: InputMaybe<Scalars['Boolean']['input']>;
};
export type ClearCachedImagesPayload = {
__typename?: 'ClearCachedImagesPayload';
cachedPages?: Maybe<Scalars['Boolean']['output']>;
cachedThumbnails?: Maybe<Scalars['Boolean']['output']>;
clientMutationId?: Maybe<Scalars['String']['output']>;
downloadedThumbnails?: Maybe<Scalars['Boolean']['output']>;
};
export type ClearDownloaderInput = {
clientMutationId?: InputMaybe<Scalars['String']['input']>;
};
@@ -907,6 +928,7 @@ export type MultiSelectListPreference = {
export type Mutation = {
__typename?: 'Mutation';
clearCachedImages: ClearCachedImagesPayload;
clearDownloader: ClearDownloaderPayload;
createBackup: CreateBackupPayload;
createCategory: CreateCategoryPayload;
@@ -957,6 +979,11 @@ export type Mutation = {
};
export type MutationClearCachedImagesArgs = {
input: ClearCachedImagesInput;
};
export type MutationClearDownloaderArgs = {
input: ClearDownloaderInput;
};
@@ -1294,13 +1321,13 @@ export type Preference = CheckBoxPreference | EditTextPreference | ListPreferenc
export type Query = {
__typename?: 'Query';
aboutServer: AboutServerPayload;
aboutWebUI: WebUiUpdateInfo;
aboutWebUI: AboutWebUi;
categories: CategoryNodeList;
category: CategoryType;
chapter: ChapterType;
chapters: ChapterNodeList;
checkForServerUpdates: Array<CheckForServerUpdatesPayload>;
checkForWebUIUpdate: WebUiUpdateInfo;
checkForWebUIUpdate: WebUiUpdateCheck;
downloadStatus: DownloadStatus;
extension: ExtensionType;
extensions: ExtensionNodeList;
@@ -2055,6 +2082,13 @@ export enum WebUiInterface {
Electron = 'ELECTRON'
}
export type WebUiUpdateCheck = {
__typename?: 'WebUIUpdateCheck';
channel: Scalars['String']['output'];
tag: Scalars['String']['output'];
updateAvailable: Scalars['Boolean']['output'];
};
export type WebUiUpdateInfo = {
__typename?: 'WebUIUpdateInfo';
channel: Scalars['String']['output'];
@@ -2109,9 +2143,9 @@ export type PartialUpdaterStatusFragment = { __typename?: 'UpdateStatus', isRunn
export type FullUpdaterStatusFragment = { __typename?: 'UpdateStatus', isRunning: boolean, completeJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', unreadCount: number, downloadCount: number, artist?: string | null, author?: string | null, chaptersLastFetchedAt?: any | null, description?: string | null, genre: Array<string>, id: number, inLibrary: boolean, inLibraryAt: any, initialized: boolean, lastFetchedAt?: any | null, realUrl?: string | null, status: MangaStatus, thumbnailUrl?: string | null, title: string, url: string, chapters: { __typename?: 'ChapterNodeList', totalCount: number }, meta: Array<{ __typename?: 'MangaMetaType', key: string, value: string }>, source?: { __typename?: 'SourceType', displayName: string, iconUrl: string, id: any, isConfigurable: boolean, isNsfw: boolean, lang: string, name: string, supportsLatest: boolean } | null }> } }, failedJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null }> } }, pendingJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null }> } }, runningJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null }> } }, skippedJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null }> } }, updatingCategories: { __typename?: 'UpdateStatusCategoryType', categories: { __typename?: 'CategoryNodeList', totalCount: number, nodes: Array<{ __typename?: 'CategoryType', id: number, name: string, includeInUpdate: IncludeInUpdate }> } }, skippedCategories: { __typename?: 'UpdateStatusCategoryType', categories: { __typename?: 'CategoryNodeList', totalCount: number, nodes: Array<{ __typename?: 'CategoryType', id: number, name: string, includeInUpdate: IncludeInUpdate }> } } };
export type WebuiUpdateInfoFragment = { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean };
export type WebuiUpdateInfoFragment = { __typename?: 'WebUIUpdateInfo', channel: string, tag: string };
export type WebuiUpdateStatusFragment = { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean } };
export type WebuiUpdateStatusFragment = { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string } };
export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string };
@@ -2218,6 +2252,7 @@ export type UpdateChapterMutationVariables = Exact<{
getRead: Scalars['Boolean']['input'];
getLastPageRead: Scalars['Boolean']['input'];
id: Scalars['Int']['input'];
chapterIdToDelete: Scalars['Int']['input'];
deleteChapter: Scalars['Boolean']['input'];
mangaId: Scalars['Int']['input'];
downloadAhead: Scalars['Boolean']['input'];
@@ -2414,7 +2449,7 @@ export type UpdateWebuiMutationVariables = Exact<{
}>;
export type UpdateWebuiMutation = { __typename?: 'Mutation', updateWebUI: { __typename?: 'WebUIUpdatePayload', clientMutationId?: string | null, updateStatus: { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean } } } };
export type UpdateWebuiMutation = { __typename?: 'Mutation', updateWebUI: { __typename?: 'WebUIUpdatePayload', clientMutationId?: string | null, updateStatus: { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string } } } };
export type ResetServerSettingsMutationVariables = Exact<{
input: ResetSettingsInput;
@@ -2604,7 +2639,7 @@ export type GetMangasQuery = { __typename?: 'Query', mangas: { __typename?: 'Man
export type GetAboutQueryVariables = Exact<{ [key: string]: never; }>;
export type GetAboutQuery = { __typename?: 'Query', aboutServer: { __typename?: 'AboutServerPayload', buildTime: any, buildType: string, discord: string, github: string, name: string, revision: string, version: string }, aboutWebUI: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean } };
export type GetAboutQuery = { __typename?: 'Query', aboutServer: { __typename?: 'AboutServerPayload', buildTime: any, buildType: string, discord: string, github: string, name: string, revision: string, version: string }, aboutWebUI: { __typename?: 'AboutWebUI', channel: string, tag: string } };
export type CheckForServerUpdatesQueryVariables = Exact<{ [key: string]: never; }>;
@@ -2614,12 +2649,12 @@ export type CheckForServerUpdatesQuery = { __typename?: 'Query', checkForServerU
export type CheckForWebuiUpdateQueryVariables = Exact<{ [key: string]: never; }>;
export type CheckForWebuiUpdateQuery = { __typename?: 'Query', checkForWebUIUpdate: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean } };
export type CheckForWebuiUpdateQuery = { __typename?: 'Query', checkForWebUIUpdate: { __typename?: 'WebUIUpdateCheck', channel: string, tag: string, updateAvailable: boolean } };
export type GetWebuiUpdateStatusQueryVariables = Exact<{ [key: string]: never; }>;
export type GetWebuiUpdateStatusQuery = { __typename?: 'Query', getWebUIUpdateStatus: { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean } } };
export type GetWebuiUpdateStatusQuery = { __typename?: 'Query', getWebUIUpdateStatus: { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string } } };
export type GetServerSettingsQueryVariables = Exact<{ [key: string]: never; }>;
@@ -2656,7 +2691,7 @@ export type DownloadStatusSubscription = { __typename?: 'Subscription', download
export type WebuiUpdateSubscriptionVariables = Exact<{ [key: string]: never; }>;
export type WebuiUpdateSubscription = { __typename?: 'Subscription', webUIUpdateStatusChange: { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string, updateAvailable: boolean } } };
export type WebuiUpdateSubscription = { __typename?: 'Subscription', webUIUpdateStatusChange: { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string } } };
export type UpdaterSubscriptionVariables = Exact<{ [key: string]: never; }>;

View File

@@ -88,6 +88,7 @@ export const UPDATE_CHAPTER = gql`
$getRead: Boolean!
$getLastPageRead: Boolean!
$id: Int!
$chapterIdToDelete: Int!
$deleteChapter: Boolean!
$mangaId: Int!
$downloadAhead: Boolean!
@@ -109,7 +110,7 @@ export const UPDATE_CHAPTER = gql`
}
}
}
deleteDownloadedChapter(input: { id: $id }) @include(if: $deleteChapter) {
deleteDownloadedChapter(input: { id: $chapterIdToDelete }) @include(if: $deleteChapter) {
clientMutationId
chapters {
id

View File

@@ -7,7 +7,7 @@
*/
import gql from 'graphql-tag';
import { WEBUI_UPDATE_INFO, WEBUI_UPDATE_STATUS } from '@/lib/graphql/Fragments';
import { WEBUI_UPDATE_STATUS } from '@/lib/graphql/Fragments';
export const GET_ABOUT = gql`
query GET_ABOUT {
@@ -23,7 +23,6 @@ export const GET_ABOUT = gql`
aboutWebUI {
channel
tag
updateAvailable
}
}
`;
@@ -39,10 +38,11 @@ export const CHECK_FOR_SERVER_UPDATES = gql`
`;
export const CHECK_FOR_WEBUI_UPDATE = gql`
${WEBUI_UPDATE_INFO}
query CHECK_FOR_WEBUI_UPDATE {
checkForWebUIUpdate {
...WEBUI_UPDATE_INFO
channel
tag
updateAvailable
}
}
`;

View File

@@ -1498,10 +1498,13 @@ export class RequestManager {
public updateChapter(
id: number,
patch: UpdateChapterPatchInput & { deleteChapter?: boolean; downloadAheadMangaId?: number },
patch: UpdateChapterPatchInput & {
chapterIdToDelete?: number;
downloadAheadMangaId?: number;
},
options?: MutationOptions<UpdateChapterMutation, UpdateChapterMutationVariables>,
): AbortableApolloMutationResponse<UpdateChapterMutation> {
const { deleteChapter, downloadAheadMangaId = -1, ...updatePatch } = patch;
const { chapterIdToDelete = -1, downloadAheadMangaId = -1, ...updatePatch } = patch;
return this.doRequest<UpdateChapterMutation, UpdateChapterMutationVariables>(
GQLMethod.MUTATION,
@@ -1512,7 +1515,8 @@ export class RequestManager {
getBookmarked: patch.isBookmarked != null,
getRead: patch.isRead != null,
getLastPageRead: patch.lastPageRead != null,
deleteChapter: !!deleteChapter,
chapterIdToDelete,
deleteChapter: chapterIdToDelete >= 0,
mangaId: downloadAheadMangaId,
downloadAhead: downloadAheadMangaId !== -1,
},