import { recentMediaActivities, type Media } from '$lib/Data/AniList/media'; import { getChapterCount } from '$lib/Data/Manga/raw'; import proxy from '$lib/Utility/proxy'; import settings from '$stores/settings'; import type { UserIdentity } from '../../Data/AniList/identity'; import { database } from '../../Database/IDB/chapters'; const getManga = async ( statusIn: string, year: number, native: string | null, english: string | null, romaji: string | null ) => { let status = ''; let error = false; switch (statusIn) { case 'FINISHED': { status = 'completed'; } break; case 'RELEASING': { status = 'ongoing'; } break; case 'HIATUS': { status = 'hiatus'; } break; case 'CANCELLED': { status = 'cancelled'; } break; } const nullIfNullString = (s: string | null) => (s == 'null' ? null : s); const get = async (title: string) => { try { return await ( await fetch( proxy( `https://api.mangadex.org/manga?title=${encodeURIComponent( title )}&year=${year}&status[]=${status}` ) ) ).json(); } catch { error = true; } }; let mangadexData = await get( nullIfNullString(native) || nullIfNullString(english) || nullIfNullString(romaji) || '' ); if (error) return new Response('rate-limited'); if (mangadexData['data'] === undefined || mangadexData['data'].length === 0) { mangadexData = await get(nullIfNullString(english) || ''); if (mangadexData['data'] === undefined || mangadexData['data'].length === 0) { mangadexData = await get(nullIfNullString(romaji) || ''); } } return Response.json(mangadexData, { headers: { 'Cache-Control': 'max-age=300' } }); }; export const chapterCount = async ( identity: UserIdentity, manga: Media, disableGuessing: boolean // preferActivity = false ): Promise => { const chapters = await database.chapters.get(manga.id); if (chapters !== undefined) return chapters.chapters === -1 ? null : chapters.chapters; // if (preferActivity) { // return await recentMediaActivities(identity, manga); // } const tryRecentMediaActivities = async () => { if (disableGuessing) { await database.chapters.put({ id: manga.id, chapters: -1, volumes: null }); return null; } const anilistData = await recentMediaActivities( identity, manga, settings.get().calculateGuessMethod ); await database.chapters.put({ id: manga.id, chapters: anilistData ? anilistData : -1, volumes: null }); return anilistData; }; if (manga.format === 'NOVEL') return await tryRecentMediaActivities(); let lastChapter = 0; let completedVolumes = null; if (!settings.get().calculatePreferNativeChapterCount) { const mangadexData = await getManga( manga.status, manga.startDate.year, manga.title.native, manga.title.english, manga.title.romaji ); if ((await mangadexData.clone().text()) === 'rate-limited') return -22; const mangadexDataJson = await mangadexData.json(); if (mangadexDataJson['data'] === undefined || mangadexDataJson['data'].length === 0) return await tryRecentMediaActivities(); const mangadexId = mangadexDataJson['data'][0]['id']; const lastChapterDataJson = await ( await fetch( proxy( `https://api.mangadex.org/manga/${mangadexId}/feed?order[chapter]=desc&translatedLanguage[]=en&limit=1&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic` ) ) ).json(); if (lastChapterDataJson['data'] === undefined || lastChapterDataJson['data'].length === 0) return await tryRecentMediaActivities(); lastChapter = lastChapterDataJson['data'][0]['attributes']['chapter']; completedVolumes = null; if ((manga.mediaListEntry || { progress: 0 }).progress > lastChapter && !disableGuessing) { const anilistData = await recentMediaActivities( identity, manga, settings.get().calculateGuessMethod ); if (anilistData !== null && anilistData > lastChapter) lastChapter = anilistData; } if (!settings.get().calculateDisableOutOfDateVolumeWarning) { const volumeOfChapterData = await ( await fetch( proxy( `https://api.mangadex.org/chapter?manga=${mangadexId}&chapter=${manga.mediaListEntry?.progress}&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic&limit=1` ) ) ).json(); let lastAvailableVolume = lastChapterDataJson['data'][0]['attributes']['volume']; if (lastAvailableVolume === null) { let chapterIndex = 0; while (chapterIndex < lastChapterDataJson['data'].length && lastAvailableVolume === null) { if (lastChapterDataJson['data'][chapterIndex]['attributes']['volume'] !== null) lastAvailableVolume = lastChapterDataJson['data'][chapterIndex]['attributes']['volume']; chapterIndex += 1; } } if (volumeOfChapterData['data'] !== undefined && volumeOfChapterData['data'].length > 0) { const volumeOfChapter = volumeOfChapterData['data'][0]['attributes']['volume']; if (volumeOfChapter !== null) completedVolumes = volumeOfChapter; if (completedVolumes === volumeOfChapter) completedVolumes -= 1; } } } else { lastChapter = (await getChapterCount(manga.title.native)) || 0; } if (lastChapter == 0) lastChapter = -1; await database.chapters.put({ id: manga.id, chapters: Number(lastChapter), volumes: completedVolumes }); return Number(lastChapter); };