Fix/request manager infinite swr requests (#306)

* Fix RequestManager initial infinite swr requests

Functions always returned "null" as the url, which causes SWR to not send the request

 - useGetSourceLatestMangas
 - useSourceSearch
 - useSourceQuickSearch

* Use "skipRequest" for infinite SWR requests

Is easier to use then overwriting "getEndpoint" only for specific cases

* Request correct first page for infinite SWR requests

The following endpoints start at page 1
 - popular source mangas
 - latest source mangas
 - source search
 - source quick search

* Remove wrong parameter from source manga browse requests

No idea why I've added this in the first place

* Correctly request "latest" and "popular" source mangas

The "page" wasn't a param of the query but part of the endpoint
This commit is contained in:
schroda
2023-05-20 13:12:23 +02:00
committed by GitHub
parent feac34ba83
commit 0cd5720f54
2 changed files with 26 additions and 20 deletions

View File

@@ -24,6 +24,7 @@ import {
IUpdateStatus, IUpdateStatus,
Metadata, Metadata,
PaginatedList, PaginatedList,
PaginatedMangaList,
SourcePreferences, SourcePreferences,
SourceSearchResult, SourceSearchResult,
UpdateCheck, UpdateCheck,
@@ -125,23 +126,26 @@ export class RequestManager {
}); });
} }
public useSwrInfinite<Data = any, ErrorResponse = any>( public useSwrInfinite<
Data = any,
ErrorResponse = any,
OptionsSWR extends SWRInfiniteOptions<Data, ErrorResponse> = SWRInfiniteOptions<Data, ErrorResponse>,
>(
getEndpoint: Required<CustomSWROptions<Data>>['getEndpoint'], getEndpoint: Required<CustomSWROptions<Data>>['getEndpoint'],
{ { axiosOptions, swrOptions }: { axiosOptions?: AxiosRequestConfig; swrOptions?: OptionsSWR } = {},
axiosOptions,
swrOptions,
}: { axiosOptions?: AxiosRequestConfig; swrOptions?: SWRInfiniteConfiguration<Data, ErrorResponse> } = {},
): SWRInfiniteResponse<Data, ErrorResponse> { ): SWRInfiniteResponse<Data, ErrorResponse> {
const { skipRequest, ...swrConfig } = swrOptions ?? {};
// useSWRInfinite will (by default) revalidate the first page, to check if the other pages have to be revalidated as well // useSWRInfinite will (by default) revalidate the first page, to check if the other pages have to be revalidated as well
const result = useSWRInfinite<Data, ErrorResponse>( const result = useSWRInfinite<Data, ErrorResponse>(
(index, previousData) => { (index, previousData) => {
const pageEndpoint = getEndpoint(index, previousData); const pageEndpoint = getEndpoint(index, previousData);
return pageEndpoint !== null ? this.getValidUrlFor(pageEndpoint) : null; return pageEndpoint !== null && !skipRequest ? this.getValidUrlFor(pageEndpoint) : null;
}, },
{ {
fetcher: (path: string) => fetcher: (path: string) =>
this.restClient.fetcher(path, { httpMethod: HttpMethod.GET, config: axiosOptions }), this.restClient.fetcher(path, { httpMethod: HttpMethod.GET, config: axiosOptions }),
...swrOptions, ...swrConfig,
}, },
); );
@@ -163,7 +167,6 @@ export class RequestManager {
* In that case "getEndpoint" has to be passed, which gets used over "endpoint" * In that case "getEndpoint" has to be passed, which gets used over "endpoint"
* *
* Pass "skipRequest" to make SWR skip sending the request to the server. * Pass "skipRequest" to make SWR skip sending the request to the server.
* Only works for none "infinite" requests, for "infinite" requests the "getEndpoint" function can return "null".
* In case "formData" is passed, "data" gets ignored. * In case "formData" is passed, "data" gets ignored.
*/ */
private doRequest< private doRequest<
@@ -265,14 +268,13 @@ export class RequestManager {
public useGetSourcePopularMangas( public useGetSourcePopularMangas(
sourceId: string, sourceId: string,
extension: string,
initialPages?: number, initialPages?: number,
swrOptions?: SWRInfiniteOptions<PaginatedList<IManga>>, swrOptions?: SWRInfiniteOptions<PaginatedMangaList>,
): SWRInfiniteResponse<PaginatedList<IManga>> { ): SWRInfiniteResponse<PaginatedMangaList> {
return this.doRequest(SWRHttpMethod.SWR_GET_INFINITE, '', { return this.doRequest(SWRHttpMethod.SWR_GET_INFINITE, '', {
swrOptions: { swrOptions: {
getEndpoint: (page, previousData) => getEndpoint: (page, previousData) =>
previousData?.hasNextPage ? `source/${sourceId}/popular/${extension}?pageNum=${page}` : null, previousData?.hasNextPage ?? true ? `source/${sourceId}/popular/${page + 1}` : null,
initialSize: initialPages, initialSize: initialPages,
...swrOptions, ...swrOptions,
} as typeof swrOptions, } as typeof swrOptions,
@@ -281,14 +283,13 @@ export class RequestManager {
public useGetSourceLatestMangas( public useGetSourceLatestMangas(
sourceId: string, sourceId: string,
extension: string,
initialPages?: number, initialPages?: number,
swrOptions?: SWRInfiniteOptions<PaginatedList<IManga>>, swrOptions?: SWRInfiniteOptions<PaginatedMangaList>,
): SWRInfiniteResponse<PaginatedList<IManga>> { ): SWRInfiniteResponse<PaginatedMangaList> {
return this.doRequest(SWRHttpMethod.SWR_GET_INFINITE, '', { return this.doRequest(SWRHttpMethod.SWR_GET_INFINITE, '', {
swrOptions: { swrOptions: {
getEndpoint: (page, previousData) => getEndpoint: (page, previousData) =>
previousData?.hasNextPage ? `source/${sourceId}/latest/${extension}?pageNum=${page}` : null, previousData?.hasNextPage ?? true ? `source/${sourceId}/latest/${page + 1}` : null,
initialSize: initialPages, initialSize: initialPages,
...swrOptions, ...swrOptions,
} as typeof swrOptions, } as typeof swrOptions,
@@ -331,8 +332,8 @@ export class RequestManager {
return this.doRequest(HttpMethod.SWR_GET_INFINITE, '', { return this.doRequest(HttpMethod.SWR_GET_INFINITE, '', {
swrOptions: { swrOptions: {
getEndpoint: (page, previousData) => getEndpoint: (page, previousData) =>
previousData?.hasNextPage previousData?.hasNextPage ?? true
? `source/${sourceId}/search?searchTerm=${searchTerm}&pageNum=${page}` ? `source/${sourceId}/search?searchTerm=${searchTerm}&pageNum=${page + 1}`
: null, : null,
initialSize: initialPages, initialSize: initialPages,
...swrOptions, ...swrOptions,
@@ -351,8 +352,8 @@ export class RequestManager {
data: filters, data: filters,
swrOptions: { swrOptions: {
getEndpoint: (page, previousData) => getEndpoint: (page, previousData) =>
previousData?.hasNextPage previousData?.hasNextPage ?? true
? `source/${sourceId}/quick-search?searchTerm=${searchTerm}&pageNum=${page}` ? `source/${sourceId}/quick-search?searchTerm=${searchTerm}&pageNum=${page + 1}`
: null, : null,
initialSize: initialPages, initialSize: initialPages,
...swrOptions, ...swrOptions,

View File

@@ -330,6 +330,11 @@ export interface PaginatedList<T> {
hasNextPage: boolean; hasNextPage: boolean;
} }
export type PaginatedMangaList = {
mangaList: IManga[];
hasNextPage: boolean;
};
export type NullAndUndefined<T> = T | null | undefined; export type NullAndUndefined<T> = T | null | undefined;
export type ChapterSortMode = 'fetchedAt' | 'source'; export type ChapterSortMode = 'fetchedAt' | 'source';