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 {
|
export interface ImportRequestDTO {
|
||||||
metadataId?: string;
|
metadataId?: string;
|
||||||
|
aniListId?: string;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,18 +115,18 @@ export interface PageMangaListDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PageableObject {
|
export interface PageableObject {
|
||||||
|
paged?: boolean;
|
||||||
pageNumber?: number;
|
pageNumber?: number;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
paged?: boolean;
|
unpaged?: boolean;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
sort?: SortObject;
|
sort?: SortObject;
|
||||||
unpaged?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SortObject {
|
export interface SortObject {
|
||||||
sorted?: boolean;
|
sorted?: boolean;
|
||||||
empty?: boolean;
|
|
||||||
unsorted?: boolean;
|
unsorted?: boolean;
|
||||||
|
empty?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DefaultResponseDTOListMangaChapterDTO {
|
export interface DefaultResponseDTOListMangaChapterDTO {
|
||||||
@ -134,12 +135,21 @@ export interface DefaultResponseDTOListMangaChapterDTO {
|
|||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LanguageDTO {
|
||||||
|
id: number;
|
||||||
|
/** @minLength 1 */
|
||||||
|
code: string;
|
||||||
|
/** @minLength 1 */
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MangaChapterDTO {
|
export interface MangaChapterDTO {
|
||||||
id: number;
|
id: number;
|
||||||
/** @minLength 1 */
|
/** @minLength 1 */
|
||||||
title: string;
|
title: string;
|
||||||
downloaded: boolean;
|
downloaded: boolean;
|
||||||
isRead: boolean;
|
isRead: boolean;
|
||||||
|
language?: LanguageDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DefaultResponseDTOMangaDTO {
|
export interface DefaultResponseDTOMangaDTO {
|
||||||
|
|||||||
@ -217,6 +217,69 @@ export const useUpdateMangaList = <TError = unknown,
|
|||||||
return useMutation(mutationOptions, queryClient);
|
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
|
* Sends a test notification to all users
|
||||||
* @summary Test notification
|
* @summary Test notification
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -45,6 +45,7 @@ export const ProviderImportDialog = ({
|
|||||||
value: z.string().min(1, "Please enter an ID or URL."),
|
value: z.string().min(1, "Please enter an ID or URL."),
|
||||||
providerId: z.string(),
|
providerId: z.string(),
|
||||||
myAnimeListId: z.string().optional(),
|
myAnimeListId: z.string().optional(),
|
||||||
|
anilistId: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
@ -53,6 +54,7 @@ export const ProviderImportDialog = ({
|
|||||||
value: "",
|
value: "",
|
||||||
providerId: "",
|
providerId: "",
|
||||||
myAnimeListId: undefined,
|
myAnimeListId: undefined,
|
||||||
|
anilistId: undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -74,7 +76,11 @@ export const ProviderImportDialog = ({
|
|||||||
(data: z.output<typeof formSchema>) => {
|
(data: z.output<typeof formSchema>) => {
|
||||||
importFromProvider({
|
importFromProvider({
|
||||||
providerId: Number(data.providerId),
|
providerId: Number(data.providerId),
|
||||||
data: { id: data.value, metadataId: data.myAnimeListId },
|
data: {
|
||||||
|
id: data.value,
|
||||||
|
metadataId: data.myAnimeListId,
|
||||||
|
aniListId: data.anilistId,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[importFromProvider],
|
[importFromProvider],
|
||||||
@ -145,27 +151,46 @@ export const ProviderImportDialog = ({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<FormField
|
<div className="flex w-full gap-4">
|
||||||
control={form.control}
|
<FormField
|
||||||
name="myAnimeListId"
|
control={form.control}
|
||||||
render={({ field }) => (
|
name="myAnimeListId"
|
||||||
<FormItem>
|
render={({ field }) => (
|
||||||
<FormLabel>MyAnimeList ID (Optional)</FormLabel>
|
<FormItem className="flex-1">
|
||||||
<FormControl>
|
<FormLabel>MyAnimeList ID (Optional)</FormLabel>
|
||||||
<Input
|
<FormControl>
|
||||||
placeholder="e.g., 13 (for One Piece)"
|
<Input
|
||||||
disabled={isPendingImportFromProvider}
|
placeholder="e.g., 13 (for One Piece)"
|
||||||
{...field}
|
disabled={isPendingImportFromProvider}
|
||||||
/>
|
{...field}
|
||||||
</FormControl>
|
/>
|
||||||
<FormDescription>
|
</FormControl>
|
||||||
Optionally link this manga to a MyAnimeList entry for better
|
<FormMessage />
|
||||||
precision on metadata fetching.
|
</FormItem>
|
||||||
</FormDescription>
|
)}
|
||||||
<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>
|
||||||
</Form>
|
</Form>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user