From e944c6711e4b990d0a87612288623108ff1bd051 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Sat, 16 May 2026 01:33:37 +0200 Subject: [PATCH] Sort browse migration manga selection by title --- CHANGELOG.md | 1 + .../screens/MigrationSelectMangas.tsx | 34 +++++- src/lib/graphql/generated/graphql.ts | 9 +- src/lib/graphql/manga/MangaQuery.ts | 22 +++- src/lib/requests/RequestManager.ts | 108 ++++++++---------- 5 files changed, 106 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d196276..c0798e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - (**Migration**) Keep the migration page open when aborting during the actual migration execution - (**Migration**) Prevent concurrent requests to the same tracker - (**Migration**) Allow only 2 tracker requests per second +- (**Migration**) Sort manga to migrate selection by title and by recently added to the library ### Fixed diff --git a/src/features/migration/screens/MigrationSelectMangas.tsx b/src/features/migration/screens/MigrationSelectMangas.tsx index e485b5b8..c120d5dd 100644 --- a/src/features/migration/screens/MigrationSelectMangas.tsx +++ b/src/features/migration/screens/MigrationSelectMangas.tsx @@ -20,12 +20,19 @@ import { useLocalStorage } from '@/base/hooks/useStorage.tsx'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { MigrationManager } from '@/features/migration/MigrationManager.ts'; import { useSelectableCollection } from '@/base/collection/hooks/useSelectableCollection.ts'; -import type { GetSourceMigratableQuery, GetSourceMigratableQueryVariables } from '@/lib/graphql/generated/graphql.ts'; +import type { + GetMigratableSourceMangasQuery, + GetMigratableSourceMangasQueryVariables, + GetSourceMigratableQuery, + GetSourceMigratableQueryVariables, +} from '@/lib/graphql/generated/graphql.ts'; import { GET_SOURCE_MIGRATABLE } from '@/lib/graphql/source/SourceQuery.ts'; import { SelectableCollectionSelectMode } from '@/base/collection/components/SelectableCollectionSelectMode.tsx'; import { Mangas } from '@/features/manga/services/Mangas.ts'; import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts'; import { MigrationContinueButton } from '@/features/migration/components/MigrationContinueButton.tsx'; +import { GET_MIGRATABLE_SOURCE_MANGAS } from '@/lib/graphql/manga/MangaQuery.ts'; +import { MangaOrderBy, SortOrder } from '@/lib/graphql/generated/graphql-base.types.ts'; const getSourceError = (error: unknown): unknown => { const message = getErrorMessage(error); @@ -66,9 +73,28 @@ export const MigrationSelectMangas = () => { loading: areMangasLoading, error: mangasError, refetch: refetchMangas, - } = requestManager.useGetMigratableSourceMangas(sourceId!, { - skip: !sourceIds, - }); + } = requestManager.useGetMangas( + GET_MIGRATABLE_SOURCE_MANGAS, + { + condition: { + sourceId, + inLibrary: true, + }, + order: [ + { + by: MangaOrderBy.Title, + byType: SortOrder.Asc, + }, + { + by: MangaOrderBy.InLibraryAt, + byType: SortOrder.Desc, + }, + ], + }, + { + skip: !sourceIds, + }, + ); const mangas = migratableSourceMangasData?.mangas.nodes ?? STABLE_EMPTY_ARRAY; const mangaIds = useMemo(() => Mangas.getIds(mangas), [mangas]); diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts index b79f21e0..f0a02125 100644 --- a/src/lib/graphql/generated/graphql.ts +++ b/src/lib/graphql/generated/graphql.ts @@ -624,7 +624,14 @@ export type GetMangasDuplicatesQueryVariables = Exact<{ export type GetMangasDuplicatesQuery = { __typename: 'Query', mangas: { __typename: 'MangaNodeList', totalCount: number, nodes: Array<{ __typename: 'MangaType', description: string | null, id: number, title: string, thumbnailUrl: string | null, thumbnailUrlLastFetched: string | null, inLibrary: boolean, initialized: boolean, sourceId: string, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, chapters: { __typename: 'ChapterNodeList', totalCount: number } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } }; export type GetMigratableSourceMangasQueryVariables = Exact<{ - sourceId: string; + after?: string | null | undefined; + before?: string | null | undefined; + condition?: Types.MangaConditionInput | null | undefined; + filter?: Types.MangaFilterInput | null | undefined; + first?: number | null | undefined; + last?: number | null | undefined; + offset?: number | null | undefined; + order?: Array | Types.MangaOrderInput | null | undefined; }>; diff --git a/src/lib/graphql/manga/MangaQuery.ts b/src/lib/graphql/manga/MangaQuery.ts index f845b5ca..f81045bf 100644 --- a/src/lib/graphql/manga/MangaQuery.ts +++ b/src/lib/graphql/manga/MangaQuery.ts @@ -239,8 +239,26 @@ export const GET_MANGAS_DUPLICATES = gql` export const GET_MIGRATABLE_SOURCE_MANGAS = gql` ${MANGA_MIGRATION_FIELDS} - query GET_MIGRATABLE_SOURCE_MANGAS($sourceId: LongString!) { - mangas(condition: { sourceId: $sourceId, inLibrary: true }) { + query GET_MIGRATABLE_SOURCE_MANGAS( + $after: Cursor + $before: Cursor + $condition: MangaConditionInput + $filter: MangaFilterInput + $first: Int + $last: Int + $offset: Int + $order: [MangaOrderInput!] + ) { + mangas( + after: $after + before: $before + condition: $condition + filter: $filter + first: $first + last: $last + offset: $offset + order: $order + ) { nodes { ...MANGA_MIGRATION_FIELDS } diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index 6f2507c6..4c385545 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -31,6 +31,8 @@ import type { ClearDownloaderMutationVariables, ClearServerCacheMutation, ClearServerCacheMutationVariables, + CreateBackupMutation, + CreateBackupMutationVariables, CreateCategoryMutation, CreateCategoryMutationVariables, DeleteCategoryMutation, @@ -57,20 +59,24 @@ import type { GetCategoryMangasQueryVariables, GetChapterPagesFetchMutation, GetChapterPagesFetchMutationVariables, + GetChaptersHistoryQuery, + GetChaptersHistoryQueryVariables, GetChaptersMangaQuery, GetChaptersMangaQueryVariables, GetChaptersUpdatesQuery, GetChaptersUpdatesQueryVariables, - GetChaptersHistoryQuery, - GetChaptersHistoryQueryVariables, GetDownloadStatusQuery, GetDownloadStatusQueryVariables, + GetExtensionQuery, + GetExtensionQueryVariables, GetExtensionsFetchMutation, GetExtensionsFetchMutationVariables, GetExtensionsQuery, GetExtensionsQueryVariables, GetGlobalMetadatasQuery, GetGlobalMetadatasQueryVariables, + GetKoSyncStatusQuery, + GetKoSyncStatusQueryVariables, GetLastUpdateTimestampQuery, GetLastUpdateTimestampQueryVariables, GetMangaChaptersFetchMutation, @@ -85,8 +91,6 @@ import type { GetMangaToMigrateQueryVariables, GetMangaToMigrateToFetchMutation, GetMangaToMigrateToFetchMutationVariables, - GetMigratableSourceMangasQuery, - GetMigratableSourceMangasQueryVariables, GetMigratableSourcesQuery, GetMigratableSourcesQueryVariables, GetRestoreStatusQuery, @@ -103,6 +107,12 @@ import type { GetWebuiUpdateStatusQueryVariables, InstallExternalExtensionMutation, InstallExternalExtensionMutationVariables, + KoSyncLoginMutation, + KoSyncLoginMutationVariables, + KoSyncLogoutMutation, + KoSyncLogoutMutationVariables, + RefreshMangaMutation, + RefreshMangaMutationVariables, ReorderChapterDownloadMutation, ReorderChapterDownloadMutationVariables, ResetWebuiUpdateStatusMutation, @@ -131,10 +141,14 @@ import type { TrackerUnbindMutationVariables, TrackerUpdateBindMutation, TrackerUpdateBindMutationVariables, + UpdateCategoryMetadataMutation, + UpdateCategoryMetadataMutationVariables, UpdateCategoryMutation, UpdateCategoryMutationVariables, UpdateCategoryOrderMutation, UpdateCategoryOrderMutationVariables, + UpdateChapterMetadataMutation, + UpdateChapterMetadataMutationVariables, UpdateChapterMutation, UpdateChapterMutationVariables, UpdateChaptersMutation, @@ -143,8 +157,14 @@ import type { UpdateExtensionMutationVariables, UpdateExtensionsMutation, UpdateExtensionsMutationVariables, + UpdateGlobalMetadataMutation, + UpdateGlobalMetadataMutationVariables, + UpdateLibraryMutation, + UpdateLibraryMutationVariables, UpdateMangaCategoriesMutation, UpdateMangaCategoriesMutationVariables, + UpdateMangaMetadataMutation, + UpdateMangaMetadataMutationVariables, UpdateMangaMutation, UpdateMangaMutationVariables, UpdateMangasCategoriesMutation, @@ -155,74 +175,52 @@ import type { UpdaterSubscriptionVariables, UpdateServerSettingsMutation, UpdateServerSettingsMutationVariables, + UpdateSourceMetadataMutation, + UpdateSourceMetadataMutationVariables, UpdateSourcePreferencesMutation, UpdateSourcePreferencesMutationVariables, UpdateWebuiMutation, UpdateWebuiMutationVariables, - ValidateBackupQuery, - ValidateBackupQueryVariables, - WebuiUpdateSubscription, - UpdateLibraryMutation, - UpdateLibraryMutationVariables, - GetExtensionQuery, - GetExtensionQueryVariables, UserLoginMutation, UserLoginMutationVariables, UserRefreshMutation, UserRefreshMutationVariables, - CreateBackupMutation, - CreateBackupMutationVariables, - KoSyncLoginMutation, - KoSyncLoginMutationVariables, - KoSyncLogoutMutation, - KoSyncLogoutMutationVariables, - GetKoSyncStatusQuery, - GetKoSyncStatusQueryVariables, - UpdateGlobalMetadataMutation, - UpdateGlobalMetadataMutationVariables, - UpdateMangaMetadataMutation, - UpdateMangaMetadataMutationVariables, - UpdateChapterMetadataMutation, - UpdateChapterMetadataMutationVariables, - UpdateCategoryMetadataMutation, - UpdateCategoryMetadataMutationVariables, - UpdateSourceMetadataMutation, - UpdateSourceMetadataMutationVariables, - RefreshMangaMutation, - RefreshMangaMutationVariables, + ValidateBackupQuery, + ValidateBackupQueryVariables, + WebuiUpdateSubscription, } from '@/lib/graphql/generated/graphql.ts'; import type { + ChapterConditionInput, + CreateBackupInput, + CreateCategoryInput, + DeleteCategoryMetasInput, + DeleteChapterMetasInput, DeleteGlobalMetasInput, - SetGlobalMetasInput, - UpdateExtensionPatchInput, + DeleteMangaMetasInput, DeleteSourceMetasInput, - SetSourceMetasInput, FetchSourceMangaInput, - SourcePreferenceChangeInput, FilterChangeInput, + RestoreBackupInput, + SetCategoryMetasInput, + SetChapterMetasInput, + SetGlobalMetasInput, + SetMangaMetasInput, + SetSourceMetasInput, + SourcePreferenceChangeInput, + UpdateCategoryPatchInput, + UpdateChapterPatchInput, + UpdateExtensionPatchInput, UpdateMangaCategoriesPatchInput, UpdateMangaPatchInput, - DeleteMangaMetasInput, - SetMangaMetasInput, - ChapterConditionInput, - UpdateChapterPatchInput, - DeleteChapterMetasInput, - SetChapterMetasInput, - CreateCategoryInput, - UpdateCategoryPatchInput, - DeleteCategoryMetasInput, - SetCategoryMetasInput, - CreateBackupInput, - RestoreBackupInput, UpdateTrackInput, } from '@/lib/graphql/generated/graphql-base.types.ts'; import { CategoryOrderBy, ChapterOrderBy, + DownloaderState, DownloadUpdateType, FetchSourceMangaType, SortOrder, - DownloaderState, } from '@/lib/graphql/generated/graphql-base.types.ts'; import { GET_GLOBAL_METADATAS } from '@/lib/graphql/metadata/GlobalMetadataQuery.ts'; import { UPDATE_GLOBAL_METADATA } from '@/lib/graphql/metadata/GlobalMetadataMutation.ts'; @@ -250,12 +248,7 @@ import { UPDATE_MANGAS, UPDATE_MANGAS_CATEGORIES, } from '@/lib/graphql/manga/MangaMutation.ts'; -import { - GET_MANGA_TO_MIGRATE, - GET_MANGA_TRACK_RECORDS, - GET_MANGAS_LIBRARY, - GET_MIGRATABLE_SOURCE_MANGAS, -} from '@/lib/graphql/manga/MangaQuery.ts'; +import { GET_MANGA_TO_MIGRATE, GET_MANGA_TRACK_RECORDS, GET_MANGAS_LIBRARY } from '@/lib/graphql/manga/MangaQuery.ts'; import { GET_CATEGORIES_BASE, GET_CATEGORIES_LIBRARY, @@ -2282,13 +2275,6 @@ export class RequestManager { return this.doRequest(GQLMethod.QUERY, document, variables, options); } - public useGetMigratableSourceMangas( - sourceId: string, - options?: QueryHookOptions, - ): AbortableApolloUseQueryResponse { - return this.doRequest(GQLMethod.USE_QUERY, GET_MIGRATABLE_SOURCE_MANGAS, { sourceId }, options); - } - public useUpdateMangaCategories( options?: MutationHookOptions, ): AbortableApolloUseMutationResponse {