mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-04 12:41:30 -07:00
Restore multi-copy digit capture and add AniList selection (#56)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { AnilistMediaGuess } from '../../core/services/anilist/anilist-updater';
|
||||
import { ANILIST_GRAPHQL_URL } from './constants';
|
||||
import type {
|
||||
AniListMediaCandidate,
|
||||
CharacterDictionaryRole,
|
||||
CharacterRecord,
|
||||
ResolvedAniListMedia,
|
||||
@@ -123,6 +124,30 @@ function pickAniListSearchResult(
|
||||
};
|
||||
}
|
||||
|
||||
function toAniListMediaCandidate(
|
||||
entry: {
|
||||
id: number;
|
||||
episodes?: number | null;
|
||||
title?: {
|
||||
romaji?: string | null;
|
||||
english?: string | null;
|
||||
native?: string | null;
|
||||
};
|
||||
},
|
||||
fallbackTitle: string,
|
||||
): AniListMediaCandidate {
|
||||
const normalizedFallback = fallbackTitle.trim() || `AniList ${entry.id}`;
|
||||
return {
|
||||
id: entry.id,
|
||||
title:
|
||||
entry.title?.english?.trim() ||
|
||||
entry.title?.romaji?.trim() ||
|
||||
entry.title?.native?.trim() ||
|
||||
normalizedFallback,
|
||||
episodes: typeof entry.episodes === 'number' && entry.episodes > 0 ? entry.episodes : null,
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchAniList<T>(
|
||||
query: string,
|
||||
variables: Record<string, unknown>,
|
||||
@@ -208,6 +233,69 @@ export async function resolveAniListMediaIdFromGuess(
|
||||
return resolved;
|
||||
}
|
||||
|
||||
export async function searchAniListMediaCandidates(
|
||||
title: string,
|
||||
beforeRequest?: () => Promise<void>,
|
||||
): Promise<AniListMediaCandidate[]> {
|
||||
const data = await fetchAniList<AniListSearchResponse>(
|
||||
`
|
||||
query($search: String!) {
|
||||
Page(perPage: 10) {
|
||||
media(search: $search, type: ANIME, sort: [SEARCH_MATCH, POPULARITY_DESC]) {
|
||||
id
|
||||
episodes
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ search: title },
|
||||
beforeRequest,
|
||||
);
|
||||
return (data.Page?.media ?? []).map((entry) => toAniListMediaCandidate(entry, title));
|
||||
}
|
||||
|
||||
export async function fetchAniListMediaCandidateById(
|
||||
mediaId: number,
|
||||
beforeRequest?: () => Promise<void>,
|
||||
): Promise<AniListMediaCandidate> {
|
||||
const data = await fetchAniList<{
|
||||
Media?: {
|
||||
id: number;
|
||||
episodes?: number | null;
|
||||
title?: {
|
||||
romaji?: string | null;
|
||||
english?: string | null;
|
||||
native?: string | null;
|
||||
};
|
||||
} | null;
|
||||
}>(
|
||||
`
|
||||
query($id: Int!) {
|
||||
Media(id: $id, type: ANIME) {
|
||||
id
|
||||
episodes
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ id: mediaId },
|
||||
beforeRequest,
|
||||
);
|
||||
if (!data.Media) {
|
||||
throw new Error(`AniList media ${mediaId} not found.`);
|
||||
}
|
||||
return toAniListMediaCandidate(data.Media, `AniList ${mediaId}`);
|
||||
}
|
||||
|
||||
export async function fetchCharactersForMedia(
|
||||
mediaId: number,
|
||||
beforeRequest?: () => Promise<void>,
|
||||
|
||||
Reference in New Issue
Block a user