diff --git a/src/components/manga/MangaDetails.tsx b/src/components/manga/MangaDetails.tsx
index 22aa6daa..8b148034 100644
--- a/src/components/manga/MangaDetails.tsx
+++ b/src/components/manga/MangaDetails.tsx
@@ -10,14 +10,15 @@ import FavoriteIcon from '@mui/icons-material/Favorite';
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
import PublicIcon from '@mui/icons-material/Public';
import { styled } from '@mui/material/styles';
-import React, { useEffect } from 'react';
+import React, { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { mutate } from 'swr';
import { t as translate } from 'i18next';
import Button from '@mui/material/Button';
-import { IManga, ISource } from '@/typings';
+import { ISource } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import makeToast from '@/components/util/Toast';
+import { MangaType } from '@/lib/graphql/generated/graphql.ts';
const DetailsWrapper = styled('div')(({ theme }) => ({
width: '100%',
@@ -125,11 +126,36 @@ const Genres = styled('div')(() => ({
},
}));
+const OpenSourceButton = ({ url }: { url?: string | null }) => {
+ const { t } = useTranslation();
+
+ const button = useMemo(
+ () => (
+ } size="large">
+ {t('global.button.open_site')}
+
+ ),
+ [url],
+ );
+
+ if (!url) {
+ return button;
+ }
+
+ return (
+
+ } size="large">
+ {t('global.button.open_site')}
+
+
+ );
+};
+
interface IProps {
- manga: IManga;
+ manga: MangaType;
}
-function getSourceName(source: ISource) {
+function getSourceName(source?: ISource | null) {
if (!source) {
return translate('global.label.unknown');
}
@@ -137,7 +163,7 @@ function getSourceName(source: ISource) {
return source.displayName ?? source.id;
}
-function getValueOrUnknown(val: string) {
+function getValueOrUnknown(val?: string | null) {
return val || 'UNKNOWN';
}
@@ -169,7 +195,9 @@ const MangaDetails: React.FC = ({ manga }) => {
-
+ {manga.thumbnailUrl && (
+
+ )}
{manga.title}
@@ -195,11 +223,7 @@ const MangaDetails: React.FC = ({ manga }) => {
{manga.inLibrary ? t('manga.button.in_library') : t('manga.button.add_to_library')}
-
- } size="large">
- {t('global.button.open_site')}
-
-
+
diff --git a/src/components/manga/MangaToolbarMenu.tsx b/src/components/manga/MangaToolbarMenu.tsx
index 43980f94..4e035d04 100644
--- a/src/components/manga/MangaToolbarMenu.tsx
+++ b/src/components/manga/MangaToolbarMenu.tsx
@@ -21,11 +21,11 @@ import {
} from '@mui/material';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
-import { IManga } from '@/typings';
import CategorySelect from '@/components/navbar/action/CategorySelect';
+import { MangaType } from '@/lib/graphql/generated/graphql.ts';
interface IProps {
- manga: IManga;
+ manga: MangaType;
onRefresh: () => any;
refreshing: boolean;
}
diff --git a/src/components/manga/hooks.ts b/src/components/manga/hooks.ts
index 2bc45b70..4327641a 100644
--- a/src/components/manga/hooks.ts
+++ b/src/components/manga/hooks.ts
@@ -16,7 +16,7 @@ export const useRefreshManga = (mangaId: string) => {
const handleRefresh = useCallback(async () => {
setFetchingOnline(true);
await Promise.all([
- requestManager.getManga(mangaId, true).response.then((res) => {
+ requestManager.getMangaFetch(mangaId).response.then((res) => {
mutate(`${RequestManager.API_VERSION}manga/${mangaId}`, res, { revalidate: false });
}),
requestManager.getMangaChapters(mangaId, true).response.then((res) =>
diff --git a/src/components/navbar/ReaderNavBar.tsx b/src/components/navbar/ReaderNavBar.tsx
index fba208aa..b95ef730 100644
--- a/src/components/navbar/ReaderNavBar.tsx
+++ b/src/components/navbar/ReaderNavBar.tsx
@@ -24,8 +24,9 @@ import ListItemText from '@mui/material/ListItemText';
import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction';
import Collapse from '@mui/material/Collapse';
import { useTranslation } from 'react-i18next';
-import { ChapterOffset, IChapter, IManga, IMangaCard, IReaderSettings } from '@/typings';
+import { ChapterOffset, IChapter, IReaderSettings } from '@/typings';
import ReaderSettingsOptions from '@/components/reader/ReaderSettingsOptions';
+import { MangaType } from '@/lib/graphql/generated/graphql.ts';
const Root = styled('div')(({ theme }) => ({
top: 0,
@@ -114,7 +115,7 @@ const OpenDrawerButton = styled(IconButton)(({ theme }) => ({
interface IProps {
settings: IReaderSettings;
setSettingValue: (key: keyof IReaderSettings, value: string | boolean) => void;
- manga: IManga | IMangaCard;
+ manga: Pick;
chapter: IChapter;
curPage: number;
scrollToPage: (page: number) => void;
diff --git a/src/components/util/EmptyView.tsx b/src/components/util/EmptyView.tsx
index d2a9ad95..ee7df4c9 100644
--- a/src/components/util/EmptyView.tsx
+++ b/src/components/util/EmptyView.tsx
@@ -22,7 +22,7 @@ function getRandomErrorFace() {
interface IProps {
message: string;
- messageExtra?: JSX.Element;
+ messageExtra?: JSX.Element | string;
}
export default function EmptyView({ message, messageExtra }: IProps) {
diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts
index 056d9a54..118b76a6 100644
--- a/src/lib/requests/RequestManager.ts
+++ b/src/lib/requests/RequestManager.ts
@@ -69,6 +69,10 @@ import {
GetExtensionsQueryVariables,
GetGlobalMetadatasQuery,
GetGlobalMetadatasQueryVariables,
+ GetMangaFetchMutation,
+ GetMangaFetchMutationVariables,
+ GetMangaQuery,
+ GetMangaQueryVariables,
GetSourceQuery,
GetSourceQueryVariables,
GetSourcesQuery,
@@ -125,7 +129,12 @@ import {
UPDATE_EXTENSION,
} from '@/lib/graphql/mutations/ExtensionMutation.ts';
import { GET_SOURCE, GET_SOURCES } from '@/lib/graphql/queries/SourceQuery.ts';
-import { SET_MANGA_METADATA, UPDATE_MANGA, UPDATE_MANGA_CATEGORIES } from '@/lib/graphql/mutations/MangaMutation.ts';
+import {
+ GET_MANGA_FETCH,
+ SET_MANGA_METADATA,
+ UPDATE_MANGA,
+ UPDATE_MANGA_CATEGORIES,
+} from '@/lib/graphql/mutations/MangaMutation.ts';
import { GET_MANGA, GET_MANGAS } from '@/lib/graphql/queries/MangaQuery.ts';
import { GET_CATEGORIES, GET_CATEGORY, GET_CATEGORY_MANGAS } from '@/lib/graphql/queries/CategoryQuery.ts';
import { GET_SOURCE_MANGAS_FETCH } from '@/lib/graphql/mutations/SourceMutation.ts';
@@ -712,27 +721,28 @@ export class RequestManager {
public useGetManga(
mangaId: number | string,
- { doOnlineFetch, ...swrOptions }: SWROptions & RequestOption = {},
- ): AbortableSWRResponse {
- const onlineFetch = doOnlineFetch ? '?onlineFetch=true' : '';
- return this.doRequest(HttpMethod.SWR_GET, `manga/${mangaId}${onlineFetch}`, {
- swrOptions,
- });
+ options?: QueryHookOptions,
+ ): AbortableApolloUseQueryResponse {
+ return this.doRequestNew(GQLMethod.USE_QUERY, GET_MANGA, { id: Number(mangaId) }, options);
}
- public getManga(mangaId: number | string, doOnlineFetch?: boolean): AbortableAxiosResponse {
- const onlineFetch = doOnlineFetch ? '?onlineFetch=true' : '';
- return this.doRequest(HttpMethod.GET, `manga/${mangaId}${onlineFetch}`);
- }
-
- public useGetFullManga(
+ public getMangaFetch(
mangaId: number | string,
- { doOnlineFetch, ...swrOptions }: SWROptions & RequestOption = {},
- ): AbortableSWRResponse {
- const onlineFetch = doOnlineFetch ? '?onlineFetch=true' : '';
- return this.doRequest(HttpMethod.SWR_GET, `manga/${mangaId}/full${onlineFetch}`, {
- swrOptions,
- });
+ options?: MutationOptions,
+ ): AbortableApolloMutationResponse {
+ return this.doRequestNew(
+ GQLMethod.MUTATION,
+ GET_MANGA_FETCH,
+ {
+ input: {
+ id: Number(mangaId),
+ },
+ },
+ {
+ refetchQueries: [GET_MANGA, GET_MANGAS],
+ ...options,
+ },
+ );
}
public getMangaThumbnailUrl(mangaId: number): string {
diff --git a/src/screens/Manga.tsx b/src/screens/Manga.tsx
index af6b0e58..aa1566b8 100644
--- a/src/screens/Manga.tsx
+++ b/src/screens/Manga.tsx
@@ -11,6 +11,7 @@ import { CircularProgress, IconButton, Stack, Tooltip, Box } from '@mui/material
import React, { useContext, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
+import { isNetworkRequestInFlight } from '@apollo/client/core/networkStatus';
import requestManager from '@/lib/requests/RequestManager.ts';
import NavbarContext, { useSetDefaultBackTo } from '@/components/context/NavbarContext';
import ChapterList from '@/components/manga/ChapterList';
@@ -19,8 +20,9 @@ import MangaDetails from '@/components/manga/MangaDetails';
import MangaToolbarMenu from '@/components/manga/MangaToolbarMenu';
import EmptyView from '@/components/util/EmptyView';
import LoadingPlaceholder from '@/components/util/LoadingPlaceholder';
+import { MangaType } from '@/lib/graphql/generated/graphql.ts';
-const AUTOFETCH_AGE = 60 * 60 * 24; // 24 hours
+const AUTOFETCH_AGE = 1000 * 60 * 60 * 24; // 24 hours
const Manga: React.FC = () => {
const { t } = useTranslation();
@@ -29,21 +31,26 @@ const Manga: React.FC = () => {
const { id } = useParams<{ id: string }>();
const autofetchedRef = useRef(false);
- const { data: manga, error, isLoading, isValidating, mutate } = requestManager.useGetManga(id);
+ const { data, error, loading: isLoading, networkStatus, refetch } = requestManager.useGetManga(id);
+ const isValidating = isNetworkRequestInFlight(networkStatus);
+ const manga = data?.manga as MangaType | undefined;
const [refresh, { loading: refreshing }] = useRefreshManga(id);
useSetDefaultBackTo('library');
useEffect(() => {
- // Automatically fetch manga from source if data is older then 24 hours
+ // Automatically fetch manga from source if data is older then 24 hours OR manga is not initialized yet
// Automatic fetch is done only once, to prevent issues when server does
// not update age for some reason (ie. error on source side)
if (manga == null) return;
- if (
- manga.inLibrary &&
- (manga.age > AUTOFETCH_AGE || manga.chaptersAge > AUTOFETCH_AGE) &&
- autofetchedRef.current === false
- ) {
+
+ const isOutdated =
+ Date.now() - Number(manga.lastFetchedAt) * 1000 > AUTOFETCH_AGE ||
+ Date.now() - Number(manga.chaptersLastFetchedAt) * 1000 > AUTOFETCH_AGE;
+ const refetchBecauseOutdated = manga.inLibrary && isOutdated;
+
+ const doFetch = !autofetchedRef.current && (refetchBecauseOutdated || !manga.initialized);
+ if (doFetch) {
autofetchedRef.current = true;
refresh();
}
@@ -67,7 +74,7 @@ const Manga: React.FC = () => {
>
}
>
- mutate()}>
+ refetch()}>
@@ -80,7 +87,7 @@ const Manga: React.FC = () => {
{manga && }
,
);
- }, [t, error, isValidating, refreshing, mutate, manga, refresh]);
+ }, [t, error, isValidating, refreshing, manga, refresh]);
if (error && !manga) {
return ;
diff --git a/src/screens/Reader.tsx b/src/screens/Reader.tsx
index d86b65a9..77178232 100644
--- a/src/screens/Reader.tsx
+++ b/src/screens/Reader.tsx
@@ -7,11 +7,11 @@
*/
import CircularProgress from '@mui/material/CircularProgress';
-import { useCallback, useContext, useEffect, useState } from 'react';
+import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { Box } from '@mui/material';
import { useTranslation } from 'react-i18next';
-import { ChapterOffset, IChapter, IManga, IMangaCard, IReaderSettings, ReaderType, TranslationKey } from '@/typings';
+import { ChapterOffset, IChapter, IReaderSettings, ReaderType, TranslationKey } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import {
checkAndHandleMissingStoredReaderSettings,
@@ -27,6 +27,7 @@ import VerticalPager from '@/components/reader/pager/VerticalPager';
import ReaderNavBar from '@/components/navbar/ReaderNavBar';
import NavbarContext from '@/components/context/NavbarContext';
import makeToast from '@/components/util/Toast';
+import { MangaType } from '@/lib/graphql/generated/graphql.ts';
const isDupChapter = async (chapterIndex: number, currentChapter: IChapter) => {
const nextChapter = await requestManager.getChapter(currentChapter.mangaId, chapterIndex).response;
@@ -93,17 +94,22 @@ export default function Reader() {
const location = useLocation();
const { chapterIndex, mangaId } = useParams<{ chapterIndex: string; mangaId: string }>();
- const {
- data: manga = {
- id: +mangaId,
- title: '',
- thumbnailUrl: '',
- genre: [],
- inLibraryAt: 0,
- lastReadAt: 0,
- } as IMangaCard | IManga,
- isLoading: isMangaLoading,
- } = requestManager.useGetManga(mangaId);
+
+ const initialManga = useMemo(
+ () =>
+ ({
+ id: +mangaId,
+ title: '',
+ thumbnailUrl: '',
+ genre: [],
+ inLibraryAt: 0,
+ lastReadAt: 0,
+ }) as unknown as MangaType,
+ [mangaId],
+ );
+
+ const { data, loading: isMangaLoading } = requestManager.useGetManga(mangaId);
+ const manga = (data?.manga as MangaType) ?? initialManga;
const { data: chapter = initialChapter, isLoading: isChapterLoading } = requestManager.useGetChapter(
mangaId,
chapterIndex,
diff --git a/src/screens/settings/DefaultReaderSettings.tsx b/src/screens/settings/DefaultReaderSettings.tsx
index d296a5d7..a71ae4cb 100644
--- a/src/screens/settings/DefaultReaderSettings.tsx
+++ b/src/screens/settings/DefaultReaderSettings.tsx
@@ -11,7 +11,7 @@ import { Box } from '@mui/material';
import CircularProgress from '@mui/material/CircularProgress';
import { useTranslation } from 'react-i18next';
import { IReaderSettings } from '@/typings';
-import { requestUpdateServerMetadata } from '@/util/metadata';
+import { convertToGqlMeta, requestUpdateServerMetadata } from '@/util/metadata';
import {
checkAndHandleMissingStoredReaderSettings,
getDefaultSettings,
@@ -34,7 +34,7 @@ export default function DefaultReaderSettings() {
useSetDefaultBackTo('settings');
const setSettingValue = (key: keyof IReaderSettings, value: string | boolean) => {
- requestUpdateServerMetadata(metadata ?? {}, [[key, value]]).catch(() =>
+ requestUpdateServerMetadata(convertToGqlMeta(metadata)! ?? {}, [[key, value]]).catch(() =>
makeToast(t('reader.settings.error.label.failed_to_save_settings'), 'warning'),
);
};
@@ -54,7 +54,11 @@ export default function DefaultReaderSettings() {
);
}
- checkAndHandleMissingStoredReaderSettings({ meta: metadata }, 'server', getDefaultSettings()).catch(() => {});
+ checkAndHandleMissingStoredReaderSettings(
+ { meta: convertToGqlMeta(metadata)! },
+ 'server',
+ getDefaultSettings(),
+ ).catch(() => {});
return (
{
- requestUpdateServerMetadata(metadata ?? {}, [[key, value]]).catch(() =>
+ requestUpdateServerMetadata(convertToGqlMeta(metadata)! ?? {}, [[key, value]]).catch(() =>
makeToast(t('search.error.label.failed_to_save_settings'), 'warning'),
);
};
diff --git a/src/typings.ts b/src/typings.ts
index a052f78c..6efc54d2 100644
--- a/src/typings.ts
+++ b/src/typings.ts
@@ -10,7 +10,7 @@ import { OverridableComponent } from '@mui/material/OverridableComponent';
import { SvgIconTypeMap } from '@mui/material/SvgIcon/SvgIcon';
import { ParseKeys } from 'i18next';
import { Location } from 'react-router-dom';
-import { ExtensionType } from '@/lib/graphql/generated/graphql.ts';
+import { ExtensionType, MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
type GenericLocation = Omit & { state?: State };
@@ -77,6 +77,8 @@ export type Metadata = {
[key in Keys]: Values;
};
+export type GqlMetaHolder = { meta?: MetaType[] };
+
export type MetadataHolder = {
meta?: Metadata;
};
@@ -236,7 +238,7 @@ export interface IReaderProps {
curPage: number;
initialPage: number;
settings: IReaderSettings;
- manga: IMangaCard | IManga;
+ manga: MangaType;
chapter: IChapter | IPartialChapter;
nextChapter: () => void;
prevChapter: () => void;
diff --git a/src/util/metadata.ts b/src/util/metadata.ts
index dd69538b..8ef3464d 100644
--- a/src/util/metadata.ts
+++ b/src/util/metadata.ts
@@ -6,21 +6,17 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
-import { mutate } from 'swr';
import {
AllowedMetadataValueTypes,
AppMetadataKeys,
- ICategory,
- IManga,
- IMangaCard,
- IMangaChapter,
+ GqlMetaHolder,
IMetadataMigration,
Metadata,
MetadataHolder,
MetadataKeyValuePair,
} from '@/typings';
-import requestManager, { RequestManager } from '@/lib/requests/RequestManager.ts';
-import { MetaType } from '@/lib/graphql/generated/graphql.ts';
+import requestManager from '@/lib/requests/RequestManager.ts';
+import { CategoryType, ChapterType, MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
const APP_METADATA_KEY_PREFIX = 'webUI_';
@@ -118,6 +114,27 @@ const convertValueFromMetadata = {
+ if (!gqlMetadata) {
+ return undefined;
+ }
+
+ const metadata: Metadata = {};
+ gqlMetadata.forEach(({ key, value }) => {
+ metadata[key] = value;
+ });
+
+ return metadata;
+};
+
+export const convertToGqlMeta = (metadata?: Metadata): MetaType[] | undefined => {
+ if (!metadata) {
+ return undefined;
+ }
+
+ return Object.entries(metadata).map(([key, value]) => ({ key, value }));
+};
+
const getAppMetadataFrom = (meta: Metadata, appPrefix: string = APP_METADATA_KEY_PREFIX): Metadata => {
const appMetadata: Metadata = {};
@@ -277,6 +294,8 @@ export const getMetadataFrom = {
if (wrap) {
return {
@@ -294,85 +313,54 @@ const wrapMetadataWithMetaKey = (wrap: boolean, metadata: Metadata): MetadataHol
type MetadataHolderType = 'manga' | 'chapter' | 'category' | 'global';
export const requestUpdateMetadataValue = async (
- metadataHolder: MetadataHolder,
+ metadataHolder: GqlMetaHolder,
holderType: MetadataHolderType,
key: AppMetadataKeys,
value: AllowedMetadataValueTypes,
): Promise => {
const metadataKey = getMetadataKey(key);
- const mutatedMetadata = {
- ...metadataHolder.meta,
- [metadataKey]: `${value}`,
- };
- let endpoint: string;
switch (holderType) {
case 'category':
- endpoint = `category/${(metadataHolder as ICategory).id}/meta`;
- await requestManager.setCategoryMeta((metadataHolder as ICategory).id, metadataKey, value).response;
+ await requestManager.setCategoryMeta((metadataHolder as CategoryType).id, metadataKey, value).response;
break;
case 'chapter':
- // eslint-disable-next-line no-case-declarations
- const { manga, chapter } = metadataHolder as IMangaChapter;
- endpoint = `manga/${manga.id}/chapter/${chapter.index}/meta`;
- await requestManager.setChapterMeta(chapter.id, metadataKey, value).response;
+ await requestManager.setChapterMeta((metadataHolder as ChapterType).id, metadataKey, value).response;
break;
case 'global':
- endpoint = 'meta';
await requestManager.setGlobalMetadata(metadataKey, value).response;
break;
case 'manga':
- endpoint = `manga/${(metadataHolder as IManga).id}/meta`;
- await requestManager.setMangaMeta((metadataHolder as IManga).id, metadataKey, value).response;
+ await requestManager.setMangaMeta((metadataHolder as MangaType).id, metadataKey, value).response;
break;
default:
throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`);
}
-
- const urlToMutate = `${RequestManager.API_VERSION}${endpoint}`;
- mutate(
- urlToMutate,
- { ...metadataHolder, ...wrapMetadataWithMetaKey(holderType !== 'global', mutatedMetadata) },
- { revalidate: false },
- );
};
export const requestUpdateMetadata = async (
- metadataHolder: MetadataHolder,
+ metadataHolder: GqlMetaHolder,
holderType: MetadataHolderType,
keysToValues: [AppMetadataKeys, AllowedMetadataValueTypes][],
): Promise =>
Promise.all(keysToValues.map(([key, value]) => requestUpdateMetadataValue(metadataHolder, holderType, key, value)));
export const requestUpdateServerMetadata = async (
- serverMetadata: Metadata,
+ serverMetadata: MetaType[],
keysToValues: MetadataKeyValuePair[],
): Promise => requestUpdateMetadata({ meta: serverMetadata }, 'global', keysToValues);
export const requestUpdateMangaMetadata = async (
- manga: IMangaCard | IManga,
+ manga: MangaType,
keysToValues: MetadataKeyValuePair[],
): Promise => requestUpdateMetadata(manga, 'manga', keysToValues);
export const requestUpdateChapterMetadata = async (
- mangaChapter: IMangaChapter,
+ chapter: ChapterType,
keysToValues: MetadataKeyValuePair[],
-): Promise => requestUpdateMetadata(mangaChapter.chapter, 'chapter', keysToValues);
+): Promise => requestUpdateMetadata(chapter, 'chapter', keysToValues);
export const requestUpdateCategoryMetadata = async (
- category: ICategory,
+ category: CategoryType,
keysToValues: MetadataKeyValuePair[],
): Promise => requestUpdateMetadata(category, 'category', keysToValues);
-
-export const convertGqlMetadata = (gqlMetadata?: MetaType[]): Metadata | undefined => {
- if (!gqlMetadata) {
- return undefined;
- }
-
- const metadata: Metadata = {};
- gqlMetadata.forEach(({ key, value }) => {
- metadata[key] = value;
- });
-
- return metadata;
-};
diff --git a/src/util/readerSettings.ts b/src/util/readerSettings.ts
index 9dce9c73..d3f05cc8 100644
--- a/src/util/readerSettings.ts
+++ b/src/util/readerSettings.ts
@@ -6,14 +6,15 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
-import { IManga, Metadata, MetadataHolder, IReaderSettings, MetadataKeyValuePair } from '@/typings';
+import { Metadata, IReaderSettings, MetadataKeyValuePair, GqlMetaHolder } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import {
- convertGqlMetadata,
+ convertFromGqlMeta,
getMetadataFrom,
requestUpdateMangaMetadata,
requestUpdateServerMetadata,
} from '@/util/metadata';
+import { MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
type UndefinedReaderSettings = {
[setting in keyof IReaderSettings]: IReaderSettings[setting] | undefined;
@@ -42,10 +43,10 @@ export const getReaderSettingsFromMetadata = (
): IReaderSettings => getReaderSettingsWithDefaultValueFallback(meta, defaultSettings, applyMetadataMigration);
export const getReaderSettingsFor = (
- { meta }: MetadataHolder,
+ { meta }: GqlMetaHolder = {},
defaultSettings?: IReaderSettings,
applyMetadataMigration?: boolean,
-): IReaderSettings => getReaderSettingsFromMetadata(meta, defaultSettings, applyMetadataMigration);
+): IReaderSettings => getReaderSettingsFromMetadata(convertFromGqlMeta(meta), defaultSettings, applyMetadataMigration);
export const useDefaultReaderSettings = (): {
metadata?: Metadata;
@@ -53,7 +54,7 @@ export const useDefaultReaderSettings = (): {
loading: boolean;
} => {
const { data, loading } = requestManager.useGetGlobalMeta();
- const metadata = convertGqlMetadata(data?.metas.nodes);
+ const metadata = convertFromGqlMeta(data?.metas.nodes);
const settings = getReaderSettingsWithDefaultValueFallback(metadata);
return { metadata, settings, loading };
@@ -67,11 +68,12 @@ export const useDefaultReaderSettings = (): {
* @param defaultSettings
*/
export const checkAndHandleMissingStoredReaderSettings = async (
- metadataHolder: IManga | MetadataHolder,
+ metadataHolder: Required | MetaType[],
metadataHolderType: 'manga' | 'server',
defaultSettings: IReaderSettings,
): Promise => {
- const meta = metadataHolder.meta ?? (metadataHolder as Metadata);
+ const getMeta = () => (Array.isArray(metadataHolder) ? metadataHolder : metadataHolder.meta);
+ const meta = convertFromGqlMeta(getMeta())!;
const settingsToCheck = getReaderSettingsWithDefaultValueFallback(
meta,
{
@@ -85,7 +87,7 @@ export const checkAndHandleMissingStoredReaderSettings = async (
},
false,
);
- const newSettings = getReaderSettingsFor({ meta }, defaultSettings);
+ const newSettings = getReaderSettingsFor({ meta: getMeta() }, defaultSettings);
const undefinedSettings = Object.entries(settingsToCheck).filter((setting) => setting[1] === undefined);
@@ -101,9 +103,9 @@ export const checkAndHandleMissingStoredReaderSettings = async (
}
if (metadataHolderType === 'manga') {
- await requestUpdateMangaMetadata(metadataHolder as IManga, settingsToUpdate);
+ await requestUpdateMangaMetadata(metadataHolder as MangaType, settingsToUpdate);
return;
}
- await requestUpdateServerMetadata(meta, settingsToUpdate);
+ await requestUpdateServerMetadata(metadataHolder as MetaType[], settingsToUpdate);
};
diff --git a/src/util/searchSettings.ts b/src/util/searchSettings.ts
index 18958d81..5b8a7fc9 100644
--- a/src/util/searchSettings.ts
+++ b/src/util/searchSettings.ts
@@ -8,7 +8,7 @@
import { Metadata, ISearchSettings } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
-import { convertGqlMetadata, getMetadataFrom } from '@/util/metadata';
+import { convertFromGqlMeta, getMetadataFrom } from '@/util/metadata';
export const getDefaultSettings = (): ISearchSettings => ({
ignoreFilters: false,
@@ -25,7 +25,7 @@ export const useSearchSettings = (): {
loading: boolean;
} => {
const { data, loading } = requestManager.useGetGlobalMeta();
- const metadata = convertGqlMetadata(data?.metas.nodes);
+ const metadata = convertFromGqlMeta(data?.metas.nodes);
const settings = getSearchSettingsWithDefaultValueFallback(metadata);
return { metadata, settings, loading };