improvement on my lists

This commit is contained in:
2025-12-07 02:48:56 +01:00
parent 1973069949
commit 220bbed16a
2 changed files with 109 additions and 64 deletions

View File

@@ -95,30 +95,43 @@ export async function getUserAniList(appUserId: number) {
anime: MediaListCollection(userId: $userId, type: ANIME) { anime: MediaListCollection(userId: $userId, type: ANIME) {
lists { lists {
entries { entries {
mediaId media {
id
title { romaji english userPreferred }
coverImage { extraLarge }
episodes
nextAiringEpisode { episode }
}
status status
progress progress
score score
startedAt { year month day }
completedAt { year month day }
repeat repeat
notes notes
private private
startedAt { year month day }
completedAt { year month day }
} }
} }
} }
manga: MediaListCollection(userId: $userId, type: MANGA) { manga: MediaListCollection(userId: $userId, type: MANGA) {
lists { lists {
entries { entries {
mediaId media {
id
title { romaji english userPreferred }
coverImage { extraLarge }
chapters
volumes
}
status status
progress progress
score score
startedAt { year month day }
completedAt { year month day }
repeat repeat
notes notes
private private
startedAt { year month day }
completedAt { year month day }
} }
} }
} }
@@ -138,15 +151,10 @@ export async function getUserAniList(appUserId: number) {
}), }),
}); });
if (!res.ok) { if (!res.ok) throw new Error(`AniList API error: ${res.status}`);
throw new Error(`AniList API error: ${res.status}`);
}
const json = await res.json(); const json = await res.json();
if (json?.errors?.length) throw new Error(json.errors[0].message);
if (json?.errors?.length) {
throw new Error(json.errors[0].message);
}
const fromFuzzy = (d: any) => { const fromFuzzy = (d: any) => {
if (!d?.year) return null; if (!d?.year) return null;
@@ -160,9 +168,24 @@ export async function getUserAniList(appUserId: number) {
for (const list of lists || []) { for (const list of lists || []) {
for (const entry of list.entries || []) { for (const entry of list.entries || []) {
const media = entry.media;
const totalEpisodes =
media?.episodes ||
(media?.nextAiringEpisode?.episode
? media.nextAiringEpisode.episode - 1
: 0);
const totalChapters =
media?.chapters ||
(media?.volumes ? media.volumes * 10 : 0);
result.push({ result.push({
user_id: appUserId, user_id: appUserId,
entry_id: entry.mediaId,
// ✅ FIX CLAVE
entry_id: media.id,
source: 'anilist', source: 'anilist',
entry_type: type, entry_type: type,
status: entry.status, status: entry.status,
@@ -172,7 +195,22 @@ export async function getUserAniList(appUserId: number) {
end_date: fromFuzzy(entry.completedAt), end_date: fromFuzzy(entry.completedAt),
repeat_count: entry.repeat || 0, repeat_count: entry.repeat || 0,
notes: entry.notes || null, notes: entry.notes || null,
is_private: entry.private ? 1 : 0 is_private: entry.private ? 1 : 0,
// ✅ CAMPOS QUE EL FRONTEND NECESITA
title: media?.title?.userPreferred
|| media?.title?.english
|| media?.title?.romaji
|| 'Unknown Title',
poster: media?.coverImage?.extraLarge
|| 'https://placehold.co/400x600?text=No+Cover',
total_episodes: type === 'ANIME' ? totalEpisodes : undefined,
total_chapters: type === 'MANGA' ? totalChapters : undefined,
// ✅ PARA ORDER BY EN EL FRONT
updated_at: new Date().toISOString()
}); });
} }
} }
@@ -184,6 +222,7 @@ export async function getUserAniList(appUserId: number) {
...normalize(json?.data?.anime?.lists, 'ANIME'), ...normalize(json?.data?.anime?.lists, 'ANIME'),
...normalize(json?.data?.manga?.lists, 'MANGA') ...normalize(json?.data?.manga?.lists, 'MANGA')
]; ];
} catch (error) { } catch (error) {
console.error('Error fetching AniList data:', error); console.error('Error fetching AniList data:', error);
return []; return [];

View File

@@ -117,14 +117,12 @@ export async function getUserList(userId: number): Promise<any> {
try { try {
const dbList = await queryAll(sql, [userId], USER_DB) as ListEntryData[]; const dbList = await queryAll(sql, [userId], USER_DB) as ListEntryData[];
const connected = await isConnected(userId); const connected = await isConnected(userId);
let finalList: ListEntryData[] = [...dbList]; let finalList: any[] = [...dbList];
if (connected) { if (connected) {
const anilistEntries = await aniListService.getUserAniList(userId); const anilistEntries = await aniListService.getUserAniList(userId);
const localWithoutAnilist = dbList.filter( const localWithoutAnilist = dbList.filter(
entry => entry.source !== 'anilist' entry => entry.source !== 'anilist'
); );
@@ -133,42 +131,46 @@ export async function getUserList(userId: number): Promise<any> {
} }
const enrichedListPromises = finalList.map(async (entry) => { const enrichedListPromises = finalList.map(async (entry) => {
// ✅ Si viene de AniList, ya está completo → NO fetch
if (entry.source === 'anilist') {
let finalTitle = entry.title;
if (typeof finalTitle === 'object' && finalTitle !== null) {
finalTitle =
finalTitle.userPreferred ||
finalTitle.english ||
finalTitle.romaji ||
'Unknown Title';
}
return {
...entry,
title: finalTitle,
poster: entry.poster || 'https://placehold.co/400x600?text=No+Cover',
};
}
// ✅ Solo se hace fetch para fuentes NO AniList
let contentDetails: any | null = null; let contentDetails: any | null = null;
const id = entry.entry_id; const id = entry.entry_id;
const source = entry.source;
const type = entry.entry_type; const type = entry.entry_type;
const ext = getExtension(entry.source);
try { try {
if (type === 'ANIME') { if (type === 'ANIME') {
let anime: any; const anime: any = await animeService.getAnimeInfoExtension(ext, id.toString());
if (source === 'anilist') {
anime = await animeService.getAnimeById(id);
} else {
const ext = getExtension(source);
anime = await animeService.getAnimeInfoExtension(ext, id.toString());
}
contentDetails = { contentDetails = {
title: anime?.title || 'Unknown Anime Title', title: anime?.title || 'Unknown Anime Title',
poster: anime?.coverImage?.extraLarge || anime?.image || '', poster: anime?.image || '',
total_episodes: anime?.episodes || anime?.nextAiringEpisode?.episode - 1 || 0, total_episodes: anime?.episodes || 0,
}; };
} else if (type === 'MANGA' || type === 'NOVEL') { } else if (type === 'MANGA' || type === 'NOVEL') {
let book: any; const book:any = await booksService.getBookInfoExtension(ext, id.toString());
if (source === 'anilist') {
book = await booksService.getBookById(id);
} else {
const ext = getExtension(source);
const result = await booksService.getBookInfoExtension(ext, id.toString());
book = result || null;
}
contentDetails = { contentDetails = {
title: book?.title || 'Unknown Book Title', title: book?.title || 'Unknown Book Title',
poster: book?.coverImage?.extraLarge || book?.image || '', poster: book?.image || '',
total_chapters: book?.chapters || book?.volumes * 10 || 0, total_chapters: book?.chapters || book?.volumes * 10 || 0,
}; };
} }
@@ -184,7 +186,11 @@ export async function getUserList(userId: number): Promise<any> {
let finalPoster = contentDetails?.poster || 'https://placehold.co/400x600?text=No+Cover'; let finalPoster = contentDetails?.poster || 'https://placehold.co/400x600?text=No+Cover';
if (typeof finalTitle === 'object' && finalTitle !== null) { if (typeof finalTitle === 'object' && finalTitle !== null) {
finalTitle = finalTitle.userPreferred || finalTitle.english || finalTitle.romaji || 'Unknown Title'; finalTitle =
finalTitle.userPreferred ||
finalTitle.english ||
finalTitle.romaji ||
'Unknown Title';
} }
return { return {