feat: Add AniList ID support for manga imports, introduce manga data update API, and include chapter language.
This commit is contained in:
parent
8b27e56758
commit
9f0eeab4fb
@ -12,6 +12,7 @@ export interface DefaultResponseDTOVoid {
|
||||
|
||||
export interface ImportRequestDTO {
|
||||
metadataId?: string;
|
||||
aniListId?: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
@ -114,18 +115,18 @@ export interface PageMangaListDTO {
|
||||
}
|
||||
|
||||
export interface PageableObject {
|
||||
paged?: boolean;
|
||||
pageNumber?: number;
|
||||
pageSize?: number;
|
||||
paged?: boolean;
|
||||
unpaged?: boolean;
|
||||
offset?: number;
|
||||
sort?: SortObject;
|
||||
unpaged?: boolean;
|
||||
}
|
||||
|
||||
export interface SortObject {
|
||||
sorted?: boolean;
|
||||
empty?: boolean;
|
||||
unsorted?: boolean;
|
||||
empty?: boolean;
|
||||
}
|
||||
|
||||
export interface DefaultResponseDTOListMangaChapterDTO {
|
||||
@ -134,12 +135,21 @@ export interface DefaultResponseDTOListMangaChapterDTO {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface LanguageDTO {
|
||||
id: number;
|
||||
/** @minLength 1 */
|
||||
code: string;
|
||||
/** @minLength 1 */
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface MangaChapterDTO {
|
||||
id: number;
|
||||
/** @minLength 1 */
|
||||
title: string;
|
||||
downloaded: boolean;
|
||||
isRead: boolean;
|
||||
language?: LanguageDTO;
|
||||
}
|
||||
|
||||
export interface DefaultResponseDTOMangaDTO {
|
||||
|
||||
@ -217,6 +217,69 @@ export const useUpdateMangaList = <TError = unknown,
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* Triggers the update of the metadata for a manga by its ID
|
||||
* @summary Trigger manga data update
|
||||
*/
|
||||
export const triggerUpdateMangaData = (
|
||||
mangaId: number,
|
||||
options?: SecondParameter<typeof customInstance>,signal?: AbortSignal
|
||||
) => {
|
||||
|
||||
|
||||
return customInstance<DefaultResponseDTOVoid>(
|
||||
{url: `/management/update-manga-data/${encodeURIComponent(String(mangaId))}`, method: 'POST', signal
|
||||
},
|
||||
options);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const getTriggerUpdateMangaDataMutationOptions = <TError = unknown,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof triggerUpdateMangaData>>, TError,{mangaId: number}, TContext>, request?: SecondParameter<typeof customInstance>}
|
||||
): UseMutationOptions<Awaited<ReturnType<typeof triggerUpdateMangaData>>, TError,{mangaId: number}, TContext> => {
|
||||
|
||||
const mutationKey = ['triggerUpdateMangaData'];
|
||||
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 triggerUpdateMangaData>>, {mangaId: number}> = (props) => {
|
||||
const {mangaId} = props ?? {};
|
||||
|
||||
return triggerUpdateMangaData(mangaId,requestOptions)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return { mutationFn, ...mutationOptions }}
|
||||
|
||||
export type TriggerUpdateMangaDataMutationResult = NonNullable<Awaited<ReturnType<typeof triggerUpdateMangaData>>>
|
||||
|
||||
export type TriggerUpdateMangaDataMutationError = unknown
|
||||
|
||||
/**
|
||||
* @summary Trigger manga data update
|
||||
*/
|
||||
export const useTriggerUpdateMangaData = <TError = unknown,
|
||||
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof triggerUpdateMangaData>>, TError,{mangaId: number}, TContext>, request?: SecondParameter<typeof customInstance>}
|
||||
, queryClient?: QueryClient): UseMutationResult<
|
||||
Awaited<ReturnType<typeof triggerUpdateMangaData>>,
|
||||
TError,
|
||||
{mangaId: number},
|
||||
TContext
|
||||
> => {
|
||||
|
||||
const mutationOptions = getTriggerUpdateMangaDataMutationOptions(options);
|
||||
|
||||
return useMutation(mutationOptions, queryClient);
|
||||
}
|
||||
/**
|
||||
* Sends a test notification to all users
|
||||
* @summary Test notification
|
||||
*/
|
||||
|
||||
@ -45,6 +45,7 @@ export const ProviderImportDialog = ({
|
||||
value: z.string().min(1, "Please enter an ID or URL."),
|
||||
providerId: z.string(),
|
||||
myAnimeListId: z.string().optional(),
|
||||
anilistId: z.string().optional(),
|
||||
});
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
@ -53,6 +54,7 @@ export const ProviderImportDialog = ({
|
||||
value: "",
|
||||
providerId: "",
|
||||
myAnimeListId: undefined,
|
||||
anilistId: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
@ -74,7 +76,11 @@ export const ProviderImportDialog = ({
|
||||
(data: z.output<typeof formSchema>) => {
|
||||
importFromProvider({
|
||||
providerId: Number(data.providerId),
|
||||
data: { id: data.value, metadataId: data.myAnimeListId },
|
||||
data: {
|
||||
id: data.value,
|
||||
metadataId: data.myAnimeListId,
|
||||
aniListId: data.anilistId,
|
||||
},
|
||||
});
|
||||
},
|
||||
[importFromProvider],
|
||||
@ -145,27 +151,46 @@ export const ProviderImportDialog = ({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="myAnimeListId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>MyAnimeList ID (Optional)</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="e.g., 13 (for One Piece)"
|
||||
disabled={isPendingImportFromProvider}
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
Optionally link this manga to a MyAnimeList entry for better
|
||||
precision on metadata fetching.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<div className="flex w-full gap-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="myAnimeListId"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>MyAnimeList ID (Optional)</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="e.g., 13 (for One Piece)"
|
||||
disabled={isPendingImportFromProvider}
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="anilistId"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>AniList ID (Optional)</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="e.g., 21 (for One Piece)"
|
||||
disabled={isPendingImportFromProvider}
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<FormDescription>
|
||||
Optionally link this manga to a MyAnimeList or AniList entry for
|
||||
better precision on metadata fetching.
|
||||
</FormDescription>
|
||||
</form>
|
||||
</Form>
|
||||
<DialogFooter>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user