continue watching/reading

This commit is contained in:
2025-12-07 17:24:49 +01:00
parent b2f6b489aa
commit 8fa40218e5
9 changed files with 367 additions and 11 deletions

View File

@@ -385,4 +385,156 @@ export async function getActiveAccessToken(userId: number): Promise<string | nul
export async function isConnected(userId: number): Promise<boolean> {
const token = await getActiveAccessToken(userId);
return !!token;
}
export async function getUserListByFilter(
userId: number,
status?: string,
entryType?: string
): Promise<any> {
let sql = `
SELECT * FROM ListEntry
WHERE user_id = ?
ORDER BY updated_at DESC;
`;
const params: any[] = [userId];
try {
const dbList = await queryAll(sql, params, USER_DB) as ListEntryData[];
const connected = await isConnected(userId);
const statusMap: any = {
watching: 'CURRENT',
reading: 'CURRENT',
completed: 'COMPLETED',
paused: 'PAUSED',
dropped: 'DROPPED',
planning: 'PLANNING'
};
const mappedStatus = status ? statusMap[status.toLowerCase()] : null;
let finalList: any[] = [];
// ✅ FILTRADO LOCAL (MANGA + NOVEL)
const filteredLocal = dbList.filter((entry) => {
if (mappedStatus && entry.status !== mappedStatus) return false;
if (entryType) {
if (entryType === 'MANGA') {
// ✅ AHORA ACEPTA MANGA Y NOVEL
if (!['MANGA', 'NOVEL'].includes(entry.entry_type)) return false;
} else {
if (entry.entry_type !== entryType) return false;
}
}
return true;
});
// ✅ FILTRADO ANILIST (MANGA + NOVEL TAMBIÉN)
let filteredAniList: any[] = [];
if (connected) {
const anilistEntries = await aniListService.getUserAniList(userId);
filteredAniList = anilistEntries.filter((entry: any) => {
if (mappedStatus && entry.status !== mappedStatus) return false;
if (entryType) {
if (entryType === 'MANGA') {
if (!['MANGA', 'NOVEL'].includes(entry.entry_type)) return false;
} else {
if (entry.entry_type !== entryType) return false;
}
}
return true;
});
}
finalList = [...filteredAniList, ...filteredLocal];
const enrichedListPromises = finalList.map(async (entry) => {
// ✅ AniList directo
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',
};
}
// ✅ LOCAL → FETCH EXTERNO
let contentDetails: any | null = null;
const id = entry.entry_id;
const type = entry.entry_type;
const ext = getExtension(entry.source);
try {
if (type === 'ANIME') {
const anime: any = await animeService.getAnimeInfoExtension(ext, id.toString());
contentDetails = {
title: anime?.title || 'Unknown Anime Title',
poster: anime?.image || '',
total_episodes: anime?.episodes || 0,
};
} else if (type === 'MANGA' || type === 'NOVEL') {
const book: any = await booksService.getBookInfoExtension(ext, id.toString());
contentDetails = {
title: book?.title || 'Unknown Book Title',
poster: book?.image || '',
total_chapters: book?.chapters || book?.volumes * 10 || 0,
};
}
} catch {
contentDetails = {
title: 'Error Loading Details',
poster: 'https://placehold.co/400x600?text=No+Cover',
};
}
let finalTitle = contentDetails?.title || 'Unknown Title';
let finalPoster = contentDetails?.poster || 'https://placehold.co/400x600?text=No+Cover';
if (typeof finalTitle === 'object' && finalTitle !== null) {
finalTitle =
finalTitle.userPreferred ||
finalTitle.english ||
finalTitle.romaji ||
'Unknown Title';
}
return {
...entry,
title: finalTitle,
poster: finalPoster,
total_episodes: contentDetails?.total_episodes,
total_chapters: contentDetails?.total_chapters,
};
});
return await Promise.all(enrichedListPromises);
} catch (error) {
console.error("Error al filtrar la lista del usuario:", error);
throw new Error("Error en la base de datos al obtener la lista filtrada.");
}
}