Use gql for "mangas" I - get manga
This commit is contained in:
@@ -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 = () => {
|
||||
</>
|
||||
}
|
||||
>
|
||||
<IconButton onClick={() => mutate()}>
|
||||
<IconButton onClick={() => refetch()}>
|
||||
<Warning color="error" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
@@ -80,7 +87,7 @@ const Manga: React.FC = () => {
|
||||
{manga && <MangaToolbarMenu manga={manga} onRefresh={refresh} refreshing={refreshing} />}
|
||||
</Stack>,
|
||||
);
|
||||
}, [t, error, isValidating, refreshing, mutate, manga, refresh]);
|
||||
}, [t, error, isValidating, refreshing, manga, refresh]);
|
||||
|
||||
if (error && !manga) {
|
||||
return <EmptyView message={t('manga.error.label.request_failure')} messageExtra={error.message ?? error} />;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 (
|
||||
<ReaderSettingsOptions
|
||||
|
||||
@@ -12,7 +12,7 @@ import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SearchMetadataKeys } from '@/typings';
|
||||
import { requestUpdateServerMetadata } from '@/util/metadata';
|
||||
import { convertToGqlMeta, requestUpdateServerMetadata } from '@/util/metadata';
|
||||
import { useSearchSettings } from '@/util/searchSettings';
|
||||
import makeToast from '@/components/util/Toast';
|
||||
import { useSetDefaultBackTo } from '@/components/context/NavbarContext';
|
||||
@@ -24,7 +24,7 @@ export default function SearchSettings() {
|
||||
useSetDefaultBackTo('settings');
|
||||
|
||||
const setSettingValue = (key: SearchMetadataKeys, value: boolean) => {
|
||||
requestUpdateServerMetadata(metadata ?? {}, [[key, value]]).catch(() =>
|
||||
requestUpdateServerMetadata(convertToGqlMeta(metadata)! ?? {}, [[key, value]]).catch(() =>
|
||||
makeToast(t('search.error.label.failed_to_save_settings'), 'warning'),
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user