aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2023-11-05 17:53:07 -0800
committerFuwn <[email protected]>2023-11-05 17:53:07 -0800
commit914623a2fc0804fd74b72cbddbe0d44d07a9e4ce (patch)
tree4998f4e780e81afbf61e67079432490128676b33 /src
parentfeat(list): display title as compliment (diff)
downloaddue.moe-914623a2fc0804fd74b72cbddbe0d44d07a9e4ce.tar.xz
due.moe-914623a2fc0804fd74b72cbddbe0d44d07a9e4ce.zip
feat(manga): display out-of-date volumes
Diffstat (limited to 'src')
-rw-r--r--src/lib/AniList/media.ts16
-rw-r--r--src/lib/List/CleanMangaList.svelte9
-rw-r--r--src/lib/Media/chapters.ts3
-rw-r--r--src/lib/Media/manga.ts44
-rw-r--r--src/routes/api/mangadex/chapter/+server.ts13
5 files changed, 71 insertions, 14 deletions
diff --git a/src/lib/AniList/media.ts b/src/lib/AniList/media.ts
index e5deb272..55e3e453 100644
--- a/src/lib/AniList/media.ts
+++ b/src/lib/AniList/media.ts
@@ -16,6 +16,7 @@ export interface Media {
type: string;
episodes: number;
chapters: number;
+ volumes: number;
format: string;
title: {
romaji: string;
@@ -28,6 +29,7 @@ export interface Media {
};
mediaListEntry?: {
progress: number;
+ progressVolumes: number;
status: string;
score: number;
startedAt: {
@@ -123,15 +125,13 @@ export const mediaListCollection = async (
type === Type.Anime ? 'ANIME' : 'MANGA'
}${includeCompleted ? '' : ', status_not_in: [ COMPLETED ]'}) {
lists { entries { media {
- id
- status
- type
- episodes
- chapters
- format
- title { romaji english native }
+ id status type episodes chapters format
+ title { romaji english native }
nextAiringEpisode { episode timeUntilAiring }
- mediaListEntry { progress status score(format: POINT_100) startedAt { year } }
+ mediaListEntry {
+ progress progressVolumes status
+ score(format: POINT_100) startedAt { year }
+ }
startDate { year }
coverImage { extraLarge }
} } }
diff --git a/src/lib/List/CleanMangaList.svelte b/src/lib/List/CleanMangaList.svelte
index f85cc47b..a046ecc0 100644
--- a/src/lib/List/CleanMangaList.svelte
+++ b/src/lib/List/CleanMangaList.svelte
@@ -1,5 +1,6 @@
<script lang="ts">
import type { Media } from '$lib/AniList/media';
+ import { volumeCount } from '$lib/Media/manga';
import settings from '../../stores/settings';
import ListTitle from './ListTitle.svelte';
@@ -66,6 +67,14 @@
</a>
{#if due || manga.episodes !== manga.chapters}
[{manga.episodes || '?'}]
+ {#await volumeCount(manga) then volumes}
+ {@const volumeProgress = manga.mediaListEntry?.progressVolumes}
+ {#if volumes !== null && (volumeProgress || 0) < volumes}
+ <span style="color: lightcoral;">
+ Vol. {volumeProgress} &#8594; {volumes}
+ </span>
+ {/if}
+ {/await}
{/if}
</li>
{/each}
diff --git a/src/lib/Media/chapters.ts b/src/lib/Media/chapters.ts
index d580e6fa..a8a4d716 100644
--- a/src/lib/Media/chapters.ts
+++ b/src/lib/Media/chapters.ts
@@ -3,6 +3,7 @@ import Dexie, { type Table } from 'dexie';
export interface Chapter {
id: number;
chapters: number | null;
+ volumes: number | null;
}
export class ChapterDatabase extends Dexie {
@@ -11,7 +12,7 @@ export class ChapterDatabase extends Dexie {
constructor() {
super('chapterDatabase');
this.version(1).stores({
- chapters: 'id, chapters'
+ chapters: 'id, chapters, volumes'
});
this.chapters = this.table('chapters');
diff --git a/src/lib/Media/manga.ts b/src/lib/Media/manga.ts
index 3c0cf837..13f251eb 100644
--- a/src/lib/Media/manga.ts
+++ b/src/lib/Media/manga.ts
@@ -11,6 +11,9 @@ export const pruneAllManga = async () => {
await chapterDatabase.chapters.bulkDelete(ids);
};
+export const volumeCount = async (manga: Media): Promise<number | null> =>
+ (await chapterDatabase.chapters.get(manga.id))?.volumes as number | null;
+
export const chapterCount = async (
identity: UserIdentity,
manga: Media,
@@ -36,7 +39,8 @@ export const chapterCount = async (
await chapterDatabase.chapters.put({
id: manga.id,
- chapters: anilistData ? anilistData : -1
+ chapters: anilistData ? anilistData : -1,
+ volumes: null
});
return anilistData;
@@ -56,15 +60,15 @@ export const chapterCount = async (
return await tryRecentMediaActivities();
}
- const lastChapterData = await (
- await fetch(`/api/mangadex/feed?id=${mangadexData['data'][0]['id']}`)
- ).json();
+ const mangadexId = mangadexData['data'][0]['id'];
+ const lastChapterData = await (await fetch(`/api/mangadex/feed?id=${mangadexId}`)).json();
if (lastChapterData['data'] === undefined || lastChapterData['data'].length === 0) {
return await tryRecentMediaActivities();
}
let lastChapter = lastChapterData['data'][0]['attributes']['chapter'];
+ let completedVolumes = null;
if ((manga.mediaListEntry || { progress: 0 }).progress > lastChapter) {
const anilistData = await recentMediaActivities(identity, manga);
@@ -74,13 +78,43 @@ export const chapterCount = async (
}
}
+ const volumeOfChapterData = await (
+ await fetch(`/api/mangadex/chapter?id=${mangadexId}&chapter=${manga.mediaListEntry?.progress}`)
+ ).json();
+ let lastAvailableVolume = lastChapterData['data'][0]['attributes']['volume'];
+
+ if (lastAvailableVolume === null) {
+ let chapterIndex = 0;
+
+ while (chapterIndex < lastChapterData['data'].length && lastAvailableVolume === null) {
+ if (lastChapterData['data'][chapterIndex]['attributes']['volume'] !== null) {
+ lastAvailableVolume = lastChapterData['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;
+ }
+ }
+
if (lastChapter == 0) {
lastChapter = -1;
}
await chapterDatabase.chapters.put({
id: manga.id,
- chapters: Number(lastChapter)
+ chapters: Number(lastChapter),
+ volumes: completedVolumes
});
return Number(lastChapter);
diff --git a/src/routes/api/mangadex/chapter/+server.ts b/src/routes/api/mangadex/chapter/+server.ts
new file mode 100644
index 00000000..b4b1a11d
--- /dev/null
+++ b/src/routes/api/mangadex/chapter/+server.ts
@@ -0,0 +1,13 @@
+export const GET = async ({ url }) => {
+ return Response.json(
+ await (
+ await fetch(
+ `https://api.mangadex.org/chapter?manga=${url.searchParams.get(
+ 'id'
+ )}&chapter=${url.searchParams.get(
+ 'chapter'
+ )}&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic&limit=1`
+ )
+ ).json()
+ );
+};