feat: add functionality to fetch all chapters from provider and update related hooks
This commit is contained in:
parent
6c8ed19be4
commit
f872d96b80
@ -24,6 +24,10 @@ import type {
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
import { customInstance } from './api';
|
||||
export interface UpdateMangaDataCommand {
|
||||
mangaId?: number;
|
||||
}
|
||||
|
||||
export interface DefaultResponseDTOVoid {
|
||||
timestamp?: string;
|
||||
data?: unknown;
|
||||
@ -105,18 +109,18 @@ export interface PageMangaListDTO {
|
||||
content?: MangaListDTO[];
|
||||
number?: number;
|
||||
pageable?: PageableObject;
|
||||
sort?: SortObject;
|
||||
first?: boolean;
|
||||
last?: boolean;
|
||||
sort?: SortObject;
|
||||
numberOfElements?: number;
|
||||
empty?: boolean;
|
||||
}
|
||||
|
||||
export interface PageableObject {
|
||||
offset?: number;
|
||||
paged?: boolean;
|
||||
pageNumber?: number;
|
||||
pageSize?: number;
|
||||
paged?: boolean;
|
||||
sort?: SortObject;
|
||||
unpaged?: boolean;
|
||||
}
|
||||
@ -268,6 +272,65 @@ type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
|
||||
|
||||
|
||||
|
||||
export const sendRecord = (
|
||||
updateMangaDataCommand: UpdateMangaDataCommand,
|
||||
options?: SecondParameter<typeof customInstance>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customInstance<string>(
|
||||
{url: `http://mangamochi.badger-pirarucu.ts.net:8080/records`, method: 'POST',
|
||||
headers: {'Content-Type': 'application/json', },
|
||||
data: updateMangaDataCommand, signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const getSendRecordMutationOptions = <TError = unknown,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof sendRecord>>, TError,{data: UpdateMangaDataCommand}, TContext>, request?: SecondParameter<typeof customInstance>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof sendRecord>>, TError,{data: UpdateMangaDataCommand}, TContext> => {
|
||||
|
||||
const mutationKey = ['sendRecord'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
|
||||
|
||||
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof sendRecord>>, {data: UpdateMangaDataCommand}> = (props) => {
|
||||
const {data} = props ?? {};
|
||||
|
||||
return sendRecord(data,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type SendRecordMutationResult = NonNullable<Awaited<ReturnType<typeof sendRecord>>>
|
||||
export type SendRecordMutationBody = UpdateMangaDataCommand
|
||||
export type SendRecordMutationError = unknown
|
||||
|
||||
export const useSendRecord = <TError = unknown,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof sendRecord>>, TError,{data: UpdateMangaDataCommand}, TContext>, request?: SecondParameter<typeof customInstance>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof sendRecord>>,
|
||||
TError,
|
||||
{data: UpdateMangaDataCommand},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
const mutationOptions = getSendRecordMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a list of manga chapters for a specific manga/provider combination.
|
||||
* @summary Fetch the available chapters for a specific manga/provider combination
|
||||
@ -332,6 +395,70 @@ export const useFetchMangaChapters = <TError = unknown,
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all not yet downloaded chapters from the provider
|
||||
* @summary Fetch all chapters
|
||||
*/
|
||||
export const fetchAllChapters = (
|
||||
mangaProviderId: number,
|
||||
options?: SecondParameter<typeof customInstance>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customInstance<DefaultResponseDTOVoid>(
|
||||
{url: `http://mangamochi.badger-pirarucu.ts.net:8080/mangas/${encodeURIComponent(String(mangaProviderId))}/fetch-all-chapters`, method: 'POST', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const getFetchAllChaptersMutationOptions = <TError = unknown,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof fetchAllChapters>>, TError,{mangaProviderId: number}, TContext>, request?: SecondParameter<typeof customInstance>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof fetchAllChapters>>, TError,{mangaProviderId: number}, TContext> => {
|
||||
|
||||
const mutationKey = ['fetchAllChapters'];
|
||||
const {mutation: mutationOptions, request: requestOptions} = options ?
|
||||
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
|
||||
options
|
||||
: {...options, mutation: {...options.mutation, mutationKey}}
|
||||
: {mutation: { mutationKey, }, request: undefined};
|
||||
|
||||
|
||||
|
||||
|
||||
const mutationFn: MutationFunction<Awaited<ReturnType<typeof fetchAllChapters>>, {mangaProviderId: number}> = (props) => {
|
||||
const {mangaProviderId} = props ?? {};
|
||||
|
||||
return fetchAllChapters(mangaProviderId,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type FetchAllChaptersMutationResult = NonNullable<Awaited<ReturnType<typeof fetchAllChapters>>>
|
||||
|
||||
export type FetchAllChaptersMutationError = unknown
|
||||
|
||||
/**
|
||||
* @summary Fetch all chapters
|
||||
*/
|
||||
export const useFetchAllChapters = <TError = unknown,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof fetchAllChapters>>, TError,{mangaProviderId: number}, TContext>, request?: SecondParameter<typeof customInstance>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof fetchAllChapters>>,
|
||||
TError,
|
||||
{mangaProviderId: number},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
const mutationOptions = getFetchAllChaptersMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a manga from favorites for the logged user.
|
||||
* @summary Unfavorite a manga
|
||||
|
||||
@ -20,9 +20,10 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { ThemeToggle } from "@/components/theme-toggle";
|
||||
import { useFetchMangaChapters, useGetManga } from "@/api/mangamochi";
|
||||
import {useFetchAllChapters, useFetchMangaChapters, useGetManga} from "@/api/mangamochi";
|
||||
import { MangaChapter } from "@/components/manga-chapter";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import {toast} from "sonner";
|
||||
|
||||
export default function MangaDetailPage() {
|
||||
const params = useParams();
|
||||
@ -33,12 +34,20 @@ export default function MangaDetailPage() {
|
||||
|
||||
const { data: mangaData, queryKey } = useGetManga(mangaId);
|
||||
|
||||
const { mutate, isPending } = useFetchMangaChapters({
|
||||
const { mutate, isPending: fetchPending } = useFetchMangaChapters({
|
||||
mutation: {
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey }),
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: fetchAllMutate, isPending: fetchAllPending } = useFetchAllChapters({
|
||||
mutation: {
|
||||
onSuccess: () => toast.success("Chapter import queued successfully.")
|
||||
}
|
||||
})
|
||||
|
||||
const isPending = fetchPending || fetchAllPending;
|
||||
|
||||
const [openProviders, setOpenProviders] = useState<Set<number>>(new Set());
|
||||
|
||||
if (!mangaData) {
|
||||
@ -258,7 +267,19 @@ export default function MangaDetailPage() {
|
||||
</div>
|
||||
</div>
|
||||
{provider.supportsChapterFetch && (
|
||||
<div className={"pr-4"}>
|
||||
<div className={"flex gap-4 pr-4"}>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
disabled={isPending}
|
||||
onClick={() =>
|
||||
fetchAllMutate({ mangaProviderId: provider.id })
|
||||
}
|
||||
className="gap-2"
|
||||
>
|
||||
<Database className="h-4 w-4" />
|
||||
Fetch all from Provider
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user