aboutsummaryrefslogtreecommitdiff
path: root/src/lib/List
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/List')
-rw-r--r--src/lib/List/Anime/rendering.test.ts96
-rw-r--r--src/lib/List/Anime/rendering.ts19
-rw-r--r--src/lib/List/CleanGrid.svelte5
3 files changed, 119 insertions, 1 deletions
diff --git a/src/lib/List/Anime/rendering.test.ts b/src/lib/List/Anime/rendering.test.ts
new file mode 100644
index 00000000..038e3729
--- /dev/null
+++ b/src/lib/List/Anime/rendering.test.ts
@@ -0,0 +1,96 @@
+import { describe, expect, it } from "vitest";
+import type { Media } from "$lib/Data/AniList/media";
+import { shouldRenderAnimeCover } from "$lib/List/Anime/rendering";
+
+const baseMedia = (id: number): Media =>
+ ({
+ id,
+ idMal: id,
+ status: "RELEASING",
+ type: "ANIME",
+ episodes: 12,
+ chapters: 0,
+ volumes: 0,
+ duration: 24,
+ format: "TV",
+ title: {
+ romaji: `Fixture Show ${id}`,
+ english: `Fixture Show ${id}`,
+ native: `Fixture Show ${id}`,
+ },
+ nextAiringEpisode: {
+ episode: 9,
+ nativeEpisode: 10,
+ airingAt: Math.floor(Date.now() / 1000) + 24 * 60 * 60,
+ nativeAiringAt: Math.floor(Date.now() / 1000) + 36 * 60 * 60,
+ },
+ synonyms: [],
+ mediaListEntry: {
+ progress: 8,
+ progressVolumes: 0,
+ status: "CURRENT",
+ score: 0,
+ repeat: 0,
+ startedAt: {
+ year: 2026,
+ month: 1,
+ day: 1,
+ },
+ completedAt: {
+ year: 0,
+ month: 0,
+ day: 0,
+ },
+ createdAt: 0,
+ updatedAt: 0,
+ customLists: {},
+ },
+ startDate: {
+ year: 2026,
+ month: 1,
+ },
+ endDate: {
+ year: 2026,
+ month: 12,
+ },
+ coverImage: {
+ extraLarge: "https://example.com/cover-xl.jpg",
+ medium: "https://example.com/cover-md.jpg",
+ },
+ tags: [],
+ genres: [],
+ season: "WINTER",
+ isAdult: false,
+ relations: {
+ edges: [],
+ },
+ }) as Media;
+
+describe("anime cover rendering", () => {
+ it("renders due media when nativeEpisode indicates user is behind", () => {
+ const media = baseMedia(194028);
+
+ expect(
+ shouldRenderAnimeCover(media, {
+ upcoming: false,
+ notYetReleased: false,
+ }),
+ ).toBe(true);
+ });
+
+ it("hides caught-up releasing media outside upcoming lists", () => {
+ const media = baseMedia(194028);
+
+ media.mediaListEntry = {
+ ...(media.mediaListEntry as NonNullable<typeof media.mediaListEntry>),
+ progress: 9,
+ };
+
+ expect(
+ shouldRenderAnimeCover(media, {
+ upcoming: false,
+ notYetReleased: false,
+ }),
+ ).toBe(false);
+ });
+});
diff --git a/src/lib/List/Anime/rendering.ts b/src/lib/List/Anime/rendering.ts
new file mode 100644
index 00000000..8a79d74c
--- /dev/null
+++ b/src/lib/List/Anime/rendering.ts
@@ -0,0 +1,19 @@
+import type { Media } from "$lib/Data/AniList/media";
+import { hasDueEpisodes } from "$lib/Media/Anime/Airing/classify";
+
+interface AnimeCoverRenderOptions {
+ upcoming: boolean;
+ notYetReleased: boolean;
+}
+
+export const shouldRenderAnimeCover = (
+ media: Media,
+ options: AnimeCoverRenderOptions,
+): boolean => {
+ const progress = media.mediaListEntry?.progress || 0;
+
+ if (options.upcoming || options.notYetReleased) return true;
+ if (media.status === "FINISHED") return progress !== media.episodes;
+
+ return hasDueEpisodes(media);
+};
diff --git a/src/lib/List/CleanGrid.svelte b/src/lib/List/CleanGrid.svelte
index 006a5e4e..384d4940 100644
--- a/src/lib/List/CleanGrid.svelte
+++ b/src/lib/List/CleanGrid.svelte
@@ -1,6 +1,7 @@
<script lang="ts">
import type { Media } from "$lib/Data/AniList/media";
import ParallaxImage from "$lib/Image/ParallaxImage.svelte";
+import { shouldRenderAnimeCover } from "$lib/List/Anime/rendering";
import { outboundLink } from "$lib/Media/links";
import LinkedTooltip from "$lib/Tooltip/LinkedTooltip.svelte";
import settings from "$stores/settings";
@@ -30,7 +31,9 @@ $: processedMedia =
{@const progress = (title.mediaListEntry || { progress: 0 }).progress}
{@const isAboveFold = index < 6}
- {#if type === 'anime' ? upcoming || notYetReleased || progress !== (title.nextAiringEpisode?.episode || 9999) - 1 : progress != title.episodes}
+ {#if type === 'anime'
+ ? shouldRenderAnimeCover(title, { upcoming, notYetReleased })
+ : progress != title.episodes}
<div class="cover-card" id={`${type}-${title.id}-${uniqueID}`}>
<LinkedTooltip
pin={`${type}-${title.id}-${uniqueID}`}