Handle source browse error

This commit is contained in:
schroda
2024-10-06 16:15:01 +02:00
parent 2916bfbe88
commit 6e9fdee0bb
3 changed files with 55 additions and 22 deletions

View File

@@ -669,6 +669,16 @@ export class RequestManager {
const { signal, abortRequest } = this.createAbortController(); const { signal, abortRequest } = this.createAbortController();
setAbortRequest(abortRequest); setAbortRequest(abortRequest);
const isRefetch = newPage === [...cachedPages][cachedPages.size - 1];
if (isRefetch) {
this.cache.cacheResponse(
cachePagesKey,
getVariablesFor(0),
new Set([...cachedPages].slice(0, cachedPages.size - 1)),
);
this.cache.clearFor(this.cache.getKeyFor(cacheResultsKey, getVariablesFor(newPage)));
}
setResult({ setResult({
...getResultIdInfo(), ...getResultIdInfo(),
...createPaginatedResult({ isLoading: true, abortRequest, size: newPage, called: true }), ...createPaginatedResult({ isLoading: true, abortRequest, size: newPage, called: true }),
@@ -689,6 +699,7 @@ export class RequestManager {
basePaginatedResult.data = response.data; basePaginatedResult.data = response.data;
} catch (error: any) { } catch (error: any) {
defaultPromiseErrorHandler('RequestManager::fetchPaginatedMutationPage')(error);
if (error instanceof ApolloError) { if (error instanceof ApolloError) {
basePaginatedResult.error = error; basePaginatedResult.error = error;
} else { } else {
@@ -706,12 +717,9 @@ export class RequestManager {
setResult(fetchPaginatedResult); setResult(fetchPaginatedResult);
const shouldCacheResult = !fetchPaginatedResult.error; const currentCachedPages = this.cache.getResponseFor<Set<number>>(cachePagesKey, getVariablesFor(0)) ?? [];
if (shouldCacheResult) { this.cache.cacheResponse(cachePagesKey, getVariablesFor(0), new Set([...currentCachedPages, newPage]));
const currentCachedPages = this.cache.getResponseFor<Set<number>>(cachePagesKey, getVariablesFor(0)) ?? []; this.cache.cacheResponse(cacheResultsKey, getVariablesFor(newPage), fetchPaginatedResult);
this.cache.cacheResponse(cachePagesKey, getVariablesFor(0), new Set([...currentCachedPages, newPage]));
this.cache.cacheResponse(cacheResultsKey, getVariablesFor(newPage), fetchPaginatedResult);
}
return response; return response;
} }

View File

@@ -114,9 +114,10 @@ const SourceSearchPreview = React.memo(
skipRequest: !searchString, skipRequest: !searchString,
addAbortSignal: true, addAbortSignal: true,
}); });
console.log('SearchAll', source.displayName, results);
const { data: searchResult, isLoading, error, abortRequest } = results[0]!; const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
const mangas = searchResult?.fetchSourceManga?.mangas ?? []; const mangas = searchResult?.fetchSourceManga?.mangas ?? [];
const noMangasFound = !isLoading && !mangas.length; const noMangasFound = !error && !isLoading && !mangas.length;
useEffect(() => { useEffect(() => {
onSearchRequestFinished(source, isLoading, !noMangasFound, !searchString); onSearchRequestFinished(source, isLoading, !noMangasFound, !searchString);

View File

@@ -47,6 +47,9 @@ import { GET_SOURCE_BROWSE } from '@/lib/graphql/queries/SourceQuery.ts';
import { MangaIdInfo } from '@/modules/manga/services/Mangas.ts'; import { MangaIdInfo } from '@/modules/manga/services/Mangas.ts';
import { TranslationKey } from '@/Base.types.ts'; import { TranslationKey } from '@/Base.types.ts';
import { IPos } from '@/modules/source/Source.types.ts'; import { IPos } from '@/modules/source/Source.types.ts';
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
import { EmptyView } from '@/modules/core/components/placeholder/EmptyView.tsx';
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx';
const ContentTypeMenu = styled('div')(({ theme }) => ({ const ContentTypeMenu = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
@@ -262,8 +265,10 @@ export function SourceMangas() {
setLocationContentType(newContentType); setLocationContentType(newContentType);
}; };
const [loadPage, { data, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage }] = const [
useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries); loadPage,
{ data, error, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage },
] = useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries);
const isLoading = loading || filteredOutAllItemsOfFetchedPage; const isLoading = loading || filteredOutAllItemsOfFetchedPage;
const mangas = data?.fetchSourceManga?.mangas ?? []; const mangas = data?.fetchSourceManga?.mangas ?? [];
const hasNextPage = !!data?.fetchSourceManga?.hasNextPage; const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
@@ -454,19 +459,38 @@ export function SourceMangas() {
{t('global.button.filter')} {t('global.button.filter')}
</ContentTypeButton> </ContentTypeButton>
</ContentTypeMenu> </ContentTypeMenu>
<BaseMangaGrid
key={contentType} {(isLoading || !error || (!!error && !!mangas.length)) && (
gridWrapperProps={{ sx: { px: 1, pb: 1 } }} <BaseMangaGrid
mangas={mangas} key={contentType}
hasNextPage={hasNextPage} gridWrapperProps={{ sx: { px: 1, pb: 1 } }}
loadMore={loadMore} mangas={mangas}
message={message} hasNextPage={hasNextPage}
messageExtra={messageExtra} loadMore={loadMore}
isLoading={isLoading} message={message}
gridLayout={sourceGridLayout} messageExtra={messageExtra}
mode="source" isLoading={isLoading}
inLibraryIndicator gridLayout={sourceGridLayout}
/> mode="source"
inLibraryIndicator
/>
)}
{error && !mangas.length && (
<EmptyViewAbsoluteCentered
message={t('global.error.label.failed_to_load_data')}
messageExtra={error.message}
retry={() => loadPage(lastPageNum).catch(defaultPromiseErrorHandler('SourceMangas::refetch'))}
/>
)}
{error && !!mangas.length && (
<EmptyView
message={t('global.error.label.failed_to_load_data')}
messageExtra={error.message}
retry={() => loadPage(lastPageNum).catch(defaultPromiseErrorHandler('SourceMangas::refetch'))}
/>
)}
{contentType === SourceContentType.SEARCH && ( {contentType === SourceContentType.SEARCH && (
<SourceOptions <SourceOptions
savedSearches={savedSearches} savedSearches={savedSearches}