aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Media
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-03-27 10:44:12 +0000
committerFuwn <[email protected]>2026-03-27 10:44:12 +0000
commit12bfed974c77a85c8fb520682aae9cfeecbdf5b8 (patch)
treed7cff80d7caa09f2a3d773577b61b5af539a554b /src/lib/Media
parentstyle(ci): format and tidy proxy files (diff)
downloaddue.moe-12bfed974c77a85c8fb520682aae9cfeecbdf5b8.tar.xz
due.moe-12bfed974c77a85c8fb520682aae9cfeecbdf5b8.zip
fix(proxy): improve native manga chapter counts
Diffstat (limited to 'src/lib/Media')
-rw-r--r--src/lib/Media/Manga/chapters.ts57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/lib/Media/Manga/chapters.ts b/src/lib/Media/Manga/chapters.ts
index 473a3ed4..04b147b0 100644
--- a/src/lib/Media/Manga/chapters.ts
+++ b/src/lib/Media/Manga/chapters.ts
@@ -1,6 +1,5 @@
import { env } from "$env/dynamic/public";
import { type Media, recentMediaActivities } from "$lib/Data/AniList/media";
-import { getChapterCount } from "$lib/Data/Manga/raw";
import { proxyRoute } from "$lib/Utility/proxy";
import settings from "$stores/settings";
import type { UserIdentity } from "../../Data/AniList/identity";
@@ -17,6 +16,14 @@ interface MangaDexChapterCountsResponse {
retryAfterMs?: number;
}
+interface NativeChapterCount {
+ chapter: number | null;
+}
+
+interface NativeChapterCountsResponse {
+ data?: Record<string, NativeChapterCount>;
+}
+
const chapterMemoryCache = new Map<number, number | null>();
const MAX_PENDING_RETRIES = 2;
const DEFAULT_PENDING_RETRY_MS = 750;
@@ -182,6 +189,36 @@ const fetchMangaChapterCounts = async (manga: Media[]) => {
return { data, rateLimited: rateLimited && !successfulResponse };
};
+const fetchNativeChapterCounts = async (manga: Media[]) => {
+ const data: Record<string, NativeChapterCount> = {};
+
+ for (let index = 0; index < manga.length; index += 100) {
+ const chunk = manga.slice(index, index + 100);
+ const response = await fetch(proxyRoute("/manga/native-chapter-counts"), {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ manga: chunk.map((entry) => ({
+ anilistId: entry.id,
+ nativeTitle: entry.title.native,
+ englishTitle: entry.title.english,
+ romajiTitle: entry.title.romaji,
+ })),
+ }),
+ }).catch(() => null);
+
+ if (!response?.ok) continue;
+
+ const payload = (await response.json()) as NativeChapterCountsResponse;
+
+ Object.assign(data, payload.data || {});
+ }
+
+ return data;
+};
+
export const hydrateChapterCounts = async (
identity: UserIdentity,
manga: Media[],
@@ -191,6 +228,7 @@ export const hydrateChapterCounts = async (
(entry, index, array) =>
array.findIndex((candidate) => candidate.id === entry.id) === index,
);
+ const nativeCountManga: Media[] = [];
const unresolvedManga: Media[] = [];
for (const entry of uniqueManga) {
@@ -203,12 +241,7 @@ export const hydrateChapterCounts = async (
}
if (settings.get().calculatePreferNativeChapterCount) {
- const nativeCount = (await getChapterCount(entry.title.native)) || 0;
-
- await writeCachedChapterCount(
- entry.id,
- nativeCount === 0 ? null : nativeCount,
- );
+ nativeCountManga.push(entry);
continue;
}
@@ -216,6 +249,16 @@ export const hydrateChapterCounts = async (
unresolvedManga.push(entry);
}
+ if (nativeCountManga.length) {
+ const nativeCounts = await fetchNativeChapterCounts(nativeCountManga);
+
+ for (const entry of nativeCountManga) {
+ const nativeCount = nativeCounts[String(entry.id)]?.chapter ?? null;
+
+ await writeCachedChapterCount(entry.id, nativeCount);
+ }
+ }
+
if (!unresolvedManga.length) return { rateLimited: false };
const { data, rateLimited } = await fetchMangaChapterCounts(unresolvedManga);