Reduce requested manga data in queries

This commit is contained in:
schroda
2024-07-08 18:02:50 +02:00
parent 4b30e9bc48
commit 3d21266f92
47 changed files with 759 additions and 471 deletions

View File

@@ -9,12 +9,13 @@
import { t as translate } from 'i18next';
import gql from 'graphql-tag';
import { DocumentNode } from '@apollo/client';
import { ChapterOffset, TManga, TranslationKey } from '@/typings.ts';
import { ChapterOffset, TranslationKey } from '@/typings.ts';
import { makeToast } from '@/components/util/Toast.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
import { ChapterListFieldsFragment, ChapterType } from '@/lib/graphql/generated/graphql.ts';
import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts';
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
export type ChapterAction = 'download' | 'delete' | 'bookmark' | 'unbookmark' | 'mark_as_read' | 'mark_as_unread';
@@ -209,7 +210,7 @@ export class Chapters {
static async markAsRead(
chapters: (ChapterDownloadInfo & ChapterBookmarkInfo)[],
wasManuallyMarkedAsRead: boolean = false,
trackProgressMangaId?: TManga['id'],
trackProgressMangaId?: MangaIdInfo['id'],
): Promise<void> {
const { deleteChaptersManuallyMarkedRead, deleteChaptersWithBookmark, updateProgressManualMarkRead } =
await getMetadataServerSettings();
@@ -279,7 +280,7 @@ export class Chapters {
}: Action extends 'mark_as_read'
? {
wasManuallyMarkedAsRead: boolean;
trackProgressMangaId?: TManga['id'];
trackProgressMangaId?: MangaIdInfo['id'];
chapters: (ChapterDownloadInfo & ChapterBookmarkInfo & ChapterReadInfo)[];
}
: {

View File

@@ -8,19 +8,26 @@
import { t as translate } from 'i18next';
import { DocumentNode } from '@apollo/client/core';
import { MetadataMigrationSettings, TManga, TranslationKey } from '@/typings.ts';
import { MetadataMigrationSettings, TranslationKey } from '@/typings.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import {
ChapterConditionInput,
GetMangasBaseQuery,
GetMangasBaseQueryVariables,
GetMangasChapterIdsWithStateQuery,
GetMangaToMigrateQuery,
GetMangaToMigrateToFetchMutation,
MangaBaseFieldsFragment,
MangaReaderFieldsFragment,
MangaType,
TrackRecordType,
UpdateMangaCategoriesPatchInput,
} from '@/lib/graphql/generated/graphql.ts';
import { Chapters } from '@/lib/data/Chapters.ts';
import { makeToast } from '@/components/util/Toast.tsx';
import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
import { FULL_MANGA_FIELDS } from '@/lib/graphql/Fragments.ts';
import { GET_MANGAS_BASE } from '@/lib/graphql/queries/MangaQuery.ts';
import { MANGA_BASE_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
export type MangaAction =
| 'download'
@@ -108,10 +115,16 @@ export const actionToTranslationKey: {
},
};
export type MangaChapterCountInfo = { chapters: Pick<TManga['chapters'], 'totalCount'> };
export type MangaDownloadInfo = Pick<TManga, 'downloadCount'> & MangaChapterCountInfo;
export type MangaUnreadInfo = Pick<TManga, 'unreadCount'> & MangaChapterCountInfo;
export type MangaThumbnailInfo = Pick<TManga, 'thumbnailUrl' | 'thumbnailUrlLastFetched'>;
export type TMangaReader = MangaReaderFieldsFragment;
export type MangaIdInfo = Pick<MangaType, 'id'>;
export type MangaChapterCountInfo = { chapters: Pick<MangaType['chapters'], 'totalCount'> };
export type MangaDownloadInfo = Pick<MangaType, 'downloadCount'> & MangaChapterCountInfo;
export type MangaUnreadInfo = Pick<MangaType, 'unreadCount'> & MangaChapterCountInfo;
export type MangaThumbnailInfo = Pick<MangaType, 'thumbnailUrl' | 'thumbnailUrlLastFetched'>;
export type MangaTrackRecordInfo = MangaIdInfo & {
trackRecords: { nodes: Pick<TrackRecordType, 'id' | 'trackerId'>[] };
};
export type MigrateMode = 'copy' | 'migrate';
@@ -162,14 +175,14 @@ type PerformActionOptions<Action extends MangaAction> = Action extends 'mark_as_
: DefaultActionOption;
export class Mangas {
static getIds(mangas: { id: number }[]): number[] {
static getIds(mangas: MangaIdInfo[]): number[] {
return mangas.map((manga) => manga.id);
}
static getFromCache<T>(
id: number,
fragment: DocumentNode = FULL_MANGA_FIELDS,
fragmentName: string = 'FULL_MANGA_FIELDS',
static getFromCache<T = MangaBaseFieldsFragment>(
id: MangaIdInfo['id'],
fragment: DocumentNode = MANGA_BASE_FIELDS,
fragmentName: string = 'MANGA_BASE_FIELDS',
): T | null {
return requestManager.graphQLClient.client.cache.readFragment<T>({
id: requestManager.graphQLClient.client.cache.identify({
@@ -236,8 +249,10 @@ export class Mangas {
return requestManager.getValidImgUrlFor(thumbnailUrl);
}
static getDuplicateLibraryMangas(title: string): ReturnType<typeof requestManager.getMangas> {
return requestManager.getMangas({
static getDuplicateLibraryMangas(
title: string,
): ReturnType<typeof requestManager.getMangas<GetMangasBaseQuery, GetMangasBaseQueryVariables>> {
return requestManager.getMangas<GetMangasBaseQuery, GetMangasBaseQueryVariables>(GET_MANGAS_BASE, {
condition: { inLibrary: true },
filter: { title: { likeInsensitive: title } },
});
@@ -429,7 +444,7 @@ export class Mangas {
}
static async migrate(
mangaId: number,
mangaId: MangaIdInfo['id'],
mangaIdToMigrateTo: number,
{
mode,

View File

@@ -49,12 +49,13 @@ export type TTrackerSearch = TTrackerBase & Pick<TrackerType, 'authUrl'>;
export type TTrackerBind = TTrackerBase & Pick<TrackerType, 'icon' | 'supportsTrackDeletion' | 'scores' | 'statuses'>;
type TrackerIdInfo = Pick<TrackerType, 'id'>;
type LoggedInInfo = Pick<TrackerType, 'isLoggedIn' | 'isTokenExpired'>;
type TrackRecordTrackerInfo = { tracker: TTrackerBind };
type TrackRecordTrackerInfo = Pick<TrackRecordType, 'trackerId'>;
export class Trackers {
static getIds(trackers: { id: number }[]): number[] {
static getIds(trackers: TrackerIdInfo[]): number[] {
return trackers.map((tracker) => tracker.id);
}
@@ -74,16 +75,19 @@ export class Trackers {
return trackers.filter(this.isLoggedIn);
}
static getTrackers<TrackRecord extends TrackRecordTrackerInfo>(
static getTrackers<TrackRecord extends TrackRecordTrackerInfo, Tracker extends TrackerIdInfo>(
trackRecords: TrackRecord[],
): TrackRecord['tracker'][] {
return trackRecords.map((trackRecord) => trackRecord.tracker);
trackers: Tracker[],
): Tracker[] {
return trackRecords
.map((trackRecord) => trackers.find((tracker) => tracker.id === trackRecord.trackerId))
.filter((tracker) => !!tracker);
}
static getTrackRecordFor<TrackRecord extends TrackRecordTrackerInfo>(
tracker: { id: number },
tracker: TrackerIdInfo,
trackRecords: TrackRecord[],
): TrackRecord | undefined {
return trackRecords.find((trackRecord) => trackRecord.tracker.id === tracker.id);
return trackRecords.find((trackRecord) => trackRecord.trackerId === tracker.id);
}
}

View File

@@ -7,9 +7,6 @@
*/
import gql from 'graphql-tag';
import { SOURCE_BASE_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts';
import { TRACKER_BIND_FIELDS } from '@/lib/graphql/fragments/TrackFragments.ts';
import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
export const PAGE_INFO = gql`
fragment PAGE_INFO on PageInfo {
@@ -27,147 +24,6 @@ export const GLOBAL_METADATA = gql`
}
`;
export const FULL_CATEGORY_FIELDS = gql`
fragment FULL_CATEGORY_FIELDS on CategoryType {
default
id
includeInUpdate
includeInDownload
name
order
meta {
key
value
}
mangas {
totalCount
}
}
`;
export const FULL_TRACK_RECORD_FIELDS = gql`
${TRACK_RECORD_BIND_FIELDS}
${TRACKER_BIND_FIELDS}
fragment FULL_TRACK_RECORD_FIELDS on TrackRecordType {
...TRACK_RECORD_BIND_FIELDS
tracker {
...TRACKER_BIND_FIELDS
}
}
`;
export const BASE_MANGA_FIELDS = gql`
${SOURCE_BASE_FIELDS}
${FULL_TRACK_RECORD_FIELDS}
fragment BASE_MANGA_FIELDS on MangaType {
artist
author
chaptersLastFetchedAt
description
genre
id
inLibrary
inLibraryAt
initialized
lastFetchedAt
meta {
key
value
}
realUrl
source {
...SOURCE_BASE_FIELDS
}
status
thumbnailUrl
thumbnailUrlLastFetched
title
url
trackRecords {
totalCount
nodes {
...FULL_TRACK_RECORD_FIELDS
}
}
}
`;
export const PARTIAL_MANGA_FIELDS = gql`
${BASE_MANGA_FIELDS}
${FULL_CATEGORY_FIELDS}
fragment PARTIAL_MANGA_FIELDS on MangaType {
...BASE_MANGA_FIELDS
unreadCount
downloadCount
bookmarkCount
categories {
nodes {
...FULL_CATEGORY_FIELDS
}
totalCount
}
chapters {
totalCount
}
}
`;
export const FULL_CHAPTER_FIELDS = gql`
fragment FULL_CHAPTER_FIELDS on ChapterType {
chapterNumber
fetchedAt
id
isBookmarked
isDownloaded
isRead
lastPageRead
lastReadAt
mangaId
manga {
id
title
inLibrary
thumbnailUrl
lastFetchedAt
}
meta {
key
value
}
name
pageCount
realUrl
scanlator
sourceOrder
uploadDate
url
}
`;
export const FULL_MANGA_FIELDS = gql`
${PARTIAL_MANGA_FIELDS}
${FULL_CHAPTER_FIELDS}
fragment FULL_MANGA_FIELDS on MangaType {
...PARTIAL_MANGA_FIELDS
lastReadChapter {
...FULL_CHAPTER_FIELDS
}
latestReadChapter {
...FULL_CHAPTER_FIELDS
}
latestFetchedChapter {
...FULL_CHAPTER_FIELDS
}
latestUploadedChapter {
...FULL_CHAPTER_FIELDS
}
firstUnreadChapter {
...FULL_CHAPTER_FIELDS
}
}
`;
export const ABOUT_WEBUI = gql`
fragment ABOUT_WEBUI on AboutWebUI {
channel

View File

@@ -7,19 +7,7 @@
*/
import gql from 'graphql-tag';
const MANGA_BASE_FIELDS = gql`
fragment MANGA_BASE_FIELDS on MangaType {
id
title
thumbnailUrl
thumbnailUrlLastFetched
inLibrary
initialized
}
`;
import { MANGA_BASE_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
export const CHAPTER_BASE_FIELDS = gql`
fragment CHAPTER_BASE_FIELDS on ChapterType {

View File

@@ -0,0 +1,144 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import gql from 'graphql-tag';
export const MANGA_BASE_FIELDS = gql`
fragment MANGA_BASE_FIELDS on MangaType {
id
title
thumbnailUrl
thumbnailUrlLastFetched
inLibrary
initialized
sourceId
}
`;
export const MANGA_CHAPTER_STAT_FIELDS = gql`
fragment MANGA_CHAPTER_STAT_FIELDS on MangaType {
id
unreadCount
downloadCount
bookmarkCount
chapters {
totalCount
}
}
`;
export const MANGA_READER_FIELDS = gql`
${MANGA_BASE_FIELDS}
fragment MANGA_READER_FIELDS on MangaType {
...MANGA_BASE_FIELDS
meta {
key
value
}
chapters {
totalCount
}
trackRecords {
totalCount
}
}
`;
export const MANGA_LIBRARY_FIELDS = gql`
${MANGA_BASE_FIELDS}
${MANGA_CHAPTER_STAT_FIELDS}
fragment MANGA_LIBRARY_FIELDS on MangaType {
...MANGA_BASE_FIELDS
...MANGA_CHAPTER_STAT_FIELDS
genre
lastFetchedAt
inLibraryAt
trackRecords {
totalCount
nodes {
id
trackerId
}
}
firstUnreadChapter {
id
sourceOrder
}
lastReadChapter {
id
sourceOrder
lastReadAt
}
latestReadChapter {
id
sourceOrder
lastReadAt
}
latestFetchedChapter {
id
fetchedAt
}
latestUploadedChapter {
id
uploadDate
}
}
`;
export const MANGA_SCREEN_FIELDS = gql`
${MANGA_LIBRARY_FIELDS}
fragment MANGA_SCREEN_FIELDS on MangaType {
...MANGA_LIBRARY_FIELDS
artist
author
description
status
realUrl
sourceId
source {
id
displayName
}
trackRecords {
totalCount
nodes {
id
trackerId
}
}
}
`;
export const MANGA_LIBRARY_DUPLICATE_SCREEN_FIELDS = gql`
${MANGA_BASE_FIELDS}
${MANGA_CHAPTER_STAT_FIELDS}
fragment MANGA_LIBRARY_DUPLICATE_SCREEN_FIELDS on MangaType {
...MANGA_BASE_FIELDS
...MANGA_CHAPTER_STAT_FIELDS
description
}
`;

View File

@@ -7,7 +7,7 @@
*/
import gql from 'graphql-tag';
import { FULL_MANGA_FIELDS } from '@/lib/graphql/Fragments.ts';
import { MANGA_CHAPTER_STAT_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
const UPDATER_MANGA_FIELDS = gql`
fragment UPDATER_MANGA_FIELDS on MangaType {
@@ -19,7 +19,7 @@ const UPDATER_MANGA_FIELDS = gql`
export const UPDATER_SUBSCRIPTION_FIELDS = gql`
${UPDATER_MANGA_FIELDS}
${FULL_MANGA_FIELDS}
${MANGA_CHAPTER_STAT_FIELDS}
fragment UPDATER_SUBSCRIPTION_FIELDS on UpdateStatus {
isRunning
@@ -28,7 +28,7 @@ export const UPDATER_SUBSCRIPTION_FIELDS = gql`
mangas {
totalCount
nodes {
...FULL_MANGA_FIELDS
...MANGA_CHAPTER_STAT_FIELDS
}
}
}

View File

@@ -1,7 +1,7 @@
import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
import {
GetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetGlobalMetadataQueryVariables,
GetMangaQueryVariables, GetSourceBrowseQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
GetMangaScreenQueryVariables, GetSourceBrowseQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
} from "@/lib/graphql/generated/graphql.ts";
import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies";
export type AboutServerPayloadKeySpecifier = ('buildTime' | 'buildType' | 'discord' | 'github' | 'name' | 'revision' | 'version' | AboutServerPayloadKeySpecifier)[];
@@ -583,7 +583,7 @@ export type QueryFieldPolicy = {
extensions?: FieldPolicy<any> | FieldReadFunction<any>,
getWebUIUpdateStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetWebuiUpdateStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetWebuiUpdateStatusQueryVariables>>,
lastUpdateTimestamp?: FieldPolicy<any> | FieldReadFunction<any>,
manga?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetMangaQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetMangaQueryVariables>>,
manga?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetMangaScreenQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetMangaScreenQueryVariables>>,
mangas?: FieldPolicy<any> | FieldReadFunction<any>,
meta?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetGlobalMetadataQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetGlobalMetadataQueryVariables>>,
metas?: FieldPolicy<any> | FieldReadFunction<any>,

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@
*/
import gql from 'graphql-tag';
import { FULL_MANGA_FIELDS } from '@/lib/graphql/Fragments';
import { MANGA_SCREEN_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
export const DELETE_MANGA_METADATA = gql`
mutation DELETE_MANGA_METADATA($input: DeleteMangaMetaInput!) {
@@ -37,12 +37,13 @@ export const DELETE_MANGA_METADATA = gql`
// makes the server fetch and return the manga
export const GET_MANGA_FETCH = gql`
${FULL_MANGA_FIELDS}
${MANGA_SCREEN_FIELDS}
mutation GET_MANGA_FETCH($input: FetchMangaInput!) {
fetchManga(input: $input) {
clientMutationId
manga {
...FULL_MANGA_FIELDS
...MANGA_SCREEN_FIELDS
}
}
}

View File

@@ -7,17 +7,18 @@
*/
import gql from 'graphql-tag';
import { BASE_MANGA_FIELDS } from '@/lib/graphql/Fragments';
import { SOURCE_SETTING_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts';
import { MANGA_BASE_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
export const GET_SOURCE_MANGAS_FETCH = gql`
${BASE_MANGA_FIELDS}
${MANGA_BASE_FIELDS}
mutation GET_SOURCE_MANGAS_FETCH($input: FetchSourceMangaInput!) {
fetchSourceManga(input: $input) {
clientMutationId
hasNextPage
mangas {
...BASE_MANGA_FIELDS
...MANGA_BASE_FIELDS
}
}
}

View File

@@ -55,15 +55,13 @@ export const TRACKER_BIND = gql`
bindTrack(input: { mangaId: $mangaId, remoteId: $remoteId, trackerId: $trackerId }) {
trackRecord {
...TRACK_RECORD_BIND_FIELDS
tracker {
id
}
manga {
id
trackRecords {
totalCount
nodes {
id
trackerId
}
}
}
@@ -83,6 +81,7 @@ export const TRACKER_UNBIND = gql`
totalCount
nodes {
id
trackerId
}
}
}
@@ -104,6 +103,7 @@ export const TRACKER_UPDATE_BIND = gql`
totalCount
nodes {
id
trackerId
}
}
}

View File

@@ -7,12 +7,13 @@
*/
import gql from 'graphql-tag';
import { FULL_MANGA_FIELDS, PAGE_INFO } from '@/lib/graphql/Fragments';
import { PAGE_INFO } from '@/lib/graphql/Fragments';
import {
CATEGORY_BASE_FIELDS,
CATEGORY_LIBRARY_FIELDS,
CATEGORY_SETTING_FIELDS,
} from '@/lib/graphql/fragments/CategoryFragments.ts';
import { MANGA_LIBRARY_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
export const GET_CATEGORIES_BASE = gql`
${CATEGORY_BASE_FIELDS}
@@ -126,14 +127,15 @@ export const GET_CATEGORIES_SETTINGS = gql`
`;
export const GET_CATEGORY_MANGAS = gql`
${FULL_MANGA_FIELDS}
${MANGA_LIBRARY_FIELDS}
${PAGE_INFO}
query GET_CATEGORY_MANGAS($id: Int!) {
category(id: $id) {
id
mangas {
nodes {
...FULL_MANGA_FIELDS
...MANGA_LIBRARY_FIELDS
}
pageInfo {
...PAGE_INFO

View File

@@ -7,15 +7,68 @@
*/
import gql from 'graphql-tag';
import { FULL_CHAPTER_FIELDS, FULL_MANGA_FIELDS, PAGE_INFO } from '@/lib/graphql/Fragments';
import { PAGE_INFO } from '@/lib/graphql/Fragments';
import {
MANGA_BASE_FIELDS,
MANGA_LIBRARY_DUPLICATE_SCREEN_FIELDS,
MANGA_LIBRARY_FIELDS,
MANGA_READER_FIELDS,
MANGA_SCREEN_FIELDS,
} from '@/lib/graphql/fragments/MangaFragments.ts';
import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
// returns the current manga from the database
export const GET_MANGA = gql`
${FULL_MANGA_FIELDS}
${FULL_CHAPTER_FIELDS}
query GET_MANGA($id: Int!) {
export const GET_MANGA_SCREEN = gql`
${MANGA_SCREEN_FIELDS}
query GET_MANGA_SCREEN($id: Int!) {
manga(id: $id) {
...FULL_MANGA_FIELDS
...MANGA_SCREEN_FIELDS
}
}
`;
// returns the current manga from the database
export const GET_MANGA_READER = gql`
${MANGA_READER_FIELDS}
query GET_MANGA_READER($id: Int!) {
manga(id: $id) {
...MANGA_READER_FIELDS
}
}
`;
// returns the current manga from the database
export const GET_MANGA_TRACK_RECORDS = gql`
${TRACK_RECORD_BIND_FIELDS}
query GET_MANGA_TRACK_RECORDS($id: Int!) {
manga(id: $id) {
id
trackRecords {
totalCount
nodes {
...TRACK_RECORD_BIND_FIELDS
}
}
}
}
`;
// returns the current manga from the database
export const GET_MANGA_CATEGORIES = gql`
query GET_MANGA_CATEGORIES($id: Int!) {
manga(id: $id) {
id
categories {
totalCount
nodes {
id
}
}
}
}
`;
@@ -62,11 +115,11 @@ export const GET_MANGA_TO_MIGRATE = gql`
`;
// returns the current manga from the database
export const GET_MANGAS = gql`
${FULL_MANGA_FIELDS}
${FULL_CHAPTER_FIELDS}
export const GET_MANGAS_BASE = gql`
${MANGA_BASE_FIELDS}
${PAGE_INFO}
query GET_MANGAS(
query GET_MANGAS_BASE(
$after: Cursor
$before: Cursor
$condition: MangaConditionInput
@@ -89,7 +142,83 @@ export const GET_MANGAS = gql`
orderByType: $orderByType
) {
nodes {
...FULL_MANGA_FIELDS
...MANGA_BASE_FIELDS
}
pageInfo {
...PAGE_INFO
}
totalCount
}
}
`;
// returns the current manga from the database
export const GET_MANGAS_LIBRARY = gql`
${MANGA_LIBRARY_FIELDS}
${PAGE_INFO}
query GET_MANGAS_LIBRARY(
$after: Cursor
$before: Cursor
$condition: MangaConditionInput
$filter: MangaFilterInput
$first: Int
$last: Int
$offset: Int
$orderBy: MangaOrderBy
$orderByType: SortOrder
) {
mangas(
after: $after
before: $before
condition: $condition
filter: $filter
first: $first
last: $last
offset: $offset
orderBy: $orderBy
orderByType: $orderByType
) {
nodes {
...MANGA_LIBRARY_FIELDS
}
pageInfo {
...PAGE_INFO
}
totalCount
}
}
`;
// returns the current manga from the database
export const GET_MANGAS_DUPLICATES = gql`
${MANGA_LIBRARY_DUPLICATE_SCREEN_FIELDS}
${PAGE_INFO}
query GET_MANGAS_DUPLICATES(
$after: Cursor
$before: Cursor
$condition: MangaConditionInput
$filter: MangaFilterInput
$first: Int
$last: Int
$offset: Int
$orderBy: MangaOrderBy
$orderByType: SortOrder
) {
mangas(
after: $after
before: $before
condition: $condition
filter: $filter
first: $first
last: $last
offset: $offset
orderBy: $orderBy
orderByType: $orderByType
) {
nodes {
...MANGA_LIBRARY_DUPLICATE_SCREEN_FIELDS
}
pageInfo {
...PAGE_INFO
@@ -106,9 +235,7 @@ export const GET_MIGRATABLE_SOURCE_MANGAS = gql`
id
title
thumbnailUrl
source {
id
}
sourceId
categories {
nodes {
id

View File

@@ -14,13 +14,13 @@ import {
Metadata,
MetadataHolder,
MetadataKeyValuePair,
TManga,
} from '@/typings.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { MetaType, SourceType } from '@/lib/graphql/generated/graphql.ts';
import { DEFAULT_DEVICE, getActiveDevice } from '@/util/device.ts';
import { CategoryIdInfo } from '@/lib/data/Categories.ts';
import { ChapterIdInfo } from '@/lib/data/Chapters.ts';
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
const APP_METADATA_KEY_PREFIX = 'webUI_';
@@ -378,7 +378,7 @@ export const requestUpdateMetadataValue = async (
await requestManager.setGlobalMetadata(metadataKey, value).response;
break;
case 'manga':
await requestManager.setMangaMeta((metadataHolder as TManga).id, metadataKey, value).response;
await requestManager.setMangaMeta((metadataHolder as MangaIdInfo).id, metadataKey, value).response;
break;
case 'source':
await requestManager.setSourceMeta((metadataHolder as Pick<SourceType, 'id'>).id, metadataKey, value)
@@ -400,7 +400,7 @@ export const requestUpdateServerMetadata = async (keysToValues: MetadataKeyValue
requestUpdateMetadata({}, 'global', keysToValues);
export const requestUpdateMangaMetadata = async (
manga: TManga,
manga: MangaIdInfo & GqlMetaHolder,
keysToValues: MetadataKeyValuePair[],
): Promise<void[]> => requestUpdateMetadata(manga, 'manga', keysToValues);

View File

@@ -6,7 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { Metadata, IReaderSettings, MetadataKeyValuePair, GqlMetaHolder, TManga } from '@/typings.ts';
import { Metadata, IReaderSettings, MetadataKeyValuePair, GqlMetaHolder } from '@/typings.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import {
convertFromGqlMeta,
@@ -15,6 +15,7 @@ import {
requestUpdateServerMetadata,
} from '@/lib/metadata/metadata.ts';
import { MetaType } from '@/lib/graphql/generated/graphql.ts';
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
type UndefinedReaderSettings = {
[setting in keyof IReaderSettings]: IReaderSettings[setting] | undefined;
@@ -109,7 +110,7 @@ export const checkAndHandleMissingStoredReaderSettings = async (
}
if (metadataHolderType === 'manga') {
await requestUpdateMangaMetadata(metadataHolder as TManga, settingsToUpdate);
await requestUpdateMangaMetadata(metadataHolder as MangaIdInfo & GqlMetaHolder, settingsToUpdate);
return;
}

View File

@@ -81,10 +81,6 @@ import {
GetMangaChaptersFetchMutationVariables,
GetMangaFetchMutation,
GetMangaFetchMutationVariables,
GetMangaQuery,
GetMangaQueryVariables,
GetMangasQuery,
GetMangasQueryVariables,
GetRestoreStatusQuery,
GetRestoreStatusQueryVariables,
GetServerSettingsQuery,
@@ -197,6 +193,8 @@ import {
GetChaptersUpdatesQueryVariables,
GetSourcesListQuery,
GetSourcesListQueryVariables,
GetMangasLibraryQuery,
GetMangasLibraryQueryVariables,
} from '@/lib/graphql/generated/graphql.ts';
import { GET_GLOBAL_METADATAS } from '@/lib/graphql/queries/GlobalMetadataQuery.ts';
import { SET_GLOBAL_METADATA } from '@/lib/graphql/mutations/GlobalMetadataMutation.ts';
@@ -223,9 +221,9 @@ import {
UPDATE_MANGAS_CATEGORIES,
} from '@/lib/graphql/mutations/MangaMutation.ts';
import {
GET_MANGA,
GET_MANGA_TO_MIGRATE,
GET_MANGAS,
GET_MANGA_TRACK_RECORDS,
GET_MANGAS_LIBRARY,
GET_MIGRATABLE_SOURCE_MANGAS,
} from '@/lib/graphql/queries/MangaQuery.ts';
import {
@@ -283,7 +281,7 @@ import { DOWNLOAD_STATUS_SUBSCRIPTION } from '@/lib/graphql/subscriptions/Downlo
import { UPDATER_SUBSCRIPTION } from '@/lib/graphql/subscriptions/UpdaterSubscription.ts';
import { GET_SERVER_SETTINGS } from '@/lib/graphql/queries/SettingsQuery.ts';
import { UPDATE_SERVER_SETTINGS } from '@/lib/graphql/mutations/SettingsMutation.ts';
import { BASE_MANGA_FIELDS, GLOBAL_METADATA } from '@/lib/graphql/Fragments.ts';
import { GLOBAL_METADATA } from '@/lib/graphql/Fragments.ts';
import { CLEAR_SERVER_CACHE } from '@/lib/graphql/mutations/ImageMutation.ts';
import { RESET_WEBUI_UPDATE_STATUS, UPDATE_WEBUI } from '@/lib/graphql/mutations/ServerInfoMutation.ts';
import { WEBUI_UPDATE_SUBSCRIPTION } from '@/lib/graphql/subscriptions/ServerInfoSubscription.ts';
@@ -301,9 +299,11 @@ import {
TRACKER_UPDATE_BIND,
} from '@/lib/graphql/mutations/TrackerMutation.ts';
import { ControlledPromise } from '@/lib/ControlledPromise.ts';
import { MetadataMigrationSettings, TManga } from '@/typings.ts';
import { MetadataMigrationSettings } from '@/typings.ts';
import { DOWNLOAD_STATUS_FIELDS } from '@/lib/graphql/fragments/DownloadFragments.ts';
import { EXTENSION_LIST_FIELDS } from '@/lib/graphql/fragments/ExtensionFragments.ts';
import { MANGA_BASE_FIELDS } from '@/lib/graphql/fragments/MangaFragments.ts';
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
enum GQLMethod {
QUERY = 'QUERY',
@@ -1555,8 +1555,8 @@ export class RequestManager {
(manga) =>
this.graphQLClient.client.cache.readFragment<typeof manga>({
id: this.graphQLClient.client.cache.identify(manga),
fragment: BASE_MANGA_FIELDS,
fragmentName: 'BASE_MANGA_FIELDS',
fragment: MANGA_BASE_FIELDS,
fragmentName: 'MANGA_BASE_FIELDS',
}) ?? manga,
),
},
@@ -1630,18 +1630,20 @@ export class RequestManager {
);
}
public useGetManga(
public useGetManga<Data, Variables extends OperationVariables = OperationVariables>(
document: DocumentNode | TypedDocumentNode<Data, Variables>,
mangaId: number | string,
options?: QueryHookOptions<GetMangaQuery, GetMangaQueryVariables>,
): AbortableApolloUseQueryResponse<GetMangaQuery, GetMangaQueryVariables> {
return this.doRequest(GQLMethod.USE_QUERY, GET_MANGA, { id: Number(mangaId) }, options);
options?: QueryHookOptions<Data, Variables>,
): AbortableApolloUseQueryResponse<Data, Variables> {
return this.doRequest(GQLMethod.USE_QUERY, document, { id: Number(mangaId) } as unknown as Variables, options);
}
public getManga(
public getManga<Data, Variables extends OperationVariables = OperationVariables>(
document: DocumentNode | TypedDocumentNode<Data, Variables>,
mangaId: number | string,
options?: QueryOptions<GetMangaQueryVariables, GetMangaQuery>,
): AbortabaleApolloQueryResponse<GetMangaQuery> {
return this.doRequest(GQLMethod.QUERY, GET_MANGA, { id: Number(mangaId) }, options);
options?: QueryOptions<Variables, Data>,
): AbortabaleApolloQueryResponse<Data> {
return this.doRequest(GQLMethod.QUERY, document, { id: Number(mangaId) } as unknown as Variables, options);
}
public getMangaToMigrate(
@@ -1712,18 +1714,20 @@ export class RequestManager {
);
}
public useGetMangas(
variables: GetMangasQueryVariables,
options?: QueryHookOptions<GetMangasQuery, GetMangasQueryVariables>,
): AbortableApolloUseQueryResponse<GetMangasQuery, GetMangasQueryVariables> {
return this.doRequest(GQLMethod.USE_QUERY, GET_MANGAS, variables, options);
public useGetMangas<Data, Variables extends OperationVariables = OperationVariables>(
document: DocumentNode | TypedDocumentNode<Data, Variables>,
variables: Variables,
options?: QueryHookOptions<Data, Variables>,
): AbortableApolloUseQueryResponse<Data, Variables> {
return this.doRequest(GQLMethod.USE_QUERY, document, variables, options);
}
public getMangas(
variables: GetMangasQueryVariables,
options?: QueryOptions<GetMangasQueryVariables, GetMangasQuery>,
): AbortabaleApolloQueryResponse<GetMangasQuery> {
return this.doRequest(GQLMethod.QUERY, GET_MANGAS, variables, options);
public getMangas<Data, Variables extends OperationVariables = OperationVariables>(
document: DocumentNode | TypedDocumentNode<Data, Variables>,
variables: Variables,
options?: QueryOptions<Variables, Data>,
): AbortabaleApolloQueryResponse<Data> {
return this.doRequest(GQLMethod.QUERY, document, variables, options);
}
public useGetMigratableSourceMangas(
@@ -2014,7 +2018,7 @@ export class RequestManager {
public updateChapters(
ids: number[],
patch: UpdateChapterPatchInput & { chapterIdsToDelete?: number[]; trackProgressMangaId?: TManga['id'] },
patch: UpdateChapterPatchInput & { chapterIdsToDelete?: number[]; trackProgressMangaId?: MangaIdInfo['id'] },
options?: MutationOptions<UpdateChaptersMutation, UpdateChaptersMutationVariables>,
): AbortableApolloMutationResponse<UpdateChaptersMutation> {
const { chapterIdsToDelete = [], trackProgressMangaId = -1, ...updatePatch } = patch;
@@ -2144,8 +2148,8 @@ export class RequestManager {
public useGetCategoryMangas(
id: number,
options?: QueryHookOptions<GetMangasQuery, GetMangasQueryVariables>,
): AbortableApolloUseQueryResponse<GetMangasQuery, GetMangasQueryVariables> {
options?: QueryHookOptions<GetMangasLibraryQuery, GetMangasLibraryQueryVariables>,
): AbortableApolloUseQueryResponse<GetMangasLibraryQuery, GetMangasLibraryQueryVariables> {
const isDefaultCategory = id === 0;
if (isDefaultCategory) {
// hacky way of loading the default category mangas - some stuff won't work but since that is not used anyway, it won't be a problem
@@ -2165,10 +2169,10 @@ export class RequestManager {
__typename: 'Query',
}
: undefined,
} as unknown as AbortableApolloUseQueryResponse<GetMangasQuery, GetMangasQueryVariables>;
} as unknown as AbortableApolloUseQueryResponse<GetMangasLibraryQuery, GetMangasLibraryQueryVariables>;
}
return this.useGetMangas({ condition: { inLibrary: true, categoryIds: [id] } }, options);
return this.useGetMangas(GET_MANGAS_LIBRARY, { condition: { inLibrary: true, categoryIds: [id] } }, options);
}
public deleteCategory(
@@ -2597,7 +2601,7 @@ export class RequestManager {
GQLMethod.MUTATION,
TRACKER_UNBIND,
{ input: { recordId, deleteRemoteTrack } },
{ refetchQueries: [GET_MANGA], ...options },
{ refetchQueries: [GET_MANGA_TRACK_RECORDS], ...options },
);
}