Add new single multipurpose metadata update mutation
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { requestUpdateCategoryMetadata } from '@/features/metadata/services/MetadataUpdater.ts';
|
import { requestCategoryMetadataUpdate } from '@/features/metadata/services/MetadataUpdater.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { LibraryOptions } from '@/features/library/Library.types.ts';
|
import { LibraryOptions } from '@/features/library/Library.types.ts';
|
||||||
import { CategoryIdInfo, CategoryMetadataKeys, ICategoryMetadata } from '@/features/category/Category.types.ts';
|
import { CategoryIdInfo, CategoryMetadataKeys, ICategoryMetadata } from '@/features/category/Category.types.ts';
|
||||||
@@ -81,9 +81,9 @@ export const updateCategoryMetadata = async <
|
|||||||
metadataKey: MetadataKey,
|
metadataKey: MetadataKey,
|
||||||
value: ICategoryMetadata[MetadataKey],
|
value: ICategoryMetadata[MetadataKey],
|
||||||
): Promise<void> =>
|
): Promise<void> =>
|
||||||
requestUpdateCategoryMetadata(category, [
|
requestCategoryMetadataUpdate(category, {
|
||||||
[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]],
|
update: [[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]]],
|
||||||
]);
|
});
|
||||||
|
|
||||||
export const createUpdateCategoryMetadata =
|
export const createUpdateCategoryMetadata =
|
||||||
<Settings extends CategoryMetadataKeys>(
|
<Settings extends CategoryMetadataKeys>(
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
MetadataHolder,
|
MetadataHolder,
|
||||||
} from '@/features/metadata/Metadata.types.ts';
|
} from '@/features/metadata/Metadata.types.ts';
|
||||||
import { convertFromGqlMeta } from '@/features/metadata/services/MetadataConverter.ts';
|
import { convertFromGqlMeta } from '@/features/metadata/services/MetadataConverter.ts';
|
||||||
import { requestUpdateMangaMetadata } from '@/features/metadata/services/MetadataUpdater.ts';
|
import { requestMangaMetadataUpdate } from '@/features/metadata/services/MetadataUpdater.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
|
|
||||||
const DEFAULT_MANGA_METADATA: MangaMetadata = {
|
const DEFAULT_MANGA_METADATA: MangaMetadata = {
|
||||||
@@ -69,9 +69,9 @@ export const updateMangaMetadata = async <
|
|||||||
metadataKey: MetadataKey,
|
metadataKey: MetadataKey,
|
||||||
value: MangaMetadata[MetadataKey],
|
value: MangaMetadata[MetadataKey],
|
||||||
): Promise<void> =>
|
): Promise<void> =>
|
||||||
requestUpdateMangaMetadata(manga, [
|
requestMangaMetadataUpdate(manga, {
|
||||||
[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]],
|
update: [[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]]],
|
||||||
]);
|
});
|
||||||
|
|
||||||
export const createUpdateMangaMetadata =
|
export const createUpdateMangaMetadata =
|
||||||
<Settings extends MangaMetadataKeys>(
|
<Settings extends MangaMetadataKeys>(
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { extractOriginalKey, getMetadataKey } from '@/features/metadata/Metadata
|
|||||||
import { MangaIdInfo } from '@/features/manga/Manga.types.ts';
|
import { MangaIdInfo } from '@/features/manga/Manga.types.ts';
|
||||||
import { CategoryIdInfo } from '@/features/category/Category.types.ts';
|
import { CategoryIdInfo } from '@/features/category/Category.types.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { getMetadataDeleteFunction, getMetadataUpdateFunction } from '@/features/metadata/services/MetadataUpdater.ts';
|
import { getMetadataUpdateFunction } from '@/features/metadata/services/MetadataUpdater.ts';
|
||||||
import { SourceIdInfo } from '@/features/source/Source.types.ts';
|
import { SourceIdInfo } from '@/features/source/Source.types.ts';
|
||||||
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
@@ -295,7 +295,6 @@ const commitMigratedMetadata = (
|
|||||||
]) as MetadataKeyValuePair[];
|
]) as MetadataKeyValuePair[];
|
||||||
|
|
||||||
const updateMetadata = getMetadataUpdateFunction(type, metadataHolder ?? { id: -1, meta: {} });
|
const updateMetadata = getMetadataUpdateFunction(type, metadataHolder ?? { id: -1, meta: {} });
|
||||||
const deleteMetadata = getMetadataDeleteFunction(type, metadataHolder ?? { id: -1, meta: {} });
|
|
||||||
|
|
||||||
useEffectFn(() => {
|
useEffectFn(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -317,9 +316,12 @@ const commitMigratedMetadata = (
|
|||||||
commitedMigrations.add(itemMigrationKey);
|
commitedMigrations.add(itemMigrationKey);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateMetadata([...metadataToUpdate], undefined, true);
|
await updateMetadata({
|
||||||
await deleteMetadata(metadataKeysToDelete, undefined, true);
|
update: metadataToUpdate,
|
||||||
await updateMetadata([['migration', METADATA_MIGRATIONS.length]]);
|
delete: metadataKeysToDelete,
|
||||||
|
migrate: [['migration', METADATA_MIGRATIONS.length]],
|
||||||
|
isMetadataKey: true,
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
commitedMigrations.delete(itemMigrationKey);
|
commitedMigrations.delete(itemMigrationKey);
|
||||||
|
|
||||||
|
|||||||
@@ -21,82 +21,96 @@ import { convertToGqlMeta } from '@/features/metadata/services/MetadataConverter
|
|||||||
import { SourceIdInfo } from '@/features/source/Source.types.ts';
|
import { SourceIdInfo } from '@/features/source/Source.types.ts';
|
||||||
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
||||||
|
|
||||||
const requestUpdateMetadataValues = async (
|
type MetadataUpdateOptions = {
|
||||||
|
update?: MetadataKeyValuePair[];
|
||||||
|
delete?: AppMetadataKeys[];
|
||||||
|
/**
|
||||||
|
* Only ever pass the "migration" key value pair into this.
|
||||||
|
*/
|
||||||
|
migrate?: MetadataKeyValuePair[];
|
||||||
|
keyPrefixes?: string[];
|
||||||
|
/**
|
||||||
|
* Applies to "update" and "delete" metadata value pairs. "migrate" is excluded from this and is always expected to not be already converted to a metadata key
|
||||||
|
*/
|
||||||
|
isMetadataKey?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const requestMetadataUpdate = async (
|
||||||
metadataHolder: GqlMetaHolder,
|
metadataHolder: GqlMetaHolder,
|
||||||
holderType: MetadataHolderType,
|
holderType: MetadataHolderType,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
{
|
||||||
keyPrefixes?: string[],
|
update: keysToValues = [],
|
||||||
isMetadataKey: boolean = false,
|
delete: keysToDelete = [],
|
||||||
|
migrate: keysToMigrate = [],
|
||||||
|
keyPrefixes,
|
||||||
|
isMetadataKey = false,
|
||||||
|
}: MetadataUpdateOptions,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const metas = keysToValues.map(([key, value]) => ({
|
if (keysToMigrate?.length > 1 || (keysToMigrate?.length === 1 && keysToMigrate[0][0] !== 'migration')) {
|
||||||
|
throw new Error(
|
||||||
|
`requestMetadataUpdate: "migrate" option must only contain a single key-value pair with the key "migration"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateMetas = keysToValues.map(([key, value]) => ({
|
||||||
key: isMetadataKey ? key : getMetadataKey(key, keyPrefixes),
|
key: isMetadataKey ? key : getMetadataKey(key, keyPrefixes),
|
||||||
value: `${value}`,
|
value: `${value}`,
|
||||||
}));
|
}));
|
||||||
|
const deleteKeys = keysToDelete.map((key) => (isMetadataKey ? key : getMetadataKey(key, keyPrefixes)));
|
||||||
|
const migrateMetas = keysToMigrate.map(([key, value]) => ({
|
||||||
|
key: getMetadataKey(key, keyPrefixes),
|
||||||
|
value: `${value}`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const updateMetaInput = {
|
||||||
|
updateInput: { metas: updateMetas },
|
||||||
|
deleteInput: { keys: deleteKeys },
|
||||||
|
migrateInput: { metas: migrateMetas },
|
||||||
|
};
|
||||||
|
|
||||||
switch (holderType) {
|
switch (holderType) {
|
||||||
case 'category':
|
case 'category':
|
||||||
await requestManager.setCategoryMeta({
|
await requestManager.updateCategoryMeta([(metadataHolder as CategoryIdInfo).id], updateMetaInput).response;
|
||||||
items: [{ categoryIds: [(metadataHolder as CategoryIdInfo).id], metas }],
|
|
||||||
}).response;
|
|
||||||
break;
|
break;
|
||||||
case 'chapter':
|
case 'chapter':
|
||||||
await requestManager.setChapterMeta({
|
await requestManager.updateChapterMeta([(metadataHolder as ChapterIdInfo).id], updateMetaInput).response;
|
||||||
items: [{ chapterIds: [(metadataHolder as ChapterIdInfo).id], metas }],
|
|
||||||
}).response;
|
|
||||||
break;
|
break;
|
||||||
case 'global':
|
case 'global':
|
||||||
await requestManager.setGlobalMetadata({
|
await requestManager.updateGlobalMeta(updateMetaInput).response;
|
||||||
metas,
|
|
||||||
}).response;
|
|
||||||
break;
|
break;
|
||||||
case 'manga':
|
case 'manga':
|
||||||
await requestManager.setMangaMeta({
|
await requestManager.updateMangaMeta([(metadataHolder as MangaIdInfo).id], updateMetaInput).response;
|
||||||
items: [{ mangaIds: [(metadataHolder as MangaIdInfo).id], metas }],
|
|
||||||
}).response;
|
|
||||||
break;
|
break;
|
||||||
case 'source':
|
case 'source':
|
||||||
await requestManager.setSourceMeta({
|
await requestManager.updateSourceMeta([(metadataHolder as SourceIdInfo).id], updateMetaInput).response;
|
||||||
items: [{ sourceIds: [(metadataHolder as SourceIdInfo).id], metas }],
|
|
||||||
}).response;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`requestUpdateMetadataValues: unknown holderType "${holderType}"`);
|
throw new Error(`requestMetadataUpdate: unknown holderType "${holderType}"`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const requestUpdateServerMetadata = async (
|
export const requestServerMetadataUpdate = async (options: MetadataUpdateOptions): Promise<void> =>
|
||||||
keysToValues: MetadataKeyValuePair[],
|
requestMetadataUpdate({}, 'global', options);
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestUpdateMetadataValues({}, 'global', keysToValues, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestUpdateMangaMetadata = async (
|
export const requestMangaMetadataUpdate = async (
|
||||||
manga: MangaIdInfo & GqlMetaHolder,
|
manga: MangaIdInfo & GqlMetaHolder,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
options: MetadataUpdateOptions,
|
||||||
keyPrefixes?: string[],
|
): Promise<void> => requestMetadataUpdate(manga, 'manga', options);
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestUpdateMetadataValues(manga, 'manga', keysToValues, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestUpdateChapterMetadata = async (
|
export const requestChapterMetadataUpdate = async (
|
||||||
chapter: ChapterIdInfo & GqlMetaHolder,
|
chapter: ChapterIdInfo & GqlMetaHolder,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
options: MetadataUpdateOptions,
|
||||||
keyPrefixes?: string[],
|
): Promise<void> => requestMetadataUpdate(chapter, 'chapter', options);
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestUpdateMetadataValues(chapter, 'chapter', keysToValues, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestUpdateCategoryMetadata = async (
|
export const requestCategoryMetadataUpdate = async (
|
||||||
category: CategoryIdInfo & GqlMetaHolder,
|
category: CategoryIdInfo & GqlMetaHolder,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
options: MetadataUpdateOptions,
|
||||||
keyPrefixes?: string[],
|
): Promise<void> => requestMetadataUpdate(category, 'category', options);
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestUpdateMetadataValues(category, 'category', keysToValues, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestUpdateSourceMetadata = async (
|
export const requestSourceMetadataUpdate = async (
|
||||||
source: SourceIdInfo & GqlMetaHolder,
|
source: SourceIdInfo & GqlMetaHolder,
|
||||||
keysToValue: MetadataKeyValuePair[],
|
options: MetadataUpdateOptions,
|
||||||
keyPrefixes?: string[],
|
): Promise<void> => requestMetadataUpdate(source, 'source', options);
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestUpdateMetadataValues(source, 'source', keysToValue, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const getMetadataUpdateFunction = (
|
export const getMetadataUpdateFunction = (
|
||||||
type: MetadataHolderType,
|
type: MetadataHolderType,
|
||||||
@@ -106,154 +120,33 @@ export const getMetadataUpdateFunction = (
|
|||||||
| (ChapterIdInfo & MetadataHolder)
|
| (ChapterIdInfo & MetadataHolder)
|
||||||
| (CategoryIdInfo & MetadataHolder)
|
| (CategoryIdInfo & MetadataHolder)
|
||||||
| (SourceIdInfo & MetadataHolder),
|
| (SourceIdInfo & MetadataHolder),
|
||||||
): ((keyValuePair: MetadataKeyValuePair[], prefixes?: string[], isMetadataKey?: boolean) => Promise<void>) => {
|
): ((options: MetadataUpdateOptions) => Promise<void>) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'global':
|
case 'global':
|
||||||
return (...args) => requestUpdateServerMetadata(...args);
|
return (options) => requestServerMetadataUpdate(options);
|
||||||
case 'manga':
|
case 'manga':
|
||||||
return (...args) =>
|
return (options) =>
|
||||||
requestUpdateMangaMetadata(
|
requestMangaMetadataUpdate(
|
||||||
{ id: (metadataHolder as MangaIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
{ id: (metadataHolder as MangaIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
||||||
...args,
|
options,
|
||||||
);
|
);
|
||||||
case 'chapter':
|
case 'chapter':
|
||||||
return (...args) =>
|
return (options) =>
|
||||||
requestUpdateChapterMetadata(
|
requestChapterMetadataUpdate(
|
||||||
{ id: (metadataHolder as ChapterIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
{ id: (metadataHolder as ChapterIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
||||||
...args,
|
options,
|
||||||
);
|
);
|
||||||
case 'category':
|
case 'category':
|
||||||
return (...args) =>
|
return (options) =>
|
||||||
requestUpdateCategoryMetadata(
|
requestCategoryMetadataUpdate(
|
||||||
{ id: (metadataHolder as CategoryIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
{ id: (metadataHolder as CategoryIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
||||||
...args,
|
options,
|
||||||
);
|
);
|
||||||
case 'source':
|
case 'source':
|
||||||
return (...args) =>
|
return (options) =>
|
||||||
requestUpdateSourceMetadata(
|
requestSourceMetadataUpdate(
|
||||||
{
|
{ id: (metadataHolder as SourceIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
||||||
id: (metadataHolder as SourceIdInfo).id,
|
options,
|
||||||
meta: convertToGqlMeta(metadataHolder.meta),
|
|
||||||
},
|
|
||||||
...args,
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
throw new Error(`Unexpected "type" (${type})`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const requestDeleteMetadataValues = async (
|
|
||||||
metadataHolder: GqlMetaHolder,
|
|
||||||
holderType: MetadataHolderType,
|
|
||||||
keys: AppMetadataKeys[],
|
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey: boolean = false,
|
|
||||||
): Promise<void> => {
|
|
||||||
const metadataKeys = keys.map((key) => (isMetadataKey ? key : getMetadataKey(key, keyPrefixes)));
|
|
||||||
|
|
||||||
switch (holderType) {
|
|
||||||
case 'category':
|
|
||||||
await requestManager.deleteCategoryMeta({
|
|
||||||
items: [{ categoryIds: [(metadataHolder as CategoryIdInfo).id], keys: metadataKeys }],
|
|
||||||
}).response;
|
|
||||||
break;
|
|
||||||
case 'chapter':
|
|
||||||
await requestManager.deleteChapterMeta({
|
|
||||||
items: [{ chapterIds: [(metadataHolder as ChapterIdInfo).id], keys: metadataKeys }],
|
|
||||||
}).response;
|
|
||||||
break;
|
|
||||||
case 'global':
|
|
||||||
await requestManager.deleteGlobalMeta({
|
|
||||||
keys: metadataKeys,
|
|
||||||
}).response;
|
|
||||||
break;
|
|
||||||
case 'manga':
|
|
||||||
await requestManager.deleteMangaMeta({
|
|
||||||
items: [{ mangaIds: [(metadataHolder as MangaIdInfo).id], keys: metadataKeys }],
|
|
||||||
}).response;
|
|
||||||
break;
|
|
||||||
case 'source':
|
|
||||||
await requestManager.deleteSourceMeta({
|
|
||||||
items: [{ sourceIds: [(metadataHolder as SourceIdInfo).id], keys: metadataKeys }],
|
|
||||||
}).response;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error(`requestDeleteMetadataValues: unknown holderType "${holderType}"`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const requestDeleteServerMetadata = async (
|
|
||||||
keys: AppMetadataKeys[],
|
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestDeleteMetadataValues({}, 'global', keys, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestDeleteMangaMetadata = async (
|
|
||||||
manga: MangaIdInfo & GqlMetaHolder,
|
|
||||||
keys: AppMetadataKeys[],
|
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestDeleteMetadataValues(manga, 'manga', keys, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestDeleteChapterMetadata = async (
|
|
||||||
chapter: ChapterIdInfo & GqlMetaHolder,
|
|
||||||
keys: AppMetadataKeys[],
|
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestDeleteMetadataValues(chapter, 'chapter', keys, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestDeleteCategoryMetadata = async (
|
|
||||||
category: CategoryIdInfo & GqlMetaHolder,
|
|
||||||
keys: AppMetadataKeys[],
|
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestDeleteMetadataValues(category, 'category', keys, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const requestDeleteSourceMetadata = async (
|
|
||||||
source: SourceIdInfo & GqlMetaHolder,
|
|
||||||
keys: AppMetadataKeys[],
|
|
||||||
keyPrefixes?: string[],
|
|
||||||
isMetadataKey?: boolean,
|
|
||||||
): Promise<void> => requestDeleteMetadataValues(source, 'source', keys, keyPrefixes, isMetadataKey);
|
|
||||||
|
|
||||||
export const getMetadataDeleteFunction = (
|
|
||||||
type: MetadataHolderType,
|
|
||||||
metadataHolder:
|
|
||||||
| MetadataHolder
|
|
||||||
| (MangaIdInfo & MetadataHolder)
|
|
||||||
| (ChapterIdInfo & MetadataHolder)
|
|
||||||
| (CategoryIdInfo & MetadataHolder)
|
|
||||||
| (SourceIdInfo & MetadataHolder),
|
|
||||||
): ((metadataToDelete: AppMetadataKeys[], keyPrefixes?: string[], isMetadataKey?: boolean) => Promise<void>) => {
|
|
||||||
switch (type) {
|
|
||||||
case 'global':
|
|
||||||
return (...args) => requestDeleteServerMetadata(...args);
|
|
||||||
case 'manga':
|
|
||||||
return (...args) =>
|
|
||||||
requestDeleteMangaMetadata(
|
|
||||||
{ id: (metadataHolder as MangaIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
|
||||||
...args,
|
|
||||||
);
|
|
||||||
case 'chapter':
|
|
||||||
return (...args) =>
|
|
||||||
requestDeleteChapterMetadata(
|
|
||||||
{ id: (metadataHolder as ChapterIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
|
||||||
...args,
|
|
||||||
);
|
|
||||||
case 'category':
|
|
||||||
return (...args) =>
|
|
||||||
requestDeleteCategoryMetadata(
|
|
||||||
{ id: (metadataHolder as CategoryIdInfo).id, meta: convertToGqlMeta(metadataHolder.meta) },
|
|
||||||
...args,
|
|
||||||
);
|
|
||||||
case 'source':
|
|
||||||
return (...args) =>
|
|
||||||
requestDeleteSourceMetadata(
|
|
||||||
{
|
|
||||||
id: (metadataHolder as SourceIdInfo).id,
|
|
||||||
meta: convertToGqlMeta(metadataHolder.meta),
|
|
||||||
},
|
|
||||||
...args,
|
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unexpected "type" (${type})`);
|
throw new Error(`Unexpected "type" (${type})`);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import { useEffect, useMemo } from 'react';
|
|||||||
// eslint-disable-next-line import/no-extraneous-dependencies,no-restricted-imports
|
// eslint-disable-next-line import/no-extraneous-dependencies,no-restricted-imports
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import {
|
import {
|
||||||
requestUpdateMangaMetadata,
|
requestMangaMetadataUpdate,
|
||||||
requestUpdateServerMetadata,
|
requestServerMetadataUpdate,
|
||||||
} from '@/features/metadata/services/MetadataUpdater.ts';
|
} from '@/features/metadata/services/MetadataUpdater.ts';
|
||||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { IReaderSettings, IReaderSettingsWithDefaultFlag, ReadingMode } from '@/features/reader/Reader.types.ts';
|
import { IReaderSettings, IReaderSettingsWithDefaultFlag, ReadingMode } from '@/features/reader/Reader.types.ts';
|
||||||
@@ -227,17 +227,16 @@ export const updateReaderSettings = async <Setting extends keyof IReaderSettings
|
|||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const isGlobalSetting = isGlobal || GLOBAL_READER_SETTING_KEYS.includes(setting);
|
const isGlobalSetting = isGlobal || GLOBAL_READER_SETTING_KEYS.includes(setting);
|
||||||
if (isGlobalSetting) {
|
if (isGlobalSetting) {
|
||||||
return requestUpdateServerMetadata(
|
return requestServerMetadataUpdate({
|
||||||
[[setting, convertSettingsToMetadata({ [setting]: value })[setting]]],
|
update: [[setting, convertSettingsToMetadata({ [setting]: value })[setting]]],
|
||||||
profile !== undefined ? [profile?.toString()] : undefined,
|
keyPrefixes: profile !== undefined ? [profile?.toString()] : undefined,
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestUpdateMangaMetadata(
|
return requestMangaMetadataUpdate(manga, {
|
||||||
manga,
|
update: [[setting, convertSettingsToMetadata({ [setting]: value })[setting]]],
|
||||||
[[setting, convertSettingsToMetadata({ [setting]: value })[setting]]],
|
keyPrefixes: profile !== undefined ? [profile?.toString()] : undefined,
|
||||||
profile !== undefined ? [profile?.toString()] : undefined,
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export const createUpdateReaderSettings =
|
export const createUpdateReaderSettings =
|
||||||
<Settings extends keyof IReaderSettings>(
|
<Settings extends keyof IReaderSettings>(
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { requestUpdateServerMetadata } from '@/features/metadata/services/MetadataUpdater.ts';
|
import { requestServerMetadataUpdate } from '@/features/metadata/services/MetadataUpdater.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { SERVER_SETTINGS_METADATA_DEFAULT } from '@/features/settings/Settings.constants.ts';
|
import { SERVER_SETTINGS_METADATA_DEFAULT } from '@/features/settings/Settings.constants.ts';
|
||||||
import { MetadataServerSettingKeys, MetadataServerSettings } from '@/features/settings/Settings.types.ts';
|
import { MetadataServerSettingKeys, MetadataServerSettings } from '@/features/settings/Settings.types.ts';
|
||||||
@@ -64,7 +64,8 @@ export const updateMetadataServerSettings = async <
|
|||||||
>(
|
>(
|
||||||
setting: Setting,
|
setting: Setting,
|
||||||
value: MetadataServerSettings[Setting],
|
value: MetadataServerSettings[Setting],
|
||||||
): Promise<void> => requestUpdateServerMetadata([[setting, convertSettingsToMetadata({ [setting]: value })[setting]]]);
|
): Promise<void> =>
|
||||||
|
requestServerMetadataUpdate({ update: [[setting, convertSettingsToMetadata({ [setting]: value })[setting]]] });
|
||||||
|
|
||||||
export const createUpdateMetadataServerSettings =
|
export const createUpdateMetadataServerSettings =
|
||||||
<Settings extends MetadataServerSettingKeys>(
|
<Settings extends MetadataServerSettingKeys>(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { requestUpdateSourceMetadata } from '@/features/metadata/services/MetadataUpdater.ts';
|
import { requestSourceMetadataUpdate } from '@/features/metadata/services/MetadataUpdater.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { ISourceMetadata, SourceIdInfo, SourceMetadataKeys } from '@/features/source/Source.types.ts';
|
import { ISourceMetadata, SourceIdInfo, SourceMetadataKeys } from '@/features/source/Source.types.ts';
|
||||||
import { convertFromGqlMeta } from '@/features/metadata/services/MetadataConverter.ts';
|
import { convertFromGqlMeta } from '@/features/metadata/services/MetadataConverter.ts';
|
||||||
@@ -51,9 +51,9 @@ export const updateSourceMetadata = async <
|
|||||||
metadataKey: MetadataKey,
|
metadataKey: MetadataKey,
|
||||||
value: ISourceMetadata[MetadataKey],
|
value: ISourceMetadata[MetadataKey],
|
||||||
): Promise<void> =>
|
): Promise<void> =>
|
||||||
requestUpdateSourceMetadata(source, [
|
requestSourceMetadataUpdate(source, {
|
||||||
[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]],
|
update: [[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]]],
|
||||||
]);
|
});
|
||||||
|
|
||||||
export const createUpdateSourceMetadata =
|
export const createUpdateSourceMetadata =
|
||||||
<Settings extends SourceMetadataKeys>(
|
<Settings extends SourceMetadataKeys>(
|
||||||
|
|||||||
@@ -104,3 +104,32 @@ export const UPDATE_CATEGORY_ORDER = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_CATEGORY_METADATA = gql`
|
||||||
|
${CATEGORY_META_FIELDS}
|
||||||
|
|
||||||
|
mutation UPDATE_CATEGORY_METADATA(
|
||||||
|
$updateInput: SetCategoryMetasInput!
|
||||||
|
$hasUpdates: Boolean!
|
||||||
|
$deleteInput: DeleteCategoryMetasInput!
|
||||||
|
$hasDeletions: Boolean!
|
||||||
|
$migrateInput: SetCategoryMetasInput!
|
||||||
|
$isMigration: Boolean!
|
||||||
|
) {
|
||||||
|
updatedMeta: setCategoryMetas(input: $updateInput) @include(if: $hasUpdates) {
|
||||||
|
metas {
|
||||||
|
...CATEGORY_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletedMeta: deleteCategoryMetas(input: $deleteInput) @include(if: $hasDeletions) {
|
||||||
|
metas {
|
||||||
|
...CATEGORY_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
migrationMeta: setCategoryMetas(input: $migrateInput) @include(if: $isMigration) {
|
||||||
|
metas {
|
||||||
|
...CATEGORY_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -181,3 +181,32 @@ export const UPDATE_CHAPTERS = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_CHAPTER_METADATA = gql`
|
||||||
|
${CHAPTER_META_FIELDS}
|
||||||
|
|
||||||
|
mutation UPDATE_CHAPTER_METADATA(
|
||||||
|
$updateInput: SetChapterMetasInput!
|
||||||
|
$hasUpdates: Boolean!
|
||||||
|
$deleteInput: DeleteChapterMetasInput!
|
||||||
|
$hasDeletions: Boolean!
|
||||||
|
$migrateInput: SetChapterMetasInput!
|
||||||
|
$isMigration: Boolean!
|
||||||
|
) {
|
||||||
|
updatedMeta: setChapterMetas(input: $updateInput) @include(if: $hasUpdates) {
|
||||||
|
metas {
|
||||||
|
...CHAPTER_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletedMeta: deleteChapterMetas(input: $deleteInput) @include(if: $hasDeletions) {
|
||||||
|
metas {
|
||||||
|
...CHAPTER_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
migrationMeta: setChapterMetas(input: $migrateInput) @include(if: $isMigration) {
|
||||||
|
metas {
|
||||||
|
...CHAPTER_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -3552,6 +3552,18 @@ export type UpdateCategoryOrderMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type UpdateCategoryOrderMutation = { __typename?: 'Mutation', updateCategoryOrder?: { __typename?: 'UpdateCategoryOrderPayload', categories: Array<{ __typename?: 'CategoryType', id: number, order: number }> } | null };
|
export type UpdateCategoryOrderMutation = { __typename?: 'Mutation', updateCategoryOrder?: { __typename?: 'UpdateCategoryOrderPayload', categories: Array<{ __typename?: 'CategoryType', id: number, order: number }> } | null };
|
||||||
|
|
||||||
|
export type UpdateCategoryMetadataMutationVariables = Exact<{
|
||||||
|
updateInput: SetCategoryMetasInput;
|
||||||
|
hasUpdates: Scalars['Boolean']['input'];
|
||||||
|
deleteInput: DeleteCategoryMetasInput;
|
||||||
|
hasDeletions: Scalars['Boolean']['input'];
|
||||||
|
migrateInput: SetCategoryMetasInput;
|
||||||
|
isMigration: Scalars['Boolean']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type UpdateCategoryMetadataMutation = { __typename?: 'Mutation', updatedMeta?: { __typename?: 'SetCategoryMetasPayload', metas: Array<{ __typename?: 'CategoryMetaType', categoryId: number, key: string, value: string }> } | null, deletedMeta?: { __typename?: 'DeleteCategoryMetasPayload', metas: Array<{ __typename?: 'CategoryMetaType', categoryId: number, key: string, value: string }> } | null, migrationMeta?: { __typename?: 'SetCategoryMetasPayload', metas: Array<{ __typename?: 'CategoryMetaType', categoryId: number, key: string, value: string }> } | null };
|
||||||
|
|
||||||
export type GetCategoriesBaseQueryVariables = Exact<{
|
export type GetCategoriesBaseQueryVariables = Exact<{
|
||||||
after?: InputMaybe<Scalars['Cursor']['input']>;
|
after?: InputMaybe<Scalars['Cursor']['input']>;
|
||||||
before?: InputMaybe<Scalars['Cursor']['input']>;
|
before?: InputMaybe<Scalars['Cursor']['input']>;
|
||||||
@@ -3671,6 +3683,18 @@ export type UpdateChaptersMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type UpdateChaptersMutation = { __typename?: 'Mutation', updateChapters?: { __typename?: 'UpdateChaptersPayload', chapters: Array<{ __typename?: 'ChapterType', id: number, isBookmarked?: boolean, isRead?: boolean, lastReadAt?: string, lastPageRead?: number, manga?: { __typename?: 'MangaType', id: number, unreadCount: number, bookmarkCount: number, lastReadChapter?: { __typename?: 'ChapterType', id: number } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number } | null, firstUnreadChapter?: { __typename?: 'ChapterType', id: number } | null } }> } | null, deleteDownloadedChapters?: { __typename?: 'DeleteDownloadedChaptersPayload', chapters: Array<{ __typename?: 'ChapterType', id: number, isDownloaded: boolean, manga: { __typename?: 'MangaType', id: number, downloadCount: number } }> } | null, trackProgress?: { __typename?: 'TrackProgressPayload', trackRecords: Array<{ __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, private: boolean }> } | null };
|
export type UpdateChaptersMutation = { __typename?: 'Mutation', updateChapters?: { __typename?: 'UpdateChaptersPayload', chapters: Array<{ __typename?: 'ChapterType', id: number, isBookmarked?: boolean, isRead?: boolean, lastReadAt?: string, lastPageRead?: number, manga?: { __typename?: 'MangaType', id: number, unreadCount: number, bookmarkCount: number, lastReadChapter?: { __typename?: 'ChapterType', id: number } | null, latestReadChapter?: { __typename?: 'ChapterType', id: number } | null, firstUnreadChapter?: { __typename?: 'ChapterType', id: number } | null } }> } | null, deleteDownloadedChapters?: { __typename?: 'DeleteDownloadedChaptersPayload', chapters: Array<{ __typename?: 'ChapterType', id: number, isDownloaded: boolean, manga: { __typename?: 'MangaType', id: number, downloadCount: number } }> } | null, trackProgress?: { __typename?: 'TrackProgressPayload', trackRecords: Array<{ __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, private: boolean }> } | null };
|
||||||
|
|
||||||
|
export type UpdateChapterMetadataMutationVariables = Exact<{
|
||||||
|
updateInput: SetChapterMetasInput;
|
||||||
|
hasUpdates: Scalars['Boolean']['input'];
|
||||||
|
deleteInput: DeleteChapterMetasInput;
|
||||||
|
hasDeletions: Scalars['Boolean']['input'];
|
||||||
|
migrateInput: SetChapterMetasInput;
|
||||||
|
isMigration: Scalars['Boolean']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type UpdateChapterMetadataMutation = { __typename?: 'Mutation', updatedMeta?: { __typename?: 'SetChapterMetasPayload', metas: Array<{ __typename?: 'ChapterMetaType', chapterId: number, key: string, value: string }> } | null, deletedMeta?: { __typename?: 'DeleteChapterMetasPayload', metas: Array<{ __typename?: 'ChapterMetaType', chapterId: number, key: string, value: string }> } | null, migrationMeta?: { __typename?: 'SetChapterMetasPayload', metas: Array<{ __typename?: 'ChapterMetaType', chapterId: number, key: string, value: string }> } | null };
|
||||||
|
|
||||||
export type GetChaptersReaderQueryVariables = Exact<{
|
export type GetChaptersReaderQueryVariables = Exact<{
|
||||||
after?: InputMaybe<Scalars['Cursor']['input']>;
|
after?: InputMaybe<Scalars['Cursor']['input']>;
|
||||||
before?: InputMaybe<Scalars['Cursor']['input']>;
|
before?: InputMaybe<Scalars['Cursor']['input']>;
|
||||||
@@ -3987,6 +4011,18 @@ export type UpdateMangasCategoriesMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type UpdateMangasCategoriesMutation = { __typename?: 'Mutation', updateMangasCategories?: { __typename?: 'UpdateMangasCategoriesPayload', mangas: Array<{ __typename?: 'MangaType', id: number, categories: { __typename?: 'CategoryNodeList', totalCount: number, nodes: Array<{ __typename?: 'CategoryType', id: number, mangas: { __typename?: 'MangaNodeList', totalCount: number } }> } }> } | null };
|
export type UpdateMangasCategoriesMutation = { __typename?: 'Mutation', updateMangasCategories?: { __typename?: 'UpdateMangasCategoriesPayload', mangas: Array<{ __typename?: 'MangaType', id: number, categories: { __typename?: 'CategoryNodeList', totalCount: number, nodes: Array<{ __typename?: 'CategoryType', id: number, mangas: { __typename?: 'MangaNodeList', totalCount: number } }> } }> } | null };
|
||||||
|
|
||||||
|
export type UpdateMangaMetadataMutationVariables = Exact<{
|
||||||
|
updateInput: SetMangaMetasInput;
|
||||||
|
hasUpdates: Scalars['Boolean']['input'];
|
||||||
|
deleteInput: DeleteMangaMetasInput;
|
||||||
|
hasDeletions: Scalars['Boolean']['input'];
|
||||||
|
migrateInput: SetMangaMetasInput;
|
||||||
|
isMigration: Scalars['Boolean']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type UpdateMangaMetadataMutation = { __typename?: 'Mutation', updatedMeta?: { __typename?: 'SetMangaMetasPayload', metas: Array<{ __typename?: 'MangaMetaType', mangaId: number, key: string, value: string }> } | null, deletedMeta?: { __typename?: 'DeleteMangaMetasPayload', metas: Array<{ __typename?: 'MangaMetaType', mangaId: number, key: string, value: string }> } | null, migrationMeta?: { __typename?: 'SetMangaMetasPayload', metas: Array<{ __typename?: 'MangaMetaType', mangaId: number, key: string, value: string }> } | null };
|
||||||
|
|
||||||
export type GetMangaScreenQueryVariables = Exact<{
|
export type GetMangaScreenQueryVariables = Exact<{
|
||||||
id: Scalars['Int']['input'];
|
id: Scalars['Int']['input'];
|
||||||
}>;
|
}>;
|
||||||
@@ -4093,6 +4129,18 @@ export type SetGlobalMetadataMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type SetGlobalMetadataMutation = { __typename?: 'Mutation', setGlobalMetas?: { __typename?: 'SetGlobalMetasPayload', metas: Array<{ __typename?: 'GlobalMetaType', key: string, value: string }> } | null };
|
export type SetGlobalMetadataMutation = { __typename?: 'Mutation', setGlobalMetas?: { __typename?: 'SetGlobalMetasPayload', metas: Array<{ __typename?: 'GlobalMetaType', key: string, value: string }> } | null };
|
||||||
|
|
||||||
|
export type UpdateGlobalMetadataMutationVariables = Exact<{
|
||||||
|
updateInput: SetGlobalMetasInput;
|
||||||
|
hasUpdates: Scalars['Boolean']['input'];
|
||||||
|
deleteInput: DeleteGlobalMetasInput;
|
||||||
|
hasDeletions: Scalars['Boolean']['input'];
|
||||||
|
migrateInput: SetGlobalMetasInput;
|
||||||
|
isMigration: Scalars['Boolean']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type UpdateGlobalMetadataMutation = { __typename?: 'Mutation', updatedMeta?: { __typename?: 'SetGlobalMetasPayload', metas: Array<{ __typename?: 'GlobalMetaType', key: string, value: string }> } | null, deletedMeta?: { __typename?: 'DeleteGlobalMetasPayload', metas: Array<{ __typename?: 'GlobalMetaType', key: string, value: string }> } | null, migrationMeta?: { __typename?: 'SetGlobalMetasPayload', metas: Array<{ __typename?: 'GlobalMetaType', key: string, value: string }> } | null };
|
||||||
|
|
||||||
export type GetGlobalMetadataQueryVariables = Exact<{
|
export type GetGlobalMetadataQueryVariables = Exact<{
|
||||||
key: Scalars['String']['input'];
|
key: Scalars['String']['input'];
|
||||||
}>;
|
}>;
|
||||||
@@ -4220,6 +4268,18 @@ export type DeleteSourceMetadataMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type DeleteSourceMetadataMutation = { __typename?: 'Mutation', deleteSourceMetas?: { __typename?: 'DeleteSourceMetasPayload', metas: Array<{ __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }> } | null };
|
export type DeleteSourceMetadataMutation = { __typename?: 'Mutation', deleteSourceMetas?: { __typename?: 'DeleteSourceMetasPayload', metas: Array<{ __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }> } | null };
|
||||||
|
|
||||||
|
export type UpdateSourceMetadataMutationVariables = Exact<{
|
||||||
|
updateInput: SetSourceMetasInput;
|
||||||
|
hasUpdates: Scalars['Boolean']['input'];
|
||||||
|
deleteInput: DeleteSourceMetasInput;
|
||||||
|
hasDeletions: Scalars['Boolean']['input'];
|
||||||
|
migrateInput: SetSourceMetasInput;
|
||||||
|
isMigration: Scalars['Boolean']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type UpdateSourceMetadataMutation = { __typename?: 'Mutation', updatedMeta?: { __typename?: 'SetSourceMetasPayload', metas: Array<{ __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }> } | null, deletedMeta?: { __typename?: 'DeleteSourceMetasPayload', metas: Array<{ __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }> } | null, migrationMeta?: { __typename?: 'SetSourceMetasPayload', metas: Array<{ __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }> } | null };
|
||||||
|
|
||||||
export type GetSourceBrowseQueryVariables = Exact<{
|
export type GetSourceBrowseQueryVariables = Exact<{
|
||||||
id: Scalars['LongString']['input'];
|
id: Scalars['LongString']['input'];
|
||||||
}>;
|
}>;
|
||||||
|
|||||||
@@ -194,3 +194,32 @@ export const UPDATE_MANGAS_CATEGORIES = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_MANGA_METADATA = gql`
|
||||||
|
${MANGA_META_FIELDS}
|
||||||
|
|
||||||
|
mutation UPDATE_MANGA_METADATA(
|
||||||
|
$updateInput: SetMangaMetasInput!
|
||||||
|
$hasUpdates: Boolean!
|
||||||
|
$deleteInput: DeleteMangaMetasInput!
|
||||||
|
$hasDeletions: Boolean!
|
||||||
|
$migrateInput: SetMangaMetasInput!
|
||||||
|
$isMigration: Boolean!
|
||||||
|
) {
|
||||||
|
updatedMeta: setMangaMetas(input: $updateInput) @include(if: $hasUpdates) {
|
||||||
|
metas {
|
||||||
|
...MANGA_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletedMeta: deleteMangaMetas(input: $deleteInput) @include(if: $hasDeletions) {
|
||||||
|
metas {
|
||||||
|
...MANGA_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
migrationMeta: setMangaMetas(input: $migrateInput) @include(if: $isMigration) {
|
||||||
|
metas {
|
||||||
|
...MANGA_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -30,3 +30,31 @@ export const SET_GLOBAL_METADATA = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_GLOBAL_METADATA = gql`
|
||||||
|
${GLOBAL_METADATA}
|
||||||
|
mutation UPDATE_GLOBAL_METADATA(
|
||||||
|
$updateInput: SetGlobalMetasInput!
|
||||||
|
$hasUpdates: Boolean!
|
||||||
|
$deleteInput: DeleteGlobalMetasInput!
|
||||||
|
$hasDeletions: Boolean!
|
||||||
|
$migrateInput: SetGlobalMetasInput!
|
||||||
|
$isMigration: Boolean!
|
||||||
|
) {
|
||||||
|
updatedMeta: setGlobalMetas(input: $updateInput) @include(if: $hasUpdates) {
|
||||||
|
metas {
|
||||||
|
...GLOBAL_METADATA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletedMeta: deleteGlobalMetas(input: $deleteInput) @include(if: $hasDeletions) {
|
||||||
|
metas {
|
||||||
|
...GLOBAL_METADATA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
migrationMeta: setGlobalMetas(input: $migrateInput) @include(if: $isMigration) {
|
||||||
|
metas {
|
||||||
|
...GLOBAL_METADATA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -58,3 +58,32 @@ export const DELETE_SOURCE_METADATA = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_SOURCE_METADATA = gql`
|
||||||
|
${SOURCE_META_FIELDS}
|
||||||
|
|
||||||
|
mutation UPDATE_SOURCE_METADATA(
|
||||||
|
$updateInput: SetSourceMetasInput!
|
||||||
|
$hasUpdates: Boolean!
|
||||||
|
$deleteInput: DeleteSourceMetasInput!
|
||||||
|
$hasDeletions: Boolean!
|
||||||
|
$migrateInput: SetSourceMetasInput!
|
||||||
|
$isMigration: Boolean!
|
||||||
|
) {
|
||||||
|
updatedMeta: setSourceMetas(input: $updateInput) @include(if: $hasUpdates) {
|
||||||
|
metas {
|
||||||
|
...SOURCE_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletedMeta: deleteSourceMetas(input: $deleteInput) @include(if: $hasDeletions) {
|
||||||
|
metas {
|
||||||
|
...SOURCE_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
migrationMeta: setSourceMetas(input: $migrateInput) @include(if: $isMigration) {
|
||||||
|
metas {
|
||||||
|
...SOURCE_META_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -238,9 +238,31 @@ import {
|
|||||||
KoSyncLogoutMutationVariables,
|
KoSyncLogoutMutationVariables,
|
||||||
GetKoSyncStatusQuery,
|
GetKoSyncStatusQuery,
|
||||||
GetKoSyncStatusQueryVariables,
|
GetKoSyncStatusQueryVariables,
|
||||||
|
UpdateGlobalMetadataMutation,
|
||||||
|
UpdateGlobalMetadataMutationVariables,
|
||||||
|
UpdateMangaMetadataMutation,
|
||||||
|
UpdateMangaMetadataMutationVariables,
|
||||||
|
UpdateChapterMetadataMutation,
|
||||||
|
UpdateChapterMetadataMutationVariables,
|
||||||
|
UpdateCategoryMetadataMutation,
|
||||||
|
UpdateCategoryMetadataMutationVariables,
|
||||||
|
UpdateSourceMetadataMutation,
|
||||||
|
UpdateSourceMetadataMutationVariables,
|
||||||
|
SetCategoryMetasItemInput,
|
||||||
|
DeleteCategoryMetasItemInput,
|
||||||
|
SetSourceMetasItemInput,
|
||||||
|
DeleteSourceMetasItemInput,
|
||||||
|
SetMangaMetasItemInput,
|
||||||
|
DeleteMangaMetasItemInput,
|
||||||
|
SetChapterMetasItemInput,
|
||||||
|
DeleteChapterMetasItemInput,
|
||||||
} from '@/lib/graphql/generated/graphql.ts';
|
} from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { GET_GLOBAL_METADATAS } from '@/lib/graphql/metadata/GlobalMetadataQuery.ts';
|
import { GET_GLOBAL_METADATAS } from '@/lib/graphql/metadata/GlobalMetadataQuery.ts';
|
||||||
import { DELETE_GLOBAL_METADATA, SET_GLOBAL_METADATA } from '@/lib/graphql/metadata/GlobalMetadataMutation.ts';
|
import {
|
||||||
|
DELETE_GLOBAL_METADATA,
|
||||||
|
SET_GLOBAL_METADATA,
|
||||||
|
UPDATE_GLOBAL_METADATA,
|
||||||
|
} from '@/lib/graphql/metadata/GlobalMetadataMutation.ts';
|
||||||
import {
|
import {
|
||||||
CHECK_FOR_SERVER_UPDATES,
|
CHECK_FOR_SERVER_UPDATES,
|
||||||
CHECK_FOR_WEBUI_UPDATE,
|
CHECK_FOR_WEBUI_UPDATE,
|
||||||
@@ -262,6 +284,7 @@ import {
|
|||||||
SET_MANGA_METADATA,
|
SET_MANGA_METADATA,
|
||||||
UPDATE_MANGA,
|
UPDATE_MANGA,
|
||||||
UPDATE_MANGA_CATEGORIES,
|
UPDATE_MANGA_CATEGORIES,
|
||||||
|
UPDATE_MANGA_METADATA,
|
||||||
UPDATE_MANGAS,
|
UPDATE_MANGAS,
|
||||||
UPDATE_MANGAS_CATEGORIES,
|
UPDATE_MANGAS_CATEGORIES,
|
||||||
} from '@/lib/graphql/manga/MangaMutation.ts';
|
} from '@/lib/graphql/manga/MangaMutation.ts';
|
||||||
@@ -281,6 +304,7 @@ import {
|
|||||||
DELETE_SOURCE_METADATA,
|
DELETE_SOURCE_METADATA,
|
||||||
GET_SOURCE_MANGAS_FETCH,
|
GET_SOURCE_MANGAS_FETCH,
|
||||||
SET_SOURCE_METADATA,
|
SET_SOURCE_METADATA,
|
||||||
|
UPDATE_SOURCE_METADATA,
|
||||||
UPDATE_SOURCE_PREFERENCES,
|
UPDATE_SOURCE_PREFERENCES,
|
||||||
} from '@/lib/graphql/source/SourceMutation.ts';
|
} from '@/lib/graphql/source/SourceMutation.ts';
|
||||||
import {
|
import {
|
||||||
@@ -307,6 +331,7 @@ import {
|
|||||||
GET_MANGA_CHAPTERS_FETCH,
|
GET_MANGA_CHAPTERS_FETCH,
|
||||||
SET_CHAPTER_METADATA,
|
SET_CHAPTER_METADATA,
|
||||||
UPDATE_CHAPTER,
|
UPDATE_CHAPTER,
|
||||||
|
UPDATE_CHAPTER_METADATA,
|
||||||
UPDATE_CHAPTERS,
|
UPDATE_CHAPTERS,
|
||||||
} from '@/lib/graphql/chapter/ChapterMutation.ts';
|
} from '@/lib/graphql/chapter/ChapterMutation.ts';
|
||||||
import {
|
import {
|
||||||
@@ -315,6 +340,7 @@ import {
|
|||||||
DELETE_CATEGORY_METADATA,
|
DELETE_CATEGORY_METADATA,
|
||||||
SET_CATEGORY_METADATA,
|
SET_CATEGORY_METADATA,
|
||||||
UPDATE_CATEGORY,
|
UPDATE_CATEGORY,
|
||||||
|
UPDATE_CATEGORY_METADATA,
|
||||||
UPDATE_CATEGORY_ORDER,
|
UPDATE_CATEGORY_ORDER,
|
||||||
} from '@/lib/graphql/category/CategoryMutation.ts';
|
} from '@/lib/graphql/category/CategoryMutation.ts';
|
||||||
import { STOP_UPDATER, UPDATE_LIBRARY } from '@/lib/graphql/updater/UpdaterMutation.ts';
|
import { STOP_UPDATER, UPDATE_LIBRARY } from '@/lib/graphql/updater/UpdaterMutation.ts';
|
||||||
@@ -353,6 +379,8 @@ import { SOURCE_META_FIELDS } from '@/lib/graphql/source/SourceFragments.ts';
|
|||||||
import { CHAPTER_META_FIELDS } from '@/lib/graphql/chapter/ChapterFragments.ts';
|
import { CHAPTER_META_FIELDS } from '@/lib/graphql/chapter/ChapterFragments.ts';
|
||||||
import { MetadataMigrationSettings } from '@/features/migration/Migration.types.ts';
|
import { MetadataMigrationSettings } from '@/features/migration/Migration.types.ts';
|
||||||
import { MangaIdInfo } from '@/features/manga/Manga.types.ts';
|
import { MangaIdInfo } from '@/features/manga/Manga.types.ts';
|
||||||
|
import { ChapterIdInfo } from '@/features/chapter/Chapter.types.ts';
|
||||||
|
import { CategoryIdInfo } from '@/features/category/Category.types.ts';
|
||||||
import { updateMetadataList } from '@/features/metadata/services/MetadataApolloCacheHandler.ts';
|
import { updateMetadataList } from '@/features/metadata/services/MetadataApolloCacheHandler.ts';
|
||||||
import { USER_LOGIN, USER_REFRESH } from '@/lib/graphql/user/UserMutation.ts';
|
import { USER_LOGIN, USER_REFRESH } from '@/lib/graphql/user/UserMutation.ts';
|
||||||
import { AuthManager } from '@/features/authentication/AuthManager.ts';
|
import { AuthManager } from '@/features/authentication/AuthManager.ts';
|
||||||
@@ -361,6 +389,7 @@ import { KO_SYNC_LOGIN, KO_SYNC_LOGOUT } from '@/lib/graphql/koreader/KoreaderSy
|
|||||||
import { GET_KO_SYNC_STATUS } from '@/lib/graphql/koreader/KoreaderSyncQuery.ts';
|
import { GET_KO_SYNC_STATUS } from '@/lib/graphql/koreader/KoreaderSyncQuery.ts';
|
||||||
import { ImageCache } from '@/lib/service-worker/ImageCache.ts';
|
import { ImageCache } from '@/lib/service-worker/ImageCache.ts';
|
||||||
import { Sources } from '@/features/source/services/Sources.ts';
|
import { Sources } from '@/features/source/services/Sources.ts';
|
||||||
|
import { SourceIdInfo } from '@/features/source/Source.types.ts';
|
||||||
|
|
||||||
enum GQLMethod {
|
enum GQLMethod {
|
||||||
QUERY = 'QUERY',
|
QUERY = 'QUERY',
|
||||||
@@ -1386,6 +1415,103 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateGlobalMeta(
|
||||||
|
{
|
||||||
|
updateInput = { metas: [] },
|
||||||
|
deleteInput = { keys: [] },
|
||||||
|
migrateInput = { metas: [] },
|
||||||
|
}: {
|
||||||
|
updateInput?: SetGlobalMetasInput;
|
||||||
|
deleteInput?: DeleteGlobalMetasInput;
|
||||||
|
migrateInput?: SetGlobalMetasInput;
|
||||||
|
},
|
||||||
|
options?: MutationOptions<UpdateGlobalMetadataMutation, UpdateGlobalMetadataMutationVariables>,
|
||||||
|
): AbortableApolloMutationResponse<UpdateGlobalMetadataMutation> {
|
||||||
|
return this.doRequest<UpdateGlobalMetadataMutation, UpdateGlobalMetadataMutationVariables>(
|
||||||
|
GQLMethod.MUTATION,
|
||||||
|
UPDATE_GLOBAL_METADATA,
|
||||||
|
{
|
||||||
|
updateInput,
|
||||||
|
hasUpdates: !!updateInput.metas.length,
|
||||||
|
deleteInput,
|
||||||
|
hasDeletions: !!deleteInput.keys?.length || !!deleteInput.prefixes?.length,
|
||||||
|
migrateInput,
|
||||||
|
isMigration: !!migrateInput.metas.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
updatedMeta: {
|
||||||
|
__typename: 'SetGlobalMetasPayload',
|
||||||
|
metas: (updateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'GlobalMetaType',
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
deletedMeta: {
|
||||||
|
__typename: 'DeleteGlobalMetasPayload',
|
||||||
|
metas: (deleteInput?.keys ?? []).map((key) => ({
|
||||||
|
__typename: 'GlobalMetaType' as const,
|
||||||
|
key,
|
||||||
|
value: '',
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
migrationMeta: {
|
||||||
|
__typename: 'SetGlobalMetasPayload',
|
||||||
|
metas: (migrateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'GlobalMetaType',
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update(cache, { data }) {
|
||||||
|
deleteInput?.keys?.forEach((key) => {
|
||||||
|
cache.evict({ id: cache.identify({ __typename: 'GlobalMetaType', key }) });
|
||||||
|
});
|
||||||
|
|
||||||
|
cache.modify({
|
||||||
|
fields: {
|
||||||
|
metas(existingMetas, { readField }) {
|
||||||
|
if (!existingMetas) {
|
||||||
|
return existingMetas;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data?.updatedMeta && !data?.migrationMeta) {
|
||||||
|
return existingMetas;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedMeta = [
|
||||||
|
...(data?.updatedMeta?.metas ?? []),
|
||||||
|
...(data?.migrationMeta?.metas ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
const newMetas = updatedMeta.filter((meta) =>
|
||||||
|
existingMetas.nodes.every(
|
||||||
|
(existingMeta: Reference) => readField('key', existingMeta) !== meta.key,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const newMetaRefs = newMetas.map((meta) =>
|
||||||
|
cache.writeFragment({
|
||||||
|
data: meta,
|
||||||
|
fragment: GLOBAL_METADATA,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...existingMetas,
|
||||||
|
nodes: [...existingMetas.nodes, ...newMetaRefs],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public useGetAbout(
|
public useGetAbout(
|
||||||
options?: QueryHookOptions<GetAboutQuery, GetAboutQueryVariables>,
|
options?: QueryHookOptions<GetAboutQuery, GetAboutQueryVariables>,
|
||||||
): AbortableApolloUseQueryResponse<GetAboutQuery, GetAboutQueryVariables> {
|
): AbortableApolloUseQueryResponse<GetAboutQuery, GetAboutQueryVariables> {
|
||||||
@@ -1810,6 +1936,104 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateSourceMeta(
|
||||||
|
sourceIds: SourceIdInfo['id'][],
|
||||||
|
{
|
||||||
|
updateInput = { metas: [] },
|
||||||
|
deleteInput = { keys: [] },
|
||||||
|
migrateInput = { metas: [] },
|
||||||
|
}: {
|
||||||
|
updateInput?: Omit<SetSourceMetasItemInput, 'sourceIds'>;
|
||||||
|
deleteInput?: Omit<DeleteSourceMetasItemInput, 'sourceIds'>;
|
||||||
|
migrateInput?: Omit<SetSourceMetasItemInput, 'sourceIds'>;
|
||||||
|
},
|
||||||
|
options?: MutationOptions<UpdateSourceMetadataMutation, UpdateSourceMetadataMutationVariables>,
|
||||||
|
): AbortableApolloMutationResponse<UpdateSourceMetadataMutation> {
|
||||||
|
return this.doRequest<UpdateSourceMetadataMutation, UpdateSourceMetadataMutationVariables>(
|
||||||
|
GQLMethod.MUTATION,
|
||||||
|
UPDATE_SOURCE_METADATA,
|
||||||
|
{
|
||||||
|
updateInput: { items: [{ ...updateInput, sourceIds }] },
|
||||||
|
hasUpdates: !!updateInput.metas.length,
|
||||||
|
deleteInput: { items: [{ ...deleteInput, sourceIds }] },
|
||||||
|
hasDeletions: !!deleteInput.keys?.length || !!deleteInput.prefixes?.length,
|
||||||
|
migrateInput: { items: [{ ...migrateInput, sourceIds }] },
|
||||||
|
isMigration: !!migrateInput.metas.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
updatedMeta: {
|
||||||
|
__typename: 'SetSourceMetasPayload',
|
||||||
|
metas: sourceIds.flatMap((sourceId) =>
|
||||||
|
(updateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'SourceMetaType' as const,
|
||||||
|
sourceId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
deletedMeta: {
|
||||||
|
__typename: 'DeleteSourceMetasPayload',
|
||||||
|
metas: sourceIds.flatMap((sourceId) =>
|
||||||
|
(deleteInput?.keys ?? []).map((key) => ({
|
||||||
|
__typename: 'SourceMetaType' as const,
|
||||||
|
sourceId,
|
||||||
|
key,
|
||||||
|
value: '',
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
migrationMeta: {
|
||||||
|
__typename: 'SetSourceMetasPayload',
|
||||||
|
metas: sourceIds.flatMap((sourceId) =>
|
||||||
|
(migrateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'SourceMetaType' as const,
|
||||||
|
sourceId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update(cache, { data }) {
|
||||||
|
sourceIds?.forEach((sourceId) => {
|
||||||
|
deleteInput?.keys?.forEach((key) => {
|
||||||
|
cache.evict({ id: cache.identify({ __typename: 'SourceMetaType', sourceId, key }) });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data?.updatedMeta && !data?.migrationMeta) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceIds.forEach((sourceId) => {
|
||||||
|
cache.modify({
|
||||||
|
id: cache.identify({ __typename: 'SourceType', id: sourceId }),
|
||||||
|
fields: {
|
||||||
|
meta(existingMetas, { readField }) {
|
||||||
|
const updatedMeta = [
|
||||||
|
...(data?.updatedMeta?.metas ?? []),
|
||||||
|
...(data?.migrationMeta?.metas ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
return updateMetadataList(updatedMeta, existingMetas, readField, (meta) =>
|
||||||
|
cache.writeFragment({
|
||||||
|
data: meta,
|
||||||
|
fragment: SOURCE_META_FIELDS,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public useGetSourceMangas(
|
public useGetSourceMangas(
|
||||||
input: FetchSourceMangaInput,
|
input: FetchSourceMangaInput,
|
||||||
initialPages: number = 1,
|
initialPages: number = 1,
|
||||||
@@ -2355,6 +2579,104 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateMangaMeta(
|
||||||
|
mangaIds: MangaIdInfo['id'][],
|
||||||
|
{
|
||||||
|
updateInput = { metas: [] },
|
||||||
|
deleteInput = { keys: [] },
|
||||||
|
migrateInput = { metas: [] },
|
||||||
|
}: {
|
||||||
|
updateInput?: Omit<SetMangaMetasItemInput, 'mangaIds'>;
|
||||||
|
deleteInput?: Omit<DeleteMangaMetasItemInput, 'mangaIds'>;
|
||||||
|
migrateInput?: Omit<SetMangaMetasItemInput, 'mangaIds'>;
|
||||||
|
},
|
||||||
|
options?: MutationOptions<UpdateMangaMetadataMutation, UpdateMangaMetadataMutationVariables>,
|
||||||
|
): AbortableApolloMutationResponse<UpdateMangaMetadataMutation> {
|
||||||
|
return this.doRequest<UpdateMangaMetadataMutation, UpdateMangaMetadataMutationVariables>(
|
||||||
|
GQLMethod.MUTATION,
|
||||||
|
UPDATE_MANGA_METADATA,
|
||||||
|
{
|
||||||
|
updateInput: { items: [{ ...updateInput, mangaIds }] },
|
||||||
|
hasUpdates: !!updateInput.metas.length,
|
||||||
|
deleteInput: { items: [{ ...deleteInput, mangaIds }] },
|
||||||
|
hasDeletions: !!deleteInput.keys?.length || !!deleteInput.prefixes?.length,
|
||||||
|
migrateInput: { items: [{ ...migrateInput, mangaIds }] },
|
||||||
|
isMigration: !!migrateInput.metas.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
updatedMeta: {
|
||||||
|
__typename: 'SetMangaMetasPayload',
|
||||||
|
metas: mangaIds.flatMap((mangaId) =>
|
||||||
|
(updateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'MangaMetaType' as const,
|
||||||
|
mangaId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
deletedMeta: {
|
||||||
|
__typename: 'DeleteMangaMetasPayload',
|
||||||
|
metas: mangaIds.flatMap((mangaId) =>
|
||||||
|
(deleteInput?.keys ?? []).map((key) => ({
|
||||||
|
__typename: 'MangaMetaType' as const,
|
||||||
|
mangaId,
|
||||||
|
key,
|
||||||
|
value: '',
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
migrationMeta: {
|
||||||
|
__typename: 'SetMangaMetasPayload',
|
||||||
|
metas: mangaIds.flatMap((mangaId) =>
|
||||||
|
(migrateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'MangaMetaType' as const,
|
||||||
|
mangaId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update(cache, { data }) {
|
||||||
|
mangaIds.forEach((mangaId) => {
|
||||||
|
deleteInput?.keys?.forEach((key) => {
|
||||||
|
cache.evict({ id: cache.identify({ __typename: 'MangaMetaType', mangaId, key }) });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data?.updatedMeta && !data?.migrationMeta) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mangaIds.forEach((mangaId) => {
|
||||||
|
cache.modify({
|
||||||
|
id: cache.identify({ __typename: 'MangaType', id: mangaId }),
|
||||||
|
fields: {
|
||||||
|
meta(existingMetas, { readField }) {
|
||||||
|
const updatedMeta = [
|
||||||
|
...(data?.updatedMeta?.metas ?? []),
|
||||||
|
...(data?.migrationMeta?.metas ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
return updateMetadataList(updatedMeta, existingMetas, readField, (meta) =>
|
||||||
|
cache.writeFragment({
|
||||||
|
data: meta,
|
||||||
|
fragment: MANGA_META_FIELDS,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public useGetChapters<Data, Variables extends OperationVariables>(
|
public useGetChapters<Data, Variables extends OperationVariables>(
|
||||||
document: DocumentNode | TypedDocumentNode<Data, Variables>,
|
document: DocumentNode | TypedDocumentNode<Data, Variables>,
|
||||||
variables: Variables,
|
variables: Variables,
|
||||||
@@ -2606,6 +2928,104 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateChapterMeta(
|
||||||
|
chapterIds: ChapterIdInfo['id'][],
|
||||||
|
{
|
||||||
|
updateInput = { metas: [] },
|
||||||
|
deleteInput = { keys: [] },
|
||||||
|
migrateInput = { metas: [] },
|
||||||
|
}: {
|
||||||
|
updateInput?: Omit<SetChapterMetasItemInput, 'chapterIds'>;
|
||||||
|
deleteInput?: Omit<DeleteChapterMetasItemInput, 'chapterIds'>;
|
||||||
|
migrateInput?: Omit<SetChapterMetasItemInput, 'chapterIds'>;
|
||||||
|
},
|
||||||
|
options?: MutationOptions<UpdateChapterMetadataMutation, UpdateChapterMetadataMutationVariables>,
|
||||||
|
): AbortableApolloMutationResponse<UpdateChapterMetadataMutation> {
|
||||||
|
return this.doRequest<UpdateChapterMetadataMutation, UpdateChapterMetadataMutationVariables>(
|
||||||
|
GQLMethod.MUTATION,
|
||||||
|
UPDATE_CHAPTER_METADATA,
|
||||||
|
{
|
||||||
|
updateInput: { items: [{ ...updateInput, chapterIds }] },
|
||||||
|
hasUpdates: !!updateInput.metas.length,
|
||||||
|
deleteInput: { items: [{ ...deleteInput, chapterIds }] },
|
||||||
|
hasDeletions: !!deleteInput.keys?.length || !!deleteInput.prefixes?.length,
|
||||||
|
migrateInput: { items: [{ ...migrateInput, chapterIds }] },
|
||||||
|
isMigration: !!migrateInput.metas.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
updatedMeta: {
|
||||||
|
__typename: 'SetChapterMetasPayload',
|
||||||
|
metas: chapterIds.flatMap((chapterId) =>
|
||||||
|
(updateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'ChapterMetaType' as const,
|
||||||
|
chapterId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
deletedMeta: {
|
||||||
|
__typename: 'DeleteChapterMetasPayload',
|
||||||
|
metas: chapterIds.flatMap((chapterId) =>
|
||||||
|
(deleteInput?.keys ?? []).map((key) => ({
|
||||||
|
__typename: 'ChapterMetaType' as const,
|
||||||
|
chapterId,
|
||||||
|
key,
|
||||||
|
value: '',
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
migrationMeta: {
|
||||||
|
__typename: 'SetChapterMetasPayload',
|
||||||
|
metas: chapterIds.flatMap((chapterId) =>
|
||||||
|
(migrateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'ChapterMetaType' as const,
|
||||||
|
chapterId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update(cache, { data }) {
|
||||||
|
chapterIds.forEach((chapterId) => {
|
||||||
|
deleteInput?.keys?.forEach((key) => {
|
||||||
|
cache.evict({ id: cache.identify({ __typename: 'ChapterMetaType', chapterId, key }) });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data?.updatedMeta && !data?.migrationMeta) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chapterIds.forEach((chapterId) => {
|
||||||
|
cache.modify({
|
||||||
|
id: cache.identify({ __typename: 'ChapterType', id: chapterId }),
|
||||||
|
fields: {
|
||||||
|
meta(existingMetas, { readField }) {
|
||||||
|
const updatedMeta = [
|
||||||
|
...(data?.updatedMeta?.metas ?? []),
|
||||||
|
...(data?.migrationMeta?.metas ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
return updateMetadataList(updatedMeta, existingMetas, readField, (meta) =>
|
||||||
|
cache.writeFragment({
|
||||||
|
data: meta,
|
||||||
|
fragment: CHAPTER_META_FIELDS,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public getChapterPageUrl(mangaId: number | string, chapterIndex: number | string, page: number): string {
|
public getChapterPageUrl(mangaId: number | string, chapterIndex: number | string, page: number): string {
|
||||||
return this.getValidImgUrlFor(
|
return this.getValidImgUrlFor(
|
||||||
`manga/${mangaId}/chapter/${chapterIndex}/page/${page}`,
|
`manga/${mangaId}/chapter/${chapterIndex}/page/${page}`,
|
||||||
@@ -2910,6 +3330,104 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateCategoryMeta(
|
||||||
|
categoryIds: CategoryIdInfo['id'][],
|
||||||
|
{
|
||||||
|
updateInput = { metas: [] },
|
||||||
|
deleteInput = { keys: [] },
|
||||||
|
migrateInput = { metas: [] },
|
||||||
|
}: {
|
||||||
|
updateInput?: Omit<SetCategoryMetasItemInput, 'categoryIds'>;
|
||||||
|
deleteInput?: Omit<DeleteCategoryMetasItemInput, 'categoryIds'>;
|
||||||
|
migrateInput?: Omit<SetCategoryMetasItemInput, 'categoryIds'>;
|
||||||
|
},
|
||||||
|
options?: MutationOptions<UpdateCategoryMetadataMutation, UpdateCategoryMetadataMutationVariables>,
|
||||||
|
): AbortableApolloMutationResponse<UpdateCategoryMetadataMutation> {
|
||||||
|
return this.doRequest<UpdateCategoryMetadataMutation, UpdateCategoryMetadataMutationVariables>(
|
||||||
|
GQLMethod.MUTATION,
|
||||||
|
UPDATE_CATEGORY_METADATA,
|
||||||
|
{
|
||||||
|
updateInput: { items: [{ ...updateInput, categoryIds }] },
|
||||||
|
hasUpdates: !!updateInput.metas.length,
|
||||||
|
deleteInput: { items: [{ ...deleteInput, categoryIds }] },
|
||||||
|
hasDeletions: !!deleteInput.keys?.length || !!deleteInput.prefixes?.length,
|
||||||
|
migrateInput: { items: [{ ...migrateInput, categoryIds }] },
|
||||||
|
isMigration: !!migrateInput.metas.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
updatedMeta: {
|
||||||
|
__typename: 'SetCategoryMetasPayload',
|
||||||
|
metas: categoryIds.flatMap((categoryId) =>
|
||||||
|
(updateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'CategoryMetaType' as const,
|
||||||
|
categoryId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
deletedMeta: {
|
||||||
|
__typename: 'DeleteCategoryMetasPayload',
|
||||||
|
metas: categoryIds.flatMap((categoryId) =>
|
||||||
|
(deleteInput?.keys ?? []).map((key) => ({
|
||||||
|
__typename: 'CategoryMetaType' as const,
|
||||||
|
categoryId,
|
||||||
|
key,
|
||||||
|
value: '',
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
migrationMeta: {
|
||||||
|
__typename: 'SetCategoryMetasPayload',
|
||||||
|
metas: categoryIds.flatMap((categoryId) =>
|
||||||
|
(migrateInput?.metas ?? []).map((meta) => ({
|
||||||
|
__typename: 'CategoryMetaType' as const,
|
||||||
|
categoryId,
|
||||||
|
key: meta.key,
|
||||||
|
value: meta.value,
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update(cache, { data }) {
|
||||||
|
categoryIds.forEach((categoryId) => {
|
||||||
|
deleteInput?.keys?.forEach((key) => {
|
||||||
|
cache.evict({ id: cache.identify({ __typename: 'CategoryMetaType', categoryId, key }) });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data?.updatedMeta && !data?.migrationMeta) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryIds.forEach((categoryId) => {
|
||||||
|
cache.modify({
|
||||||
|
id: cache.identify({ __typename: 'CategoryType', id: categoryId }),
|
||||||
|
fields: {
|
||||||
|
meta(existingMetas, { readField }) {
|
||||||
|
const updatedMeta = [
|
||||||
|
...(data?.updatedMeta?.metas ?? []),
|
||||||
|
...(data?.migrationMeta?.metas ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
return updateMetadataList(updatedMeta, existingMetas, readField, (meta) =>
|
||||||
|
cache.writeFragment({
|
||||||
|
data: meta,
|
||||||
|
fragment: CATEGORY_META_FIELDS,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
...options,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public createBackupFile(
|
public createBackupFile(
|
||||||
input: CreateBackupInput,
|
input: CreateBackupInput,
|
||||||
options?: MutationOptions<CreateBackupMutation, CreateBackupMutationVariables>,
|
options?: MutationOptions<CreateBackupMutation, CreateBackupMutationVariables>,
|
||||||
|
|||||||
Reference in New Issue
Block a user