Feature/request manager remove get client usage (#325)
* Remove "getClient" usage from "metadata" util * Remove "getClient" usage from "useRefreshManga" hook * Remove "getClient" usage from "isDupChapter" util function * Use correct endpoint for setting category metadata "/meta" suffix was missing from url * Use correct http method for updating manga metadata
This commit is contained in:
@@ -8,24 +8,20 @@
|
|||||||
|
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { mutate } from 'swr';
|
import { mutate } from 'swr';
|
||||||
import requestManager from 'lib/RequestManager';
|
import requestManager, { RequestManager } from 'lib/RequestManager';
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
|
||||||
export const useRefreshManga = (mangaId: string) => {
|
export const useRefreshManga = (mangaId: string) => {
|
||||||
const [fetchingOnline, setFetchingOnline] = useState(false);
|
const [fetchingOnline, setFetchingOnline] = useState(false);
|
||||||
|
|
||||||
const handleRefresh = useCallback(async () => {
|
const handleRefresh = useCallback(async () => {
|
||||||
setFetchingOnline(true);
|
setFetchingOnline(true);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
requestManager
|
requestManager.getManga(mangaId, true).response.then((res) => {
|
||||||
.getClient()
|
console.log('manga', res);
|
||||||
.get(`/api/v1/manga/${mangaId}/?onlineFetch=true`)
|
mutate(`${RequestManager.API_VERSION}manga/${mangaId}`, res, { revalidate: false });
|
||||||
.then((res) => mutate(`/api/v1/manga/${mangaId}`, res.data, { revalidate: false })),
|
}),
|
||||||
requestManager
|
requestManager.getMangaChapters(mangaId, true).response.then((res) =>
|
||||||
.getClient()
|
mutate(`${RequestManager.API_VERSION}manga/${mangaId}/chapters`, res, {
|
||||||
.get(`/api/v1/manga/${mangaId}/chapters?onlineFetch=true`)
|
|
||||||
.then((res) =>
|
|
||||||
mutate(`/api/v1/manga/${mangaId}/chapters`, res.data, {
|
|
||||||
revalidate: false,
|
revalidate: false,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export type AbortableSWRInfiniteResponse<Data = any, Error = any> = SWRInfiniteR
|
|||||||
// - POST /api/v1/backup/validate - validate backup # "validate backup file" endpoint used instead
|
// - POST /api/v1/backup/validate - validate backup # "validate backup file" endpoint used instead
|
||||||
// - GET /api/v1/backup/export - export backup # no function needed, url gets called via link triggering the download
|
// - GET /api/v1/backup/export - export backup # no function needed, url gets called via link triggering the download
|
||||||
export class RequestManager {
|
export class RequestManager {
|
||||||
private static readonly API_VERSION = '/api/v1/';
|
public static readonly API_VERSION = '/api/v1/';
|
||||||
|
|
||||||
private readonly restClient: RestClient = new RestClient();
|
private readonly restClient: RestClient = new RestClient();
|
||||||
|
|
||||||
@@ -425,6 +425,11 @@ export class RequestManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getManga(mangaId: number | string, doOnlineFetch?: boolean): AbortableAxiosResponse<IManga> {
|
||||||
|
const onlineFetch = doOnlineFetch ? '?onlineFetch=true' : '';
|
||||||
|
return this.doRequest(HttpMethod.GET, `manga/${mangaId}${onlineFetch}`);
|
||||||
|
}
|
||||||
|
|
||||||
public useGetFullManga(
|
public useGetFullManga(
|
||||||
mangaId: number | string,
|
mangaId: number | string,
|
||||||
{ doOnlineFetch, ...swrOptions }: SWROptions<IManga> & RequestOption = {},
|
{ doOnlineFetch, ...swrOptions }: SWROptions<IManga> & RequestOption = {},
|
||||||
@@ -463,7 +468,7 @@ export class RequestManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setMangaMeta(mangaId: number, key: string, value: any): AbortableAxiosResponse {
|
public setMangaMeta(mangaId: number, key: string, value: any): AbortableAxiosResponse {
|
||||||
return this.doRequest(HttpMethod.POST, `manga/${mangaId}/meta`, { formData: { key, value } });
|
return this.doRequest(HttpMethod.PATCH, `manga/${mangaId}/meta`, { formData: { key, value } });
|
||||||
}
|
}
|
||||||
|
|
||||||
public useGetMangaChapters(
|
public useGetMangaChapters(
|
||||||
@@ -476,6 +481,11 @@ export class RequestManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMangaChapters(mangaId: number | string, doOnlineFetch?: boolean): AbortableAxiosResponse<IChapter[]> {
|
||||||
|
const onlineFetch = doOnlineFetch ? '?onlineFetch=true' : '';
|
||||||
|
return this.doRequest(HttpMethod.GET, `manga/${mangaId}/chapters${onlineFetch}`);
|
||||||
|
}
|
||||||
|
|
||||||
public updateMangaChapters(
|
public updateMangaChapters(
|
||||||
mangaId: number | string,
|
mangaId: number | string,
|
||||||
{
|
{
|
||||||
@@ -506,6 +516,10 @@ export class RequestManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getChapter(mangaId: number | string, chapterIndex: number | string): AbortableAxiosResponse<IChapter> {
|
||||||
|
return this.doRequest(HttpMethod.GET, `manga/${mangaId}/chapter/${chapterIndex}`);
|
||||||
|
}
|
||||||
|
|
||||||
public deleteDownloadedChapter(mangaId: number | string, chapterIndex: number | string): AbortableAxiosResponse {
|
public deleteDownloadedChapter(mangaId: number | string, chapterIndex: number | string): AbortableAxiosResponse {
|
||||||
return this.doRequest(HttpMethod.DELETE, `manga/${mangaId}/chapter/${chapterIndex}`);
|
return this.doRequest(HttpMethod.DELETE, `manga/${mangaId}/chapter/${chapterIndex}`);
|
||||||
}
|
}
|
||||||
@@ -570,7 +584,7 @@ export class RequestManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setCategoryMeta(categoryId: number, key: string, value: any): AbortableAxiosResponse {
|
public setCategoryMeta(categoryId: number, key: string, value: any): AbortableAxiosResponse {
|
||||||
return this.doRequest(HttpMethod.PATCH, `category/${categoryId}`, { formData: { key, value } });
|
return this.doRequest(HttpMethod.PATCH, `category/${categoryId}/meta`, { formData: { key, value } });
|
||||||
}
|
}
|
||||||
|
|
||||||
public restoreBackupFile(file: File): AbortableAxiosResponse {
|
public restoreBackupFile(file: File): AbortableAxiosResponse {
|
||||||
|
|||||||
@@ -29,11 +29,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import requestManager from 'lib/RequestManager';
|
import requestManager from 'lib/RequestManager';
|
||||||
|
|
||||||
const isDupChapter = async (chapterIndex: number, currentChapter: IChapter) => {
|
const isDupChapter = async (chapterIndex: number, currentChapter: IChapter) => {
|
||||||
const nextChapter = (
|
const nextChapter = await requestManager.getChapter(currentChapter.mangaId, chapterIndex).response;
|
||||||
await requestManager
|
|
||||||
.getClient()
|
|
||||||
.get<IChapter>(`/api/v1/manga/${currentChapter.mangaId}/chapter/${chapterIndex}`)
|
|
||||||
).data;
|
|
||||||
|
|
||||||
return nextChapter.chapterNumber === currentChapter.chapterNumber;
|
return nextChapter.chapterNumber === currentChapter.chapterNumber;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ import {
|
|||||||
IManga,
|
IManga,
|
||||||
IMangaCard,
|
IMangaCard,
|
||||||
IMangaChapter,
|
IMangaChapter,
|
||||||
|
IMetadataMigration,
|
||||||
Metadata,
|
Metadata,
|
||||||
MetadataHolder,
|
MetadataHolder,
|
||||||
IMetadataMigration,
|
|
||||||
MetadataKeyValuePair,
|
MetadataKeyValuePair,
|
||||||
} from 'typings';
|
} from 'typings';
|
||||||
import requestManager from 'lib/RequestManager';
|
import requestManager, { RequestManager } from 'lib/RequestManager';
|
||||||
|
|
||||||
const APP_METADATA_KEY_PREFIX = 'webUI_';
|
const APP_METADATA_KEY_PREFIX = 'webUI_';
|
||||||
|
|
||||||
@@ -290,72 +290,75 @@ const wrapMetadataWithMetaKey = (wrap: boolean, metadata: Metadata): MetadataHol
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type MetadataHolderType = 'manga' | 'chapter' | 'category' | 'global';
|
||||||
|
|
||||||
export const requestUpdateMetadataValue = async (
|
export const requestUpdateMetadataValue = async (
|
||||||
endpoint: string,
|
|
||||||
metadataHolder: MetadataHolder,
|
metadataHolder: MetadataHolder,
|
||||||
|
holderType: MetadataHolderType,
|
||||||
key: AppMetadataKeys,
|
key: AppMetadataKeys,
|
||||||
value: AllowedMetadataValueTypes,
|
value: AllowedMetadataValueTypes,
|
||||||
endpointToMutate: string = endpoint,
|
|
||||||
wrapWithMetaKey: boolean = true,
|
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const restApiVersion = '/api/v1';
|
|
||||||
const url = `${restApiVersion}${endpoint}/meta`;
|
|
||||||
const urlToMutate = `${restApiVersion}${endpointToMutate}`;
|
|
||||||
|
|
||||||
const metadataKey = getMetadataKey(key);
|
const metadataKey = getMetadataKey(key);
|
||||||
const valueAsString = `${value}`;
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('key', metadataKey);
|
|
||||||
formData.append('value', valueAsString);
|
|
||||||
|
|
||||||
const mutatedMetadata = {
|
const mutatedMetadata = {
|
||||||
...metadataHolder.meta,
|
...metadataHolder.meta,
|
||||||
[metadataKey]: valueAsString,
|
[metadataKey]: `${value}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
await requestManager.getClient().patch(url, formData);
|
let endpoint: string;
|
||||||
await mutate(
|
switch (holderType) {
|
||||||
|
case 'category':
|
||||||
|
endpoint = `category/${(metadataHolder as ICategory).id}/meta`;
|
||||||
|
await requestManager.setCategoryMeta((metadataHolder as ICategory).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(manga.id, chapter.index, 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;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlToMutate = `${RequestManager.API_VERSION}${endpoint}`;
|
||||||
|
mutate(
|
||||||
urlToMutate,
|
urlToMutate,
|
||||||
{ ...metadataHolder, ...wrapMetadataWithMetaKey(wrapWithMetaKey, mutatedMetadata) },
|
{ ...metadataHolder, ...wrapMetadataWithMetaKey(holderType !== 'global', mutatedMetadata) },
|
||||||
{ revalidate: false },
|
{ revalidate: false },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const requestUpdateMetadata = async (
|
export const requestUpdateMetadata = async (
|
||||||
endpoint: string,
|
|
||||||
metadataHolder: MetadataHolder,
|
metadataHolder: MetadataHolder,
|
||||||
|
holderType: MetadataHolderType,
|
||||||
keysToValues: [AppMetadataKeys, AllowedMetadataValueTypes][],
|
keysToValues: [AppMetadataKeys, AllowedMetadataValueTypes][],
|
||||||
endpointToMutate?: string,
|
|
||||||
wrapWithMetaKey?: boolean,
|
|
||||||
): Promise<void[]> =>
|
): Promise<void[]> =>
|
||||||
Promise.all(
|
Promise.all(keysToValues.map(([key, value]) => requestUpdateMetadataValue(metadataHolder, holderType, key, value)));
|
||||||
keysToValues.map(([key, value]) =>
|
|
||||||
requestUpdateMetadataValue(endpoint, metadataHolder, key, value, endpointToMutate, wrapWithMetaKey),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const requestUpdateServerMetadata = async (
|
export const requestUpdateServerMetadata = async (
|
||||||
serverMetadata: Metadata,
|
serverMetadata: Metadata,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
keysToValues: MetadataKeyValuePair[],
|
||||||
): Promise<void[]> => requestUpdateMetadata('', { meta: serverMetadata }, keysToValues, '/meta', false);
|
): Promise<void[]> => requestUpdateMetadata({ meta: serverMetadata }, 'global', keysToValues);
|
||||||
|
|
||||||
export const requestUpdateMangaMetadata = async (
|
export const requestUpdateMangaMetadata = async (
|
||||||
manga: IMangaCard | IManga,
|
manga: IMangaCard | IManga,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
keysToValues: MetadataKeyValuePair[],
|
||||||
): Promise<void[]> => requestUpdateMetadata(`/manga/${manga.id}`, manga, keysToValues);
|
): Promise<void[]> => requestUpdateMetadata(manga, 'manga', keysToValues);
|
||||||
|
|
||||||
export const requestUpdateChapterMetadata = async (
|
export const requestUpdateChapterMetadata = async (
|
||||||
mangaChapter: IMangaChapter,
|
mangaChapter: IMangaChapter,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
keysToValues: MetadataKeyValuePair[],
|
||||||
): Promise<void[]> =>
|
): Promise<void[]> => requestUpdateMetadata(mangaChapter.chapter, 'chapter', keysToValues);
|
||||||
requestUpdateMetadata(
|
|
||||||
`/manga/${mangaChapter.manga.id}/chapter/${mangaChapter.chapter.index}`,
|
|
||||||
mangaChapter.chapter,
|
|
||||||
keysToValues,
|
|
||||||
);
|
|
||||||
|
|
||||||
export const requestUpdateCategoryMetadata = async (
|
export const requestUpdateCategoryMetadata = async (
|
||||||
category: ICategory,
|
category: ICategory,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
keysToValues: MetadataKeyValuePair[],
|
||||||
): Promise<void[]> => requestUpdateMetadata(`/category/${category.id}`, category, keysToValues);
|
): Promise<void[]> => requestUpdateMetadata(category, 'category', keysToValues);
|
||||||
|
|||||||
Reference in New Issue
Block a user