diff --git a/gql_codegen.ts b/gql_codegen.ts index 397e6a1a..d3581c12 100644 --- a/gql_codegen.ts +++ b/gql_codegen.ts @@ -10,7 +10,7 @@ import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { overwrite: true, - schema: 'http://localhost:45670/api/graphql', + schema: 'http://localhost:4567/api/graphql', documents: [ 'src/lib/graphql/queries/**', 'src/lib/graphql/mutations/**', diff --git a/src/lib/graphql/fragments/UpdaterFragments.ts b/src/lib/graphql/fragments/UpdaterFragments.ts index 453322c1..e28520e6 100644 --- a/src/lib/graphql/fragments/UpdaterFragments.ts +++ b/src/lib/graphql/fragments/UpdaterFragments.ts @@ -7,77 +7,76 @@ */ import gql from 'graphql-tag'; -import { MANGA_CHAPTER_STAT_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts'; const UPDATER_MANGA_FIELDS = gql` - fragment UPDATER_MANGA_FIELDS on MangaType { - id - title - thumbnailUrl + fragment UPDATER_MANGA_FIELDS on MangaUpdateType { + status + manga { + id + title + thumbnailUrl + } + } +`; + +const UPDATER_CATEGORY_FIELDS = gql` + fragment UPDATER_CATEGORY_FIELDS on CategoryUpdateType { + status + category { + id + name + } + } +`; + +const UPDATER_JOB_INFO_FIELDS = gql` + fragment UPDATER_JOB_INFO_FIELDS on UpdaterJobsInfoType { + isRunning + totalJobs + finishedJobs + skippedCategoriesCount + skippedMangasCount + } +`; + +export const UPDATER_STATUS_FIELDS = gql` + ${UPDATER_JOB_INFO_FIELDS} + ${UPDATER_CATEGORY_FIELDS} + ${UPDATER_MANGA_FIELDS} + + fragment UPDATER_STATUS_FIELDS on LibraryUpdateStatus { + jobsInfo { + ...UPDATER_JOB_INFO_FIELDS + } + + categoryUpdates { + ...UPDATER_CATEGORY_FIELDS + } + + mangaUpdates { + ...UPDATER_MANGA_FIELDS + } } `; export const UPDATER_SUBSCRIPTION_FIELDS = gql` + ${UPDATER_JOB_INFO_FIELDS} + ${UPDATER_CATEGORY_FIELDS} ${UPDATER_MANGA_FIELDS} - ${MANGA_CHAPTER_STAT_FIELDS} - fragment UPDATER_SUBSCRIPTION_FIELDS on UpdateStatus { - isRunning + fragment UPDATER_SUBSCRIPTION_FIELDS on UpdaterUpdates { + omittedUpdates - completeJobs { - mangas { - totalCount - nodes { - ...MANGA_CHAPTER_STAT_FIELDS + jobsInfo { + ...UPDATER_JOB_INFO_FIELDS + } - firstUnreadChapter { - id - sourceOrder - } - lastReadChapter { - id - sourceOrder - lastReadAt - } - latestReadChapter { - id - sourceOrder - lastReadAt - } - latestFetchedChapter { - id - fetchedAt - } - latestUploadedChapter { - id - uploadDate - } - } - } + categoryUpdates { + ...UPDATER_CATEGORY_FIELDS } - failedJobs { - mangas { - totalCount - nodes { - ...UPDATER_MANGA_FIELDS - } - } - } - pendingJobs { - mangas { - totalCount - nodes { - ...UPDATER_MANGA_FIELDS - } - } - } - runningJobs { - mangas { - totalCount - nodes { - ...UPDATER_MANGA_FIELDS - } - } + + mangaUpdates { + ...UPDATER_MANGA_FIELDS } } `; diff --git a/src/lib/graphql/generated/apollo-helpers.ts b/src/lib/graphql/generated/apollo-helpers.ts index f04124b9..d078f2ef 100644 --- a/src/lib/graphql/generated/apollo-helpers.ts +++ b/src/lib/graphql/generated/apollo-helpers.ts @@ -60,6 +60,11 @@ export type CategoryTypeFieldPolicy = { name?: FieldPolicy | FieldReadFunction, order?: FieldPolicy | FieldReadFunction }; +export type CategoryUpdateTypeKeySpecifier = ('category' | 'status' | CategoryUpdateTypeKeySpecifier)[]; +export type CategoryUpdateTypeFieldPolicy = { + category?: FieldPolicy | FieldReadFunction, + status?: FieldPolicy | FieldReadFunction +}; export type ChapterEdgeKeySpecifier = ('cursor' | 'node' | ChapterEdgeKeySpecifier)[]; export type ChapterEdgeFieldPolicy = { cursor?: FieldPolicy | FieldReadFunction, @@ -352,6 +357,12 @@ export type LastUpdateTimestampPayloadKeySpecifier = ('timestamp' | LastUpdateTi export type LastUpdateTimestampPayloadFieldPolicy = { timestamp?: FieldPolicy | FieldReadFunction }; +export type LibraryUpdateStatusKeySpecifier = ('categoryUpdates' | 'jobsInfo' | 'mangaUpdates' | LibraryUpdateStatusKeySpecifier)[]; +export type LibraryUpdateStatusFieldPolicy = { + categoryUpdates?: FieldPolicy | FieldReadFunction, + jobsInfo?: FieldPolicy | FieldReadFunction, + mangaUpdates?: FieldPolicy | FieldReadFunction +}; export type ListPreferenceKeySpecifier = ('currentValue' | 'default' | 'entries' | 'entryValues' | 'key' | 'summary' | 'title' | 'visible' | ListPreferenceKeySpecifier)[]; export type ListPreferenceFieldPolicy = { currentValue?: FieldPolicy | FieldReadFunction, @@ -437,6 +448,11 @@ export type MangaTypeFieldPolicy = { updateStrategy?: FieldPolicy | FieldReadFunction, url?: FieldPolicy | FieldReadFunction }; +export type MangaUpdateTypeKeySpecifier = ('manga' | 'status' | MangaUpdateTypeKeySpecifier)[]; +export type MangaUpdateTypeFieldPolicy = { + manga?: FieldPolicy | FieldReadFunction, + status?: FieldPolicy | FieldReadFunction +}; export type MetaEdgeKeySpecifier = ('cursor' | 'node' | MetaEdgeKeySpecifier)[]; export type MetaEdgeFieldPolicy = { cursor?: FieldPolicy | FieldReadFunction, @@ -460,7 +476,7 @@ export type MultiSelectListPreferenceFieldPolicy = { title?: FieldPolicy | FieldReadFunction, visible?: FieldPolicy | FieldReadFunction }; -export type MutationKeySpecifier = ('bindTrack' | 'clearCachedImages' | 'clearDownloader' | 'createBackup' | 'createCategory' | 'deleteCategory' | 'deleteCategoryMeta' | 'deleteChapterMeta' | 'deleteDownloadedChapter' | 'deleteDownloadedChapters' | 'deleteGlobalMeta' | 'deleteMangaMeta' | 'deleteSourceMeta' | 'dequeueChapterDownload' | 'dequeueChapterDownloads' | 'enqueueChapterDownload' | 'enqueueChapterDownloads' | 'fetchChapterPages' | 'fetchChapters' | 'fetchExtensions' | 'fetchManga' | 'fetchSourceManga' | 'fetchTrack' | 'installExternalExtension' | 'loginTrackerCredentials' | 'loginTrackerOAuth' | 'logoutTracker' | 'reorderChapterDownload' | 'resetSettings' | 'resetWebUIUpdateStatus' | 'restoreBackup' | 'setCategoryMeta' | 'setChapterMeta' | 'setGlobalMeta' | 'setMangaMeta' | 'setSettings' | 'setSourceMeta' | 'startDownloader' | 'stopDownloader' | 'trackProgress' | 'unbindTrack' | 'updateCategories' | 'updateCategory' | 'updateCategoryManga' | 'updateCategoryOrder' | 'updateChapter' | 'updateChapters' | 'updateExtension' | 'updateExtensions' | 'updateLibraryManga' | 'updateManga' | 'updateMangaCategories' | 'updateMangas' | 'updateMangasCategories' | 'updateSourcePreference' | 'updateStop' | 'updateTrack' | 'updateWebUI' | MutationKeySpecifier)[]; +export type MutationKeySpecifier = ('bindTrack' | 'clearCachedImages' | 'clearDownloader' | 'createBackup' | 'createCategory' | 'deleteCategory' | 'deleteCategoryMeta' | 'deleteChapterMeta' | 'deleteDownloadedChapter' | 'deleteDownloadedChapters' | 'deleteGlobalMeta' | 'deleteMangaMeta' | 'deleteSourceMeta' | 'dequeueChapterDownload' | 'dequeueChapterDownloads' | 'enqueueChapterDownload' | 'enqueueChapterDownloads' | 'fetchChapterPages' | 'fetchChapters' | 'fetchExtensions' | 'fetchManga' | 'fetchSourceManga' | 'fetchTrack' | 'installExternalExtension' | 'loginTrackerCredentials' | 'loginTrackerOAuth' | 'logoutTracker' | 'reorderChapterDownload' | 'resetSettings' | 'resetWebUIUpdateStatus' | 'restoreBackup' | 'setCategoryMeta' | 'setChapterMeta' | 'setGlobalMeta' | 'setMangaMeta' | 'setSettings' | 'setSourceMeta' | 'startDownloader' | 'stopDownloader' | 'trackProgress' | 'unbindTrack' | 'updateCategories' | 'updateCategory' | 'updateCategoryManga' | 'updateCategoryOrder' | 'updateChapter' | 'updateChapters' | 'updateExtension' | 'updateExtensions' | 'updateLibrary' | 'updateLibraryManga' | 'updateManga' | 'updateMangaCategories' | 'updateMangas' | 'updateMangasCategories' | 'updateSourcePreference' | 'updateStop' | 'updateTrack' | 'updateWebUI' | MutationKeySpecifier)[]; export type MutationFieldPolicy = { bindTrack?: FieldPolicy | FieldReadFunction, clearCachedImages?: FieldPolicy | FieldReadFunction, @@ -511,6 +527,7 @@ export type MutationFieldPolicy = { updateChapters?: FieldPolicy | FieldReadFunction, updateExtension?: FieldPolicy | FieldReadFunction, updateExtensions?: FieldPolicy | FieldReadFunction, + updateLibrary?: FieldPolicy | FieldReadFunction, updateLibraryManga?: FieldPolicy | FieldReadFunction, updateManga?: FieldPolicy | FieldReadFunction, updateMangaCategories?: FieldPolicy | FieldReadFunction, @@ -586,7 +603,7 @@ export type PartialSettingsTypeFieldPolicy = { webUIInterface?: FieldPolicy | FieldReadFunction, webUIUpdateCheckInterval?: FieldPolicy | FieldReadFunction }; -export type QueryKeySpecifier = ('aboutServer' | 'aboutWebUI' | 'categories' | 'category' | 'chapter' | 'chapters' | 'checkForServerUpdates' | 'checkForWebUIUpdate' | 'downloadStatus' | 'extension' | 'extensions' | 'getWebUIUpdateStatus' | 'lastUpdateTimestamp' | 'manga' | 'mangas' | 'meta' | 'metas' | 'restoreStatus' | 'searchTracker' | 'settings' | 'source' | 'sources' | 'trackRecord' | 'trackRecords' | 'tracker' | 'trackers' | 'updateStatus' | 'validateBackup' | QueryKeySpecifier)[]; +export type QueryKeySpecifier = ('aboutServer' | 'aboutWebUI' | 'categories' | 'category' | 'chapter' | 'chapters' | 'checkForServerUpdates' | 'checkForWebUIUpdate' | 'downloadStatus' | 'extension' | 'extensions' | 'getWebUIUpdateStatus' | 'lastUpdateTimestamp' | 'libraryUpdateStatus' | 'manga' | 'mangas' | 'meta' | 'metas' | 'restoreStatus' | 'searchTracker' | 'settings' | 'source' | 'sources' | 'trackRecord' | 'trackRecords' | 'tracker' | 'trackers' | 'updateStatus' | 'validateBackup' | QueryKeySpecifier)[]; export type QueryFieldPolicy = { aboutServer?: FieldPolicy | FieldReadFunction, aboutWebUI?: FieldPolicy | FieldReadFunction, @@ -601,6 +618,7 @@ export type QueryFieldPolicy = { extensions?: FieldPolicy | FieldReadFunction, getWebUIUpdateStatus?: FieldPolicy> | FieldReadFunction>, lastUpdateTimestamp?: FieldPolicy | FieldReadFunction, + libraryUpdateStatus?: FieldPolicy> | FieldReadFunction>, manga?: FieldPolicy> | FieldReadFunction>, mangas?: FieldPolicy | FieldReadFunction, meta?: FieldPolicy> | FieldReadFunction>, @@ -614,7 +632,7 @@ export type QueryFieldPolicy = { trackRecords?: FieldPolicy | FieldReadFunction, tracker?: FieldPolicy | FieldReadFunction, trackers?: FieldPolicy | FieldReadFunction, - updateStatus?: FieldPolicy> | FieldReadFunction>, + updateStatus?: FieldPolicy | FieldReadFunction, validateBackup?: FieldPolicy | FieldReadFunction }; export type ReorderChapterDownloadPayloadKeySpecifier = ('clientMutationId' | 'downloadStatus' | ReorderChapterDownloadPayloadKeySpecifier)[]; @@ -835,10 +853,11 @@ export type StopDownloaderPayloadFieldPolicy = { clientMutationId?: FieldPolicy | FieldReadFunction, downloadStatus?: FieldPolicy | FieldReadFunction }; -export type SubscriptionKeySpecifier = ('downloadChanged' | 'downloadStatusChanged' | 'updateStatusChanged' | 'webUIUpdateStatusChange' | SubscriptionKeySpecifier)[]; +export type SubscriptionKeySpecifier = ('downloadChanged' | 'downloadStatusChanged' | 'libraryUpdateStatusChanged' | 'updateStatusChanged' | 'webUIUpdateStatusChange' | SubscriptionKeySpecifier)[]; export type SubscriptionFieldPolicy = { downloadChanged?: FieldPolicy | FieldReadFunction, downloadStatusChanged?: FieldPolicy | FieldReadFunction, + libraryUpdateStatusChanged?: FieldPolicy | FieldReadFunction, updateStatusChanged?: FieldPolicy | FieldReadFunction, webUIUpdateStatusChange?: FieldPolicy | FieldReadFunction }; @@ -992,6 +1011,11 @@ export type UpdateLibraryMangaPayloadFieldPolicy = { clientMutationId?: FieldPolicy | FieldReadFunction, updateStatus?: FieldPolicy | FieldReadFunction }; +export type UpdateLibraryPayloadKeySpecifier = ('clientMutationId' | 'updateStatus' | UpdateLibraryPayloadKeySpecifier)[]; +export type UpdateLibraryPayloadFieldPolicy = { + clientMutationId?: FieldPolicy | FieldReadFunction, + updateStatus?: FieldPolicy | FieldReadFunction +}; export type UpdateMangaCategoriesPayloadKeySpecifier = ('clientMutationId' | 'manga' | UpdateMangaCategoriesPayloadKeySpecifier)[]; export type UpdateMangaCategoriesPayloadFieldPolicy = { clientMutationId?: FieldPolicy | FieldReadFunction, @@ -1046,6 +1070,22 @@ export type UpdateTrackPayloadFieldPolicy = { clientMutationId?: FieldPolicy | FieldReadFunction, trackRecord?: FieldPolicy | FieldReadFunction }; +export type UpdaterJobsInfoTypeKeySpecifier = ('finishedJobs' | 'isRunning' | 'skippedCategoriesCount' | 'skippedMangasCount' | 'totalJobs' | UpdaterJobsInfoTypeKeySpecifier)[]; +export type UpdaterJobsInfoTypeFieldPolicy = { + finishedJobs?: FieldPolicy | FieldReadFunction, + isRunning?: FieldPolicy | FieldReadFunction, + skippedCategoriesCount?: FieldPolicy | FieldReadFunction, + skippedMangasCount?: FieldPolicy | FieldReadFunction, + totalJobs?: FieldPolicy | FieldReadFunction +}; +export type UpdaterUpdatesKeySpecifier = ('categoryUpdates' | 'initial' | 'jobsInfo' | 'mangaUpdates' | 'omittedUpdates' | UpdaterUpdatesKeySpecifier)[]; +export type UpdaterUpdatesFieldPolicy = { + categoryUpdates?: FieldPolicy | FieldReadFunction, + initial?: FieldPolicy | FieldReadFunction, + jobsInfo?: FieldPolicy | FieldReadFunction, + mangaUpdates?: FieldPolicy | FieldReadFunction, + omittedUpdates?: FieldPolicy | FieldReadFunction +}; export type ValidateBackupResultKeySpecifier = ('missingSources' | 'missingTrackers' | ValidateBackupResultKeySpecifier)[]; export type ValidateBackupResultFieldPolicy = { missingSources?: FieldPolicy | FieldReadFunction, @@ -1115,6 +1155,10 @@ export type StrictTypedTypePolicies = { keyFields?: false | CategoryTypeKeySpecifier | (() => undefined | CategoryTypeKeySpecifier), fields?: CategoryTypeFieldPolicy, }, + CategoryUpdateType?: Omit & { + keyFields?: false | CategoryUpdateTypeKeySpecifier | (() => undefined | CategoryUpdateTypeKeySpecifier), + fields?: CategoryUpdateTypeFieldPolicy, + }, ChapterEdge?: Omit & { keyFields?: false | ChapterEdgeKeySpecifier | (() => undefined | ChapterEdgeKeySpecifier), fields?: ChapterEdgeFieldPolicy, @@ -1299,6 +1343,10 @@ export type StrictTypedTypePolicies = { keyFields?: false | LastUpdateTimestampPayloadKeySpecifier | (() => undefined | LastUpdateTimestampPayloadKeySpecifier), fields?: LastUpdateTimestampPayloadFieldPolicy, }, + LibraryUpdateStatus?: Omit & { + keyFields?: false | LibraryUpdateStatusKeySpecifier | (() => undefined | LibraryUpdateStatusKeySpecifier), + fields?: LibraryUpdateStatusFieldPolicy, + }, ListPreference?: Omit & { keyFields?: false | ListPreferenceKeySpecifier | (() => undefined | ListPreferenceKeySpecifier), fields?: ListPreferenceFieldPolicy, @@ -1331,6 +1379,10 @@ export type StrictTypedTypePolicies = { keyFields?: false | MangaTypeKeySpecifier | (() => undefined | MangaTypeKeySpecifier), fields?: MangaTypeFieldPolicy, }, + MangaUpdateType?: Omit & { + keyFields?: false | MangaUpdateTypeKeySpecifier | (() => undefined | MangaUpdateTypeKeySpecifier), + fields?: MangaUpdateTypeFieldPolicy, + }, MetaEdge?: Omit & { keyFields?: false | MetaEdgeKeySpecifier | (() => undefined | MetaEdgeKeySpecifier), fields?: MetaEdgeFieldPolicy, @@ -1543,6 +1595,10 @@ export type StrictTypedTypePolicies = { keyFields?: false | UpdateLibraryMangaPayloadKeySpecifier | (() => undefined | UpdateLibraryMangaPayloadKeySpecifier), fields?: UpdateLibraryMangaPayloadFieldPolicy, }, + UpdateLibraryPayload?: Omit & { + keyFields?: false | UpdateLibraryPayloadKeySpecifier | (() => undefined | UpdateLibraryPayloadKeySpecifier), + fields?: UpdateLibraryPayloadFieldPolicy, + }, UpdateMangaCategoriesPayload?: Omit & { keyFields?: false | UpdateMangaCategoriesPayloadKeySpecifier | (() => undefined | UpdateMangaCategoriesPayloadKeySpecifier), fields?: UpdateMangaCategoriesPayloadFieldPolicy, @@ -1583,6 +1639,14 @@ export type StrictTypedTypePolicies = { keyFields?: false | UpdateTrackPayloadKeySpecifier | (() => undefined | UpdateTrackPayloadKeySpecifier), fields?: UpdateTrackPayloadFieldPolicy, }, + UpdaterJobsInfoType?: Omit & { + keyFields?: false | UpdaterJobsInfoTypeKeySpecifier | (() => undefined | UpdaterJobsInfoTypeKeySpecifier), + fields?: UpdaterJobsInfoTypeFieldPolicy, + }, + UpdaterUpdates?: Omit & { + keyFields?: false | UpdaterUpdatesKeySpecifier | (() => undefined | UpdaterUpdatesKeySpecifier), + fields?: UpdaterUpdatesFieldPolicy, + }, ValidateBackupResult?: Omit & { keyFields?: false | ValidateBackupResultKeySpecifier | (() => undefined | ValidateBackupResultKeySpecifier), fields?: ValidateBackupResultFieldPolicy, diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts index 0b8b82be..36e3244a 100644 --- a/src/lib/graphql/generated/graphql.ts +++ b/src/lib/graphql/generated/graphql.ts @@ -103,6 +103,11 @@ export type CategoryFilterInput = { order?: InputMaybe; }; +export enum CategoryJobStatus { + Skipped = 'SKIPPED', + Updating = 'UPDATING' +} + export type CategoryMetaType = MetaType & { __typename?: 'CategoryMetaType'; category: CategoryType; @@ -148,6 +153,12 @@ export type CategoryType = { order: Scalars['Int']['output']; }; +export type CategoryUpdateType = { + __typename?: 'CategoryUpdateType'; + category: CategoryType; + status: CategoryJobStatus; +}; + export type ChapterConditionInput = { chapterNumber?: InputMaybe; fetchedAt?: InputMaybe; @@ -267,7 +278,7 @@ export type CheckBoxPreference = { default: Scalars['Boolean']['output']; key: Scalars['String']['output']; summary?: Maybe; - title: Scalars['String']['output']; + title?: Maybe; visible: Scalars['Boolean']['output']; }; @@ -835,6 +846,18 @@ export type LastUpdateTimestampPayload = { timestamp: Scalars['LongString']['output']; }; +export type LibraryUpdateStatus = { + __typename?: 'LibraryUpdateStatus'; + categoryUpdates: Array; + jobsInfo: UpdaterJobsInfoType; + mangaUpdates: Array; +}; + +export type LibraryUpdateStatusChangedInput = { + /** Sets a max number of updates that can be contained in a updater update message.Everything above this limit will be omitted and the "updateStatus" should be re-fetched via the corresponding query. Due to the graphql subscription execution strategy not supporting batching for data loaders, the data loaders run into the n+1 problem, which can cause the server to get unresponsive until the status update has been handled. This is an issue e.g. when starting an update. */ + maxUpdates?: InputMaybe; +}; + export type ListPreference = { __typename?: 'ListPreference'; currentValue?: Maybe; @@ -953,6 +976,14 @@ export type MangaFilterInput = { url?: InputMaybe; }; +export enum MangaJobStatus { + Complete = 'COMPLETE', + Failed = 'FAILED', + Pending = 'PENDING', + Running = 'RUNNING', + Skipped = 'SKIPPED' +} + export type MangaMetaType = MetaType & { __typename?: 'MangaMetaType'; key: Scalars['String']['output']; @@ -1053,6 +1084,12 @@ export type MangaType = { url: Scalars['String']['output']; }; +export type MangaUpdateType = { + __typename?: 'MangaUpdateType'; + manga: MangaType; + status: MangaJobStatus; +}; + export type MetaConditionInput = { key?: InputMaybe; value?: InputMaybe; @@ -1152,6 +1189,7 @@ export type Mutation = { updateChapters?: Maybe; updateExtension?: Maybe; updateExtensions?: Maybe; + updateLibrary?: Maybe; updateLibraryManga?: Maybe; updateManga?: Maybe; updateMangaCategories?: Maybe; @@ -1404,6 +1442,11 @@ export type MutationUpdateExtensionsArgs = { }; +export type MutationUpdateLibraryArgs = { + input: UpdateLibraryInput; +}; + + export type MutationUpdateLibraryMangaArgs = { input: UpdateLibraryMangaInput; }; @@ -1593,6 +1636,7 @@ export type Query = { extensions: ExtensionNodeList; getWebUIUpdateStatus: WebUiUpdateStatus; lastUpdateTimestamp: LastUpdateTimestampPayload; + libraryUpdateStatus: LibraryUpdateStatus; manga: MangaType; mangas: MangaNodeList; meta: GlobalMetaType; @@ -1606,6 +1650,7 @@ export type Query = { trackRecords: TrackRecordNodeList; tracker: TrackerType; trackers: TrackerNodeList; + /** @deprecated Replaced with libraryUpdateStatus, replace with libraryUpdateStatus */ updateStatus: UpdateStatus; validateBackup: ValidateBackupResult; }; @@ -1620,8 +1665,6 @@ export type QueryCategoriesArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1644,8 +1687,6 @@ export type QueryChaptersArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1663,8 +1704,6 @@ export type QueryExtensionsArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1682,8 +1721,6 @@ export type QueryMangasArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1701,8 +1738,6 @@ export type QueryMetasArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1730,8 +1765,6 @@ export type QuerySourcesArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1749,8 +1782,6 @@ export type QueryTrackRecordsArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -1767,8 +1798,6 @@ export type QueryTrackersArgs = { last?: InputMaybe; offset?: InputMaybe; order?: InputMaybe>; - orderBy?: InputMaybe; - orderByType?: InputMaybe; }; @@ -2212,9 +2241,11 @@ export type StringFilterInput = { export type Subscription = { __typename?: 'Subscription'; - /** @deprecated Replaced width downloadStatusChanged, replace with downloadStatusChanged(input) */ + /** @deprecated Replaced with downloadStatusChanged, replace with downloadStatusChanged(input) */ downloadChanged: DownloadStatus; downloadStatusChanged: DownloadUpdates; + libraryUpdateStatusChanged: UpdaterUpdates; + /** @deprecated Replaced with updates, replace with updates(input) */ updateStatusChanged: UpdateStatus; webUIUpdateStatusChange: WebUiUpdateStatus; }; @@ -2224,13 +2255,18 @@ export type SubscriptionDownloadStatusChangedArgs = { input: DownloadChangedInput; }; + +export type SubscriptionLibraryUpdateStatusChangedArgs = { + input: LibraryUpdateStatusChangedInput; +}; + export type SwitchPreference = { __typename?: 'SwitchPreference'; currentValue?: Maybe; default: Scalars['Boolean']['output']; key: Scalars['String']['output']; summary?: Maybe; - title: Scalars['String']['output']; + title?: Maybe; visible: Scalars['Boolean']['output']; }; @@ -2545,6 +2581,11 @@ export type UpdateExtensionsPayload = { extensions: Array; }; +export type UpdateLibraryInput = { + categories?: InputMaybe>; + clientMutationId?: InputMaybe; +}; + export type UpdateLibraryMangaInput = { clientMutationId?: InputMaybe; }; @@ -2555,6 +2596,12 @@ export type UpdateLibraryMangaPayload = { updateStatus: UpdateStatus; }; +export type UpdateLibraryPayload = { + __typename?: 'UpdateLibraryPayload'; + clientMutationId?: Maybe; + updateStatus: LibraryUpdateStatus; +}; + export type UpdateMangaCategoriesInput = { clientMutationId?: InputMaybe; id: Scalars['Int']['input']; @@ -2685,6 +2732,26 @@ export type UpdateTrackPayload = { trackRecord?: Maybe; }; +export type UpdaterJobsInfoType = { + __typename?: 'UpdaterJobsInfoType'; + finishedJobs: Scalars['Int']['output']; + isRunning: Scalars['Boolean']['output']; + skippedCategoriesCount: Scalars['Int']['output']; + skippedMangasCount: Scalars['Int']['output']; + totalJobs: Scalars['Int']['output']; +}; + +export type UpdaterUpdates = { + __typename?: 'UpdaterUpdates'; + categoryUpdates: Array; + /** The current update status at the time of sending the initial message. Is null for all following messages */ + initial?: Maybe; + jobsInfo: UpdaterJobsInfoType; + mangaUpdates: Array; + /** Indicates whether updates have been omitted based on the "maxUpdates" subscription variable. In case updates have been omitted, the "updateStatus" query should be re-fetched. */ + omittedUpdates: Scalars['Boolean']['output']; +}; + export type ValidateBackupInput = { backup: Scalars['Upload']['input']; }; @@ -2769,11 +2836,11 @@ export type ChapterStateFieldsFragment = { __typename?: 'ChapterType', id: numbe export type ChapterReaderFieldsFragment = { __typename?: 'ChapterType', uploadDate: string, lastPageRead: number, pageCount: number, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean }; -export type ChapterListFieldsFragment = { __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean }; +export type ChapterListFieldsFragment = { __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean }; -export type ChapterUpdateListFieldsFragment = { __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }; +export type ChapterUpdateListFieldsFragment = { __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }; -export type ChapterHistoryListFieldsFragment = { __typename?: 'ChapterType', lastReadAt: string, lastPageRead: number, pageCount: number, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }; +export type ChapterHistoryListFieldsFragment = { __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }; export type DownloadTypeFieldsFragment = { __typename?: 'DownloadType', progress: number, state: DownloadState, tries: number, chapter: { __typename?: 'ChapterType', id: number, name: string, sourceOrder: number, isDownloaded: boolean }, manga: { __typename?: 'MangaType', id: number, title: string, downloadCount: number } }; @@ -2823,7 +2890,7 @@ export type SourceListFieldsFragment = { __typename?: 'SourceType', lang: string export type SourceBrowseFieldsFragment = { __typename?: 'SourceType', isConfigurable: boolean, supportsLatest: boolean, id: string, name: string, displayName: string, meta: Array<{ __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }>, filters: Array<{ __typename?: 'CheckBoxFilter', name: string, type: 'CheckBoxFilter', CheckBoxFilterDefault: boolean } | { __typename?: 'GroupFilter', name: string, type: 'GroupFilter', filters: Array<{ __typename?: 'CheckBoxFilter', name: string, type: 'CheckBoxFilter', CheckBoxFilterDefault: boolean } | { __typename?: 'GroupFilter' } | { __typename?: 'HeaderFilter', name: string, type: 'HeaderFilter' } | { __typename?: 'SelectFilter', name: string, values: Array, type: 'SelectFilter', SelectFilterDefault: number } | { __typename?: 'SeparatorFilter', name: string, type: 'SeparatorFilter' } | { __typename?: 'SortFilter', name: string, values: Array, type: 'SortFilter', SortFilterDefault?: { __typename?: 'SortSelection', ascending: boolean, index: number } | null } | { __typename?: 'TextFilter', name: string, type: 'TextFilter', TextFilterDefault: string } | { __typename?: 'TriStateFilter', name: string, type: 'TriStateFilter', TriStateFilterDefault: TriState }> } | { __typename?: 'HeaderFilter', name: string, type: 'HeaderFilter' } | { __typename?: 'SelectFilter', name: string, values: Array, type: 'SelectFilter', SelectFilterDefault: number } | { __typename?: 'SeparatorFilter', name: string, type: 'SeparatorFilter' } | { __typename?: 'SortFilter', name: string, values: Array, type: 'SortFilter', SortFilterDefault?: { __typename?: 'SortSelection', ascending: boolean, index: number } | null } | { __typename?: 'TextFilter', name: string, type: 'TextFilter', TextFilterDefault: string } | { __typename?: 'TriStateFilter', name: string, type: 'TriStateFilter', TriStateFilterDefault: TriState }> }; -export type SourceSettingFieldsFragment = { __typename?: 'SourceType', id: string, name: string, displayName: string, preferences: Array<{ __typename?: 'CheckBoxPreference', summary?: string | null, key: string, type: 'CheckBoxPreference', CheckBoxCheckBoxCurrentValue?: boolean | null, CheckBoxDefault: boolean, CheckBoxTitle: string } | { __typename?: 'EditTextPreference', text?: string | null, summary?: string | null, key: string, dialogTitle?: string | null, dialogMessage?: string | null, type: 'EditTextPreference', EditTextPreferenceCurrentValue?: string | null, EditTextPreferenceDefault?: string | null, EditTextPreferenceTitle?: string | null } | { __typename?: 'ListPreference', summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'ListPreference', ListPreferenceCurrentValue?: string | null, ListPreferenceDefault?: string | null, ListPreferenceTitle?: string | null } | { __typename?: 'MultiSelectListPreference', dialogMessage?: string | null, dialogTitle?: string | null, summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'MultiSelectListPreference', MultiSelectListPreferenceTitle?: string | null, MultiSelectListPreferenceDefault?: Array | null, MultiSelectListPreferenceCurrentValue?: Array | null } | { __typename?: 'SwitchPreference', summary?: string | null, key: string, type: 'SwitchPreference', SwitchPreferenceCurrentValue?: boolean | null, SwitchPreferenceDefault: boolean, SwitchPreferenceTitle: string }> }; +export type SourceSettingFieldsFragment = { __typename?: 'SourceType', id: string, name: string, displayName: string, preferences: Array<{ __typename?: 'CheckBoxPreference', summary?: string | null, key: string, type: 'CheckBoxPreference', CheckBoxCheckBoxCurrentValue?: boolean | null, CheckBoxDefault: boolean, CheckBoxTitle?: string | null } | { __typename?: 'EditTextPreference', text?: string | null, summary?: string | null, key: string, dialogTitle?: string | null, dialogMessage?: string | null, type: 'EditTextPreference', EditTextPreferenceCurrentValue?: string | null, EditTextPreferenceDefault?: string | null, EditTextPreferenceTitle?: string | null } | { __typename?: 'ListPreference', summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'ListPreference', ListPreferenceCurrentValue?: string | null, ListPreferenceDefault?: string | null, ListPreferenceTitle?: string | null } | { __typename?: 'MultiSelectListPreference', dialogMessage?: string | null, dialogTitle?: string | null, summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'MultiSelectListPreference', MultiSelectListPreferenceTitle?: string | null, MultiSelectListPreferenceDefault?: Array | null, MultiSelectListPreferenceCurrentValue?: Array | null } | { __typename?: 'SwitchPreference', summary?: string | null, key: string, type: 'SwitchPreference', SwitchPreferenceCurrentValue?: boolean | null, SwitchPreferenceDefault: boolean, SwitchPreferenceTitle?: string | null }> }; export type TrackerBaseFieldsFragment = { __typename?: 'TrackerType', id: number, name: string, icon: string, isLoggedIn: boolean, isTokenExpired: boolean }; @@ -2835,9 +2902,15 @@ export type TrackRecordSearchFieldsFragment = { __typename?: 'TrackSearchType', export type TrackRecordBindFieldsFragment = { __typename?: 'TrackRecordType', id: number, remoteId: string, trackerId: number, remoteUrl: string, title: string, status: number, lastChapterRead: number, totalChapters: number, score: number, displayScore: string, startDate: string, finishDate: string }; -export type UpdaterMangaFieldsFragment = { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null }; +export type UpdaterMangaFieldsFragment = { __typename?: 'MangaUpdateType', status: MangaJobStatus, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null } }; -export type UpdaterSubscriptionFieldsFragment = { __typename?: 'UpdateStatus', isRunning: boolean, completeJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, firstUnreadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number } | null, lastReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestFetchedChapter?: { __typename?: 'ChapterType', id: number, fetchedAt: string } | null, latestUploadedChapter?: { __typename?: 'ChapterType', id: number, uploadDate: string } | null, chapters: { __typename?: 'ChapterNodeList', totalCount: number } }> } }, 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 }> } } }; +export type UpdaterCategoryFieldsFragment = { __typename?: 'CategoryUpdateType', status: CategoryJobStatus, category: { __typename?: 'CategoryType', id: number, name: string } }; + +export type UpdaterJobInfoFieldsFragment = { __typename?: 'UpdaterJobsInfoType', isRunning: boolean, totalJobs: number, finishedJobs: number, skippedCategoriesCount: number, skippedMangasCount: number }; + +export type UpdaterStatusFieldsFragment = { __typename?: 'LibraryUpdateStatus', jobsInfo: { __typename?: 'UpdaterJobsInfoType', isRunning: boolean, totalJobs: number, finishedJobs: number, skippedCategoriesCount: number, skippedMangasCount: number }, categoryUpdates: Array<{ __typename?: 'CategoryUpdateType', status: CategoryJobStatus, category: { __typename?: 'CategoryType', id: number, name: string } }>, mangaUpdates: Array<{ __typename?: 'MangaUpdateType', status: MangaJobStatus, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null } }> }; + +export type UpdaterSubscriptionFieldsFragment = { __typename?: 'UpdaterUpdates', omittedUpdates: boolean, jobsInfo: { __typename?: 'UpdaterJobsInfoType', isRunning: boolean, totalJobs: number, finishedJobs: number, skippedCategoriesCount: number, skippedMangasCount: number }, categoryUpdates: Array<{ __typename?: 'CategoryUpdateType', status: CategoryJobStatus, category: { __typename?: 'CategoryType', id: number, name: string } }>, mangaUpdates: Array<{ __typename?: 'MangaUpdateType', status: MangaJobStatus, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null } }> }; export type UpdaterStartStopFieldsFragment = { __typename?: 'UpdateStatus', isRunning: boolean }; @@ -2931,7 +3004,7 @@ export type GetMangaChaptersFetchMutationVariables = Exact<{ }>; -export type GetMangaChaptersFetchMutation = { __typename?: 'Mutation', fetchChapters?: { __typename?: 'FetchChaptersPayload', chapters: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, chapters: { __typename?: 'ChapterNodeList', totalCount: number }, firstUnreadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, isRead: boolean, mangaId: number } | null, lastReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestFetchedChapter?: { __typename?: 'ChapterType', id: number, fetchedAt: string } | null, latestUploadedChapter?: { __typename?: 'ChapterType', id: number, uploadDate: string } | null } }> } | null }; +export type GetMangaChaptersFetchMutation = { __typename?: 'Mutation', fetchChapters?: { __typename?: 'FetchChaptersPayload', chapters: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, chapters: { __typename?: 'ChapterNodeList', totalCount: number }, firstUnreadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, isRead: boolean, mangaId: number } | null, lastReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestFetchedChapter?: { __typename?: 'ChapterType', id: number, fetchedAt: string } | null, latestUploadedChapter?: { __typename?: 'ChapterType', id: number, uploadDate: string } | null } }> } | null }; export type SetChapterMetadataMutationVariables = Exact<{ input: SetChapterMetaInput; @@ -3188,7 +3261,7 @@ export type UpdateSourcePreferencesMutationVariables = Exact<{ }>; -export type UpdateSourcePreferencesMutation = { __typename?: 'Mutation', updateSourcePreference?: { __typename?: 'UpdateSourcePreferencePayload', source: { __typename?: 'SourceType', id: string, name: string, displayName: string, preferences: Array<{ __typename?: 'CheckBoxPreference', summary?: string | null, key: string, type: 'CheckBoxPreference', CheckBoxCheckBoxCurrentValue?: boolean | null, CheckBoxDefault: boolean, CheckBoxTitle: string } | { __typename?: 'EditTextPreference', text?: string | null, summary?: string | null, key: string, dialogTitle?: string | null, dialogMessage?: string | null, type: 'EditTextPreference', EditTextPreferenceCurrentValue?: string | null, EditTextPreferenceDefault?: string | null, EditTextPreferenceTitle?: string | null } | { __typename?: 'ListPreference', summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'ListPreference', ListPreferenceCurrentValue?: string | null, ListPreferenceDefault?: string | null, ListPreferenceTitle?: string | null } | { __typename?: 'MultiSelectListPreference', dialogMessage?: string | null, dialogTitle?: string | null, summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'MultiSelectListPreference', MultiSelectListPreferenceTitle?: string | null, MultiSelectListPreferenceDefault?: Array | null, MultiSelectListPreferenceCurrentValue?: Array | null } | { __typename?: 'SwitchPreference', summary?: string | null, key: string, type: 'SwitchPreference', SwitchPreferenceCurrentValue?: boolean | null, SwitchPreferenceDefault: boolean, SwitchPreferenceTitle: string }> } } | null }; +export type UpdateSourcePreferencesMutation = { __typename?: 'Mutation', updateSourcePreference?: { __typename?: 'UpdateSourcePreferencePayload', source: { __typename?: 'SourceType', id: string, name: string, displayName: string, preferences: Array<{ __typename?: 'CheckBoxPreference', summary?: string | null, key: string, type: 'CheckBoxPreference', CheckBoxCheckBoxCurrentValue?: boolean | null, CheckBoxDefault: boolean, CheckBoxTitle?: string | null } | { __typename?: 'EditTextPreference', text?: string | null, summary?: string | null, key: string, dialogTitle?: string | null, dialogMessage?: string | null, type: 'EditTextPreference', EditTextPreferenceCurrentValue?: string | null, EditTextPreferenceDefault?: string | null, EditTextPreferenceTitle?: string | null } | { __typename?: 'ListPreference', summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'ListPreference', ListPreferenceCurrentValue?: string | null, ListPreferenceDefault?: string | null, ListPreferenceTitle?: string | null } | { __typename?: 'MultiSelectListPreference', dialogMessage?: string | null, dialogTitle?: string | null, summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'MultiSelectListPreference', MultiSelectListPreferenceTitle?: string | null, MultiSelectListPreferenceDefault?: Array | null, MultiSelectListPreferenceCurrentValue?: Array | null } | { __typename?: 'SwitchPreference', summary?: string | null, key: string, type: 'SwitchPreference', SwitchPreferenceCurrentValue?: boolean | null, SwitchPreferenceDefault: boolean, SwitchPreferenceTitle?: string | null }> } } | null }; export type SetSourceMetadataMutationVariables = Exact<{ input: SetSourceMetaInput; @@ -3255,19 +3328,12 @@ export type TrackerFetchBindMutationVariables = Exact<{ export type TrackerFetchBindMutation = { __typename?: 'Mutation', fetchTrack: { __typename?: 'FetchTrackPayload', trackRecord: { __typename?: 'TrackRecordType', id: number, remoteId: string, trackerId: number, remoteUrl: string, title: string, status: number, lastChapterRead: number, totalChapters: number, score: number, displayScore: string, startDate: string, finishDate: string } } }; -export type UpdateCategoryMangasMutationVariables = Exact<{ - input: UpdateCategoryMangaInput; +export type UpdateLibraryMutationVariables = Exact<{ + input?: InputMaybe; }>; -export type UpdateCategoryMangasMutation = { __typename?: 'Mutation', updateCategoryManga?: { __typename?: 'UpdateCategoryMangaPayload', updateStatus: { __typename?: 'UpdateStatus', isRunning: boolean } } | null }; - -export type UpdateLibraryMangasMutationVariables = Exact<{ - input?: InputMaybe; -}>; - - -export type UpdateLibraryMangasMutation = { __typename?: 'Mutation', updateLibraryManga?: { __typename?: 'UpdateLibraryMangaPayload', updateStatus: { __typename?: 'UpdateStatus', isRunning: boolean } } | null }; +export type UpdateLibraryMutation = { __typename?: 'Mutation', updateLibrary?: { __typename?: 'UpdateLibraryPayload', updateStatus: { __typename?: 'LibraryUpdateStatus', jobsInfo: { __typename?: 'UpdaterJobsInfoType', isRunning: boolean, totalJobs: number, finishedJobs: number, skippedCategoriesCount: number, skippedMangasCount: number }, categoryUpdates: Array<{ __typename?: 'CategoryUpdateType', status: CategoryJobStatus, category: { __typename?: 'CategoryType', id: number, name: string } }>, mangaUpdates: Array<{ __typename?: 'MangaUpdateType', status: MangaJobStatus, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null } }> } } | null }; export type StopUpdaterMutationVariables = Exact<{ input?: InputMaybe; @@ -3365,7 +3431,7 @@ export type GetChaptersMangaQueryVariables = Exact<{ }>; -export type GetChaptersMangaQuery = { __typename?: 'Query', chapters: { __typename?: 'ChapterNodeList', totalCount: number, nodes: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null } } }; +export type GetChaptersMangaQuery = { __typename?: 'Query', chapters: { __typename?: 'ChapterNodeList', totalCount: number, nodes: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null } } }; export type GetChaptersUpdatesQueryVariables = Exact<{ after?: InputMaybe; @@ -3378,7 +3444,8 @@ export type GetChaptersUpdatesQueryVariables = Exact<{ order?: InputMaybe | ChapterOrderInput>; }>; -export type GetChaptersUpdatesQuery = { __typename?: 'Query', chapters: { __typename?: 'ChapterNodeList', totalCount: number, nodes: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null } } }; + +export type GetChaptersUpdatesQuery = { __typename?: 'Query', chapters: { __typename?: 'ChapterNodeList', totalCount: number, nodes: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null } } }; export type GetChaptersHistoryQueryVariables = Exact<{ after?: InputMaybe; @@ -3391,7 +3458,8 @@ export type GetChaptersHistoryQueryVariables = Exact<{ order?: InputMaybe | ChapterOrderInput>; }>; -export type GetChaptersHistoryQuery = { __typename?: 'Query', chapters: { __typename?: 'ChapterNodeList', totalCount: number, nodes: Array<{ __typename?: 'ChapterType', lastReadAt: string, lastPageRead: number, pageCount: number, uploadDate: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null } } }; + +export type GetChaptersHistoryQuery = { __typename?: 'Query', chapters: { __typename?: 'ChapterNodeList', totalCount: number, nodes: Array<{ __typename?: 'ChapterType', fetchedAt: string, uploadDate: string, lastReadAt: string, id: number, name: string, mangaId: number, scanlator?: string | null, realUrl?: string | null, sourceOrder: number, chapterNumber: number, isRead: boolean, isDownloaded: boolean, isBookmarked: boolean, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null } } }; export type GetMangasChapterIdsWithStateQueryVariables = Exact<{ mangaIds: Array | Scalars['Int']['input']; @@ -3572,7 +3640,7 @@ export type GetSourceSettingsQueryVariables = Exact<{ }>; -export type GetSourceSettingsQuery = { __typename?: 'Query', source: { __typename?: 'SourceType', id: string, name: string, displayName: string, preferences: Array<{ __typename?: 'CheckBoxPreference', summary?: string | null, key: string, type: 'CheckBoxPreference', CheckBoxCheckBoxCurrentValue?: boolean | null, CheckBoxDefault: boolean, CheckBoxTitle: string } | { __typename?: 'EditTextPreference', text?: string | null, summary?: string | null, key: string, dialogTitle?: string | null, dialogMessage?: string | null, type: 'EditTextPreference', EditTextPreferenceCurrentValue?: string | null, EditTextPreferenceDefault?: string | null, EditTextPreferenceTitle?: string | null } | { __typename?: 'ListPreference', summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'ListPreference', ListPreferenceCurrentValue?: string | null, ListPreferenceDefault?: string | null, ListPreferenceTitle?: string | null } | { __typename?: 'MultiSelectListPreference', dialogMessage?: string | null, dialogTitle?: string | null, summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'MultiSelectListPreference', MultiSelectListPreferenceTitle?: string | null, MultiSelectListPreferenceDefault?: Array | null, MultiSelectListPreferenceCurrentValue?: Array | null } | { __typename?: 'SwitchPreference', summary?: string | null, key: string, type: 'SwitchPreference', SwitchPreferenceCurrentValue?: boolean | null, SwitchPreferenceDefault: boolean, SwitchPreferenceTitle: string }> } }; +export type GetSourceSettingsQuery = { __typename?: 'Query', source: { __typename?: 'SourceType', id: string, name: string, displayName: string, preferences: Array<{ __typename?: 'CheckBoxPreference', summary?: string | null, key: string, type: 'CheckBoxPreference', CheckBoxCheckBoxCurrentValue?: boolean | null, CheckBoxDefault: boolean, CheckBoxTitle?: string | null } | { __typename?: 'EditTextPreference', text?: string | null, summary?: string | null, key: string, dialogTitle?: string | null, dialogMessage?: string | null, type: 'EditTextPreference', EditTextPreferenceCurrentValue?: string | null, EditTextPreferenceDefault?: string | null, EditTextPreferenceTitle?: string | null } | { __typename?: 'ListPreference', summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'ListPreference', ListPreferenceCurrentValue?: string | null, ListPreferenceDefault?: string | null, ListPreferenceTitle?: string | null } | { __typename?: 'MultiSelectListPreference', dialogMessage?: string | null, dialogTitle?: string | null, summary?: string | null, key: string, entryValues: Array, entries: Array, type: 'MultiSelectListPreference', MultiSelectListPreferenceTitle?: string | null, MultiSelectListPreferenceDefault?: Array | null, MultiSelectListPreferenceCurrentValue?: Array | null } | { __typename?: 'SwitchPreference', summary?: string | null, key: string, type: 'SwitchPreference', SwitchPreferenceCurrentValue?: boolean | null, SwitchPreferenceDefault: boolean, SwitchPreferenceTitle?: string | null }> } }; export type GetSourceMigratableQueryVariables = Exact<{ id: Scalars['LongString']['input']; @@ -3612,7 +3680,7 @@ export type TrackerSearchQuery = { __typename?: 'Query', searchTracker: { __type export type GetUpdateStatusQueryVariables = Exact<{ [key: string]: never; }>; -export type GetUpdateStatusQuery = { __typename?: 'Query', updateStatus: { __typename?: 'UpdateStatus', isRunning: boolean, completeJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, firstUnreadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number } | null, lastReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestFetchedChapter?: { __typename?: 'ChapterType', id: number, fetchedAt: string } | null, latestUploadedChapter?: { __typename?: 'ChapterType', id: number, uploadDate: string } | null, chapters: { __typename?: 'ChapterNodeList', totalCount: number } }> } }, 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 }> } } } }; +export type GetUpdateStatusQuery = { __typename?: 'Query', libraryUpdateStatus: { __typename?: 'LibraryUpdateStatus', jobsInfo: { __typename?: 'UpdaterJobsInfoType', isRunning: boolean, totalJobs: number, finishedJobs: number, skippedCategoriesCount: number, skippedMangasCount: number }, categoryUpdates: Array<{ __typename?: 'CategoryUpdateType', status: CategoryJobStatus, category: { __typename?: 'CategoryType', id: number, name: string } }>, mangaUpdates: Array<{ __typename?: 'MangaUpdateType', status: MangaJobStatus, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null } }> } }; export type GetLastUpdateTimestampQueryVariables = Exact<{ [key: string]: never; }>; @@ -3631,7 +3699,9 @@ 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 } } }; -export type UpdaterSubscriptionVariables = Exact<{ [key: string]: never; }>; +export type UpdaterSubscriptionVariables = Exact<{ + input: LibraryUpdateStatusChangedInput; +}>; -export type UpdaterSubscription = { __typename?: 'Subscription', updateStatusChanged: { __typename?: 'UpdateStatus', isRunning: boolean, completeJobs: { __typename?: 'UpdateStatusType', mangas: { __typename?: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename?: 'MangaType', id: number, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, firstUnreadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number } | null, lastReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number, sourceOrder: number, lastReadAt: string } | null, latestFetchedChapter?: { __typename?: 'ChapterType', id: number, fetchedAt: string } | null, latestUploadedChapter?: { __typename?: 'ChapterType', id: number, uploadDate: string } | null, chapters: { __typename?: 'ChapterNodeList', totalCount: number } }> } }, 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 }> } } } }; +export type UpdaterSubscription = { __typename?: 'Subscription', libraryUpdateStatusChanged: { __typename?: 'UpdaterUpdates', omittedUpdates: boolean, jobsInfo: { __typename?: 'UpdaterJobsInfoType', isRunning: boolean, totalJobs: number, finishedJobs: number, skippedCategoriesCount: number, skippedMangasCount: number }, categoryUpdates: Array<{ __typename?: 'CategoryUpdateType', status: CategoryJobStatus, category: { __typename?: 'CategoryType', id: number, name: string } }>, mangaUpdates: Array<{ __typename?: 'MangaUpdateType', status: MangaJobStatus, manga: { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null } }> } }; diff --git a/src/lib/graphql/mutations/UpdaterMutation.ts b/src/lib/graphql/mutations/UpdaterMutation.ts index 24890122..4d5e95e4 100644 --- a/src/lib/graphql/mutations/UpdaterMutation.ts +++ b/src/lib/graphql/mutations/UpdaterMutation.ts @@ -7,27 +7,15 @@ */ import gql from 'graphql-tag'; -import { UPDATER_START_STOP_FIELDS } from '@/lib/graphql/fragments/UpdaterFragments.ts'; +import { UPDATER_STATUS_FIELDS } from '@/lib/graphql/fragments/UpdaterFragments.ts'; -export const UPDATE_CATEGORY_MANGAS = gql` - ${UPDATER_START_STOP_FIELDS} +export const UPDATE_LIBRARY = gql` + ${UPDATER_STATUS_FIELDS} - mutation UPDATE_CATEGORY_MANGAS($input: UpdateCategoryMangaInput!) { - updateCategoryManga(input: $input) { + mutation UPDATE_LIBRARY($input: UpdateLibraryInput = {}) { + updateLibrary(input: $input) { updateStatus { - ...UPDATER_START_STOP_FIELDS - } - } - } -`; - -export const UPDATE_LIBRARY_MANGAS = gql` - ${UPDATER_START_STOP_FIELDS} - - mutation UPDATE_LIBRARY_MANGAS($input: UpdateLibraryMangaInput = {}) { - updateLibraryManga(input: $input) { - updateStatus { - ...UPDATER_START_STOP_FIELDS + ...UPDATER_STATUS_FIELDS } } } diff --git a/src/lib/graphql/queries/UpdaterQuery.ts b/src/lib/graphql/queries/UpdaterQuery.ts index 289b9d60..bd96edb4 100644 --- a/src/lib/graphql/queries/UpdaterQuery.ts +++ b/src/lib/graphql/queries/UpdaterQuery.ts @@ -7,14 +7,14 @@ */ import gql from 'graphql-tag'; -import { UPDATER_SUBSCRIPTION_FIELDS } from '@/lib/graphql/fragments/UpdaterFragments.ts'; +import { UPDATER_STATUS_FIELDS } from '@/lib/graphql/fragments/UpdaterFragments.ts'; export const GET_UPDATE_STATUS = gql` - ${UPDATER_SUBSCRIPTION_FIELDS} + ${UPDATER_STATUS_FIELDS} query GET_UPDATE_STATUS { - updateStatus { - ...UPDATER_SUBSCRIPTION_FIELDS + libraryUpdateStatus { + ...UPDATER_STATUS_FIELDS } } `; diff --git a/src/lib/graphql/subscriptions/UpdaterSubscription.ts b/src/lib/graphql/subscriptions/UpdaterSubscription.ts index fd7b099c..7ce9c70f 100644 --- a/src/lib/graphql/subscriptions/UpdaterSubscription.ts +++ b/src/lib/graphql/subscriptions/UpdaterSubscription.ts @@ -12,8 +12,8 @@ import { UPDATER_SUBSCRIPTION_FIELDS } from '@/lib/graphql/fragments/UpdaterFrag export const UPDATER_SUBSCRIPTION = gql` ${UPDATER_SUBSCRIPTION_FIELDS} - subscription UPDATER_SUBSCRIPTION { - updateStatusChanged { + subscription UPDATER_SUBSCRIPTION($input: LibraryUpdateStatusChangedInput!) { + libraryUpdateStatusChanged(input: $input) { ...UPDATER_SUBSCRIPTION_FIELDS } } diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index 0fb81eb7..b8bbd2ed 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -170,8 +170,6 @@ import { TrackerUnbindMutationVariables, TrackerUpdateBindMutation, TrackerUpdateBindMutationVariables, - UpdateCategoryMangasMutation, - UpdateCategoryMangasMutationVariables, UpdateCategoryMutation, UpdateCategoryMutationVariables, UpdateCategoryOrderMutation, @@ -187,8 +185,6 @@ import { UpdateExtensionPatchInput, UpdateExtensionsMutation, UpdateExtensionsMutationVariables, - UpdateLibraryMangasMutation, - UpdateLibraryMangasMutationVariables, UpdateMangaCategoriesMutation, UpdateMangaCategoriesMutationVariables, UpdateMangaCategoriesPatchInput, @@ -211,6 +207,8 @@ import { ValidateBackupQuery, ValidateBackupQueryVariables, WebuiUpdateSubscription, + UpdateLibraryMutation, + UpdateLibraryMutationVariables, } from '@/lib/graphql/generated/graphql.ts'; import { GET_GLOBAL_METADATAS } from '@/lib/graphql/queries/GlobalMetadataQuery.ts'; import { DELETE_GLOBAL_METADATA, SET_GLOBAL_METADATA } from '@/lib/graphql/mutations/GlobalMetadataMutation.ts'; @@ -290,11 +288,7 @@ import { UPDATE_CATEGORY, UPDATE_CATEGORY_ORDER, } from '@/lib/graphql/mutations/CategoryMutation.ts'; -import { - STOP_UPDATER, - UPDATE_CATEGORY_MANGAS, - UPDATE_LIBRARY_MANGAS, -} from '@/lib/graphql/mutations/UpdaterMutation.ts'; +import { STOP_UPDATER, UPDATE_LIBRARY } from '@/lib/graphql/mutations/UpdaterMutation.ts'; import { GET_LAST_UPDATE_TIMESTAMP, GET_UPDATE_STATUS } from '@/lib/graphql/queries/UpdaterQuery.ts'; import { CustomCache } from '@/lib/storage/CustomCache.ts'; import { RESTORE_BACKUP } from '@/lib/graphql/mutations/BackupMutation.ts'; @@ -2925,35 +2919,11 @@ export class RequestManager { } as typeof result; } - public startGlobalUpdate( - categories?: undefined, - options?: MutationOptions, - ): AbortableApolloMutationResponse; - public startGlobalUpdate( categories?: number[], - options?: MutationOptions, - ): AbortableApolloMutationResponse; - - public startGlobalUpdate< - Data extends UpdateLibraryMangasMutation | UpdateCategoryMangasMutation, - Variables extends UpdateLibraryMangasMutationVariables | UpdateCategoryMangasMutationVariables, - >(categories?: number[], options?: MutationOptions): AbortableApolloMutationResponse { - if (categories?.length) { - return this.doRequest( - GQLMethod.MUTATION, - UPDATE_CATEGORY_MANGAS, - { input: { categories } }, - options as MutationOptions, - ) as AbortableApolloMutationResponse; - } - - return this.doRequest( - GQLMethod.MUTATION, - UPDATE_LIBRARY_MANGAS, - {}, - options as MutationOptions, - ) as AbortableApolloMutationResponse; + options?: MutationOptions, + ): AbortableApolloMutationResponse { + return this.doRequest(GQLMethod.MUTATION, UPDATE_LIBRARY, { input: { categories } }, options); } public resetGlobalUpdate( @@ -3025,7 +2995,27 @@ export class RequestManager { public useUpdaterSubscription( options?: SubscriptionHookOptions, ): SubscriptionResult { - return this.doRequest(GQLMethod.USE_SUBSCRIPTION, UPDATER_SUBSCRIPTION, {}, options); + return this.doRequest( + GQLMethod.USE_SUBSCRIPTION, + UPDATER_SUBSCRIPTION, + { input: { maxUpdates: 30 } }, + { + ...options, + onData: (onDataOptions) => { + const updatesChanged = onDataOptions.data.data?.libraryUpdateStatusChanged; + + if (!updatesChanged?.omittedUpdates) { + return; + } + + const { cache } = this.graphQLClient.client; + + cache.gc(); + cache.evict({ broadcast: true, id: 'LibraryUpdateStatus' }); + cache.evict({ broadcast: true, fieldName: 'libraryUpdateStatus' }); + }, + }, + ); } public useGetServerSettings( diff --git a/src/lib/requests/client/GraphQLClient.ts b/src/lib/requests/client/GraphQLClient.ts index bff20db6..72b0e583 100644 --- a/src/lib/requests/client/GraphQLClient.ts +++ b/src/lib/requests/client/GraphQLClient.ts @@ -62,6 +62,9 @@ const typePolicies: StrictTypedTypePolicies = { }, }, DownloadType: { keyFields: ['chapter'] }, + CategoryUpdateType: { keyFields: ['category'] }, + MangaUpdateType: { keyFields: ['manga'] }, + UpdaterJobsInfoType: { keyFields: [] }, WebUIUpdateStatus: { keyFields: [] }, UpdateStatus: { keyFields: [] }, Query: { diff --git a/src/modules/core/components/UpdateChecker.tsx b/src/modules/core/components/UpdateChecker.tsx index a90e6ba4..b405f47e 100644 --- a/src/modules/core/components/UpdateChecker.tsx +++ b/src/modules/core/components/UpdateChecker.tsx @@ -6,7 +6,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useState } from 'react'; import IconButton from '@mui/material/IconButton'; import RefreshIcon from '@mui/icons-material/Refresh'; import { useTranslation } from 'react-i18next'; @@ -18,7 +18,6 @@ import Stack from '@mui/material/Stack'; import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { makeToast } from '@/modules/core/utils/Toast.ts'; -import { UpdaterSubscription } from '@/lib/graphql/generated/graphql.ts'; import { Progress } from '@/modules/core/components/Progress.tsx'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { dateTimeFormatter } from '@/util/DateHelper.ts'; @@ -27,19 +26,6 @@ import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx'; import { CategoryIdInfo } from '@/modules/category/Category.types.ts'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; -const calcProgress = (status: UpdaterSubscription['updateStatusChanged'] | undefined) => { - if (!status) { - return 0; - } - - const finishedUpdates = status.failedJobs.mangas.totalCount + status.completeJobs.mangas.totalCount; - const totalMangas = finishedUpdates + status.pendingJobs.mangas.totalCount + status.runningJobs.mangas.totalCount; - - const progress = 100 * (finishedUpdates / totalMangas); - - return Number.isNaN(progress) ? 0 : progress; -}; - let lastRunningState = false; export function UpdateChecker({ @@ -58,21 +44,13 @@ export function UpdateChecker({ requestManager.useGetLastGlobalUpdateTimestamp(); const lastUpdateTimestamp = lastUpdateTimestampData?.lastUpdateTimestamp.timestamp; const { data: updaterData } = requestManager.useGetGlobalUpdateSummary(); - const status = updaterData?.updateStatus; + const status = updaterData?.libraryUpdateStatus; - const isRunning = !!status?.isRunning; - const progress = useMemo( - () => calcProgress(status), - [ - status?.failedJobs.mangas.totalCount, - status?.completeJobs.mangas.totalCount, - status?.pendingJobs.mangas.totalCount, - status?.runningJobs.mangas.totalCount, - ], - ); + const isRunning = !!status?.jobsInfo.isRunning; + const progress = status ? (status.jobsInfo.finishedJobs / status.jobsInfo.totalJobs) * 100 : 0; useEffect(() => { - if (!lastRunningState && status?.isRunning) { + if (!lastRunningState && isRunning) { lastRunningState = true; } @@ -85,7 +63,7 @@ export function UpdateChecker({ handleFinishedUpdate?.(); // this re-fetch is necessary since a running update could have been triggered by the server or another client reFetchLastTimestamp().catch(defaultPromiseErrorHandler('UpdateChecker::reFetchLastTimestamp')); - }, [status?.isRunning]); + }, [isRunning]); const startUpdate = async (category?: CategoryIdInfo['id']) => { try { diff --git a/src/modules/source/components/sourceConfiguration/TwoStatePreference.tsx b/src/modules/source/components/sourceConfiguration/TwoStatePreference.tsx index c893143a..8479c523 100644 --- a/src/modules/source/components/sourceConfiguration/TwoStatePreference.tsx +++ b/src/modules/source/components/sourceConfiguration/TwoStatePreference.tsx @@ -27,7 +27,7 @@ function getTwoStateType(type: TwoStatePreferenceProps['twoStateType']) { const getTwoStateValues = ( props: TwoStatePreferenceProps, ): { - title: string; + title: string | null | undefined; defaultValue: boolean; currentValue?: boolean | null | undefined; } => { diff --git a/tools/scripts/codegenFormatter.ts b/tools/scripts/codegenFormatter.ts index 5d2a8a28..1c78a0b9 100644 --- a/tools/scripts/codegenFormatter.ts +++ b/tools/scripts/codegenFormatter.ts @@ -63,6 +63,7 @@ const fixTypingOfQueryTypePolicies = format( \textensions?: FieldPolicy | FieldReadFunction, \tgetWebUIUpdateStatus?: FieldPolicy | FieldReadFunction, \tlastUpdateTimestamp?: FieldPolicy | FieldReadFunction, +\tlibraryUpdateStatus?: FieldPolicy | FieldReadFunction, \tmanga?: FieldPolicy | FieldReadFunction, \tmangas?: FieldPolicy | FieldReadFunction, \tmeta?: FieldPolicy | FieldReadFunction, @@ -93,6 +94,7 @@ const fixTypingOfQueryTypePolicies = format( \textensions?: FieldPolicy | FieldReadFunction, \tgetWebUIUpdateStatus?: FieldPolicy> | FieldReadFunction>, \tlastUpdateTimestamp?: FieldPolicy | FieldReadFunction, +\tlibraryUpdateStatus?: FieldPolicy> | FieldReadFunction>, \tmanga?: FieldPolicy> | FieldReadFunction>, \tmangas?: FieldPolicy | FieldReadFunction, \tmeta?: FieldPolicy> | FieldReadFunction>, @@ -106,7 +108,7 @@ const fixTypingOfQueryTypePolicies = format( \ttrackRecords?: FieldPolicy | FieldReadFunction, \ttracker?: FieldPolicy | FieldReadFunction, \ttrackers?: FieldPolicy | FieldReadFunction, -\tupdateStatus?: FieldPolicy> | FieldReadFunction>, +\tupdateStatus?: FieldPolicy | FieldReadFunction, \tvalidateBackup?: FieldPolicy | FieldReadFunction };`, ); diff --git a/versionToServerVersionMapping.json b/versionToServerVersionMapping.json index 96e885d1..96773dda 100644 --- a/versionToServerVersionMapping.json +++ b/versionToServerVersionMapping.json @@ -1,6 +1,11 @@ [ { "uiVersion": "PREVIEW", + "serverVersion": "r1716" + }, + { + "tag": "PREVIEW", + "uiVersion": "r2415", "serverVersion": "r1636" }, {