Save chapter list options on server

This commit is contained in:
schroda
2025-04-20 21:40:28 +02:00
parent 0f3becf505
commit 0733c930d4
13 changed files with 172 additions and 104 deletions

View File

@@ -20,8 +20,8 @@ import {
TrackRecordType,
} from '@/lib/graphql/generated/graphql.ts';
import { SingleModeProps } from '@/modules/manga/components/MangaActionMenuItems.tsx';
import { IReaderSettings } from '@/modules/reader/types/Reader.types.ts';
import { GridLayout } from '@/modules/core/Core.types.ts';
import { ChapterListOptions } from '@/modules/chapter/Chapter.types.ts';
export type MangaCardMode = 'default' | 'source' | 'migrate.search' | 'migrate.select' | 'duplicate';
@@ -67,7 +67,9 @@ export type SpecificMangaCardProps = Omit<MangaCardProps, 'manga'> &
mangaBadges: JSX.Element;
};
export type MangaMetadataKeys = keyof IReaderSettings;
export type MangaMetadata = ChapterListOptions;
export type MangaMetadataKeys = keyof MangaMetadata;
export type MangaAction =
| 'download'

View File

@@ -0,0 +1,91 @@
/*
* 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 { useEffect, useMemo } from 'react';
import { DEFAULT_CHAPTER_OPTIONS } from '@/modules/chapter/Chapter.constants.ts';
import { getMetadataFrom } from '@/modules/metadata/services/MetadataReader.ts';
import { MangaIdInfo, MangaMetadata, MangaMetadataKeys } from '@/modules/manga/Manga.types.ts';
import {
AllowedMetadataValueTypes,
AppMetadataKeys,
GqlMetaHolder,
Metadata,
MetadataHolder,
} from '@/modules/metadata/Metadata.types.ts';
import { convertFromGqlMeta } from '@/modules/metadata/services/MetadataConverter.ts';
import { requestUpdateMangaMetadata } from '@/modules/metadata/services/MetadataUpdater.ts';
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
const DEFAULT_MANGA_METADATA: MangaMetadata = {
...DEFAULT_CHAPTER_OPTIONS,
};
const convertAppMetadataToGqlMetadata = (
metadata: Partial<MangaMetadata>,
): Metadata<string, AllowedMetadataValueTypes> => ({
...metadata,
});
const convertGqlMetadataToAppMetadata = (
metadata: Partial<Metadata<AppMetadataKeys, AllowedMetadataValueTypes>>,
): MangaMetadata => ({
...(metadata as unknown as MangaMetadata),
});
const getMangaMetadataWithDefaultValueFallback = (
meta: MangaIdInfo & MetadataHolder,
defaultMetadata: MangaMetadata = DEFAULT_MANGA_METADATA,
useEffectFn?: typeof useEffect,
): MangaMetadata =>
convertGqlMetadataToAppMetadata(
getMetadataFrom('manga', meta, convertAppMetadataToGqlMetadata(defaultMetadata), undefined, useEffectFn),
);
const getMetadata = (
metaHolder: MangaIdInfo & GqlMetaHolder,
defaultMetadata?: MangaMetadata,
useEffectFn?: typeof useEffect,
) =>
getMangaMetadataWithDefaultValueFallback(
{ ...metaHolder, meta: convertFromGqlMeta(metaHolder.meta) },
defaultMetadata,
useEffectFn,
);
export const getMangaMetadata = (
metaHolder: MangaIdInfo & GqlMetaHolder,
defaultMetadata?: MangaMetadata,
): MangaMetadata => getMetadata(metaHolder, defaultMetadata);
export const useGetMangaMetadata = (
metaHolder: MangaIdInfo & GqlMetaHolder,
defaultMetadata?: MangaMetadata,
): MangaMetadata => {
const metadata = getMetadata(metaHolder, defaultMetadata, useEffect);
return useMemo(() => metadata, [metaHolder, defaultMetadata]);
};
export const updateMangaMetadata = async <
MetadataKeys extends MangaMetadataKeys = MangaMetadataKeys,
MetadataKey extends MetadataKeys = MetadataKeys,
>(
manga: MangaIdInfo & GqlMetaHolder,
metadataKey: MetadataKey,
value: MangaMetadata[MetadataKey],
): Promise<void[]> =>
requestUpdateMangaMetadata(manga, [
[metadataKey, convertAppMetadataToGqlMetadata({ [metadataKey]: value })[metadataKey]],
]);
export const createUpdateMangaMetadata =
<Settings extends MangaMetadataKeys>(
manga: MangaIdInfo & GqlMetaHolder,
handleError: (error: any) => void = defaultPromiseErrorHandler('createUpdateMangaMetadata'),
): ((...args: OmitFirst<Parameters<typeof updateMangaMetadata<Settings>>>) => Promise<void | void[]>) =>
(metadataKey, value) =>
updateMangaMetadata(manga, metadataKey, value).catch(handleError);