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( + () => ( + + ), + [url], + ); + + if (!url) { + return button; + } + + return ( + + + + ); +}; + 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 Thumbnail + {manga.thumbnailUrl && ( + Manga Thumbnail + )}

{manga.title}

@@ -195,11 +223,7 @@ const MangaDetails: React.FC = ({ manga }) => { {manga.inLibrary ? t('manga.button.in_library') : t('manga.button.add_to_library')} - - - +
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 };