aboutsummaryrefslogtreecommitdiff
path: root/src/lib/List/Anime/DueAnimeList.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/List/Anime/DueAnimeList.svelte')
-rw-r--r--src/lib/List/Anime/DueAnimeList.svelte281
1 files changed, 174 insertions, 107 deletions
diff --git a/src/lib/List/Anime/DueAnimeList.svelte b/src/lib/List/Anime/DueAnimeList.svelte
index 2db8da65..d2c47ebe 100644
--- a/src/lib/List/Anime/DueAnimeList.svelte
+++ b/src/lib/List/Anime/DueAnimeList.svelte
@@ -1,111 +1,178 @@
<script lang="ts">
- import { mediaListCollection, Type, type Media } from '$lib/Data/AniList/media';
- import type { AniListAuthorisation } from '$lib/Data/AniList/identity';
- import { onDestroy, onMount } from 'svelte';
- import anime from '$stores/anime';
- import settings from '$stores/settings';
- import lastPruneTimes from '$stores/lastPruneTimes';
- import AnimeList from './AnimeListTemplate.svelte';
- import type { SubsPlease } from '$lib/Media/Anime/Airing/Subtitled/subsPlease';
- import { injectAiringTime } from '$lib/Media/Anime/Airing/Subtitled/match';
- import { addNotification } from '$lib/Notification/store';
- import locale from '$stores/locale';
- import identity from '$stores/identity';
-
- export let user: AniListAuthorisation;
- let animeLists: Promise<Media[]>;
- let startTime: number;
- let endTime: number;
-
- const keyCacher = setInterval(
- () => {
- startTime = performance.now();
- endTime = -1;
- animeLists = mediaListCollection(user, $identity, Type.Anime, $anime, $lastPruneTimes.anime, {
- forcePrune: true,
- addNotification
- });
- },
- $settings.cacheMinutes * 1000 * 60
- );
-
- onMount(async () => {
- startTime = performance.now();
- animeLists = mediaListCollection(user, $identity, Type.Anime, $anime, $lastPruneTimes.anime, {
- addNotification
- });
- });
-
- onDestroy(() => clearInterval(keyCacher));
-
- const cleanMedia = (
- anime: Media[],
- displayUnresolved: boolean,
- subsPlease: SubsPlease | null
- ) => {
- if (anime === undefined) return [];
-
- let dueAnime = anime
- .map((media) => injectAiringTime(media, subsPlease))
- .filter(
- // Releasing media
- (media: Media) =>
- media.status === 'RELEASING' &&
- (media.mediaListEntry || { status: 'DROPPED' }).status !=
- ($settings.displayPausedMedia ? '' : 'PAUSED') &&
- (media.mediaListEntry || { progress: 0 }).progress >=
- ($settings.displayNotStarted === true ? 0 : 1) &&
- (media.mediaListEntry || { status: 'DROPPED' }).status !== 'DROPPED'
- )
- .filter(
- (media: Media) =>
- // Outdated media
- (media.nextAiringEpisode || { episode: 0 }).episode - 1 >
- (media.mediaListEntry || { progress: 0 }).progress
- )
- .map((media: Media) => {
- if ((media.nextAiringEpisode || { episode: 0 }).episode - 1 <= 0)
- media.nextAiringEpisode = { episode: -1 };
-
- return media;
- });
-
- if (!displayUnresolved)
- dueAnime = dueAnime.filter((media: Media) => media.nextAiringEpisode?.episode !== -1);
-
- dueAnime.sort((a: Media, b: Media) => {
- switch ($settings.displayAnimeSort) {
- case 'difference': {
- const difference = (anime: Media) =>
- (anime.nextAiringEpisode?.episode === -1
- ? 99999
- : anime.nextAiringEpisode?.episode || -1) -
- (anime.mediaListEntry || { progress: 0 }).progress;
-
- return difference(a) - difference(b);
- }
-
- case 'end_date':
- return (
- new Date(a.endDate.year, a.endDate.month - 1).getTime() -
- new Date(b.endDate.year, b.endDate.month - 1).getTime()
- );
-
- case 'start_date':
- return (
- new Date(a.startDate.year, a.startDate.month - 1).getTime() -
- new Date(b.startDate.year, b.startDate.month - 1).getTime()
- );
-
- case 'time_remaining':
- return (a.nextAiringEpisode?.airingAt || 9999) - (b.nextAiringEpisode?.airingAt || 9999);
- }
- });
-
- if (!endTime || endTime === -1) endTime = performance.now() - startTime;
-
- return dueAnime;
- };
+import { mediaListCollection, Type, type Media } from "$lib/Data/AniList/media";
+import { hydrateMediaListCache } from "$lib/Data/AniList/cacheHydration";
+import type { AniListAuthorisation } from "$lib/Data/AniList/identity";
+import { onDestroy, onMount } from "svelte";
+import anime from "$stores/anime";
+import settings from "$stores/settings";
+import lastPruneTimes from "$stores/lastPruneTimes";
+import AnimeList from "./AnimeListTemplate.svelte";
+import type { SubsPlease } from "$lib/Media/Anime/Airing/Subtitled/subsPlease";
+import { injectAiringTime } from "$lib/Media/Anime/Airing/Subtitled/match";
+import {
+ hasDueEpisodes,
+ hasNoAiredEpisodes,
+} from "$lib/Media/Anime/Airing/classify";
+import { addNotification } from "$lib/Notification/store";
+import locale from "$stores/locale";
+import identity from "$stores/identity";
+import revalidateAnime from "$stores/revalidateAnime";
+
+export let user: AniListAuthorisation;
+let animeLists: Promise<Media[]>;
+let startTime: number;
+let endTime: number;
+let keyCacher: ReturnType<typeof setInterval> | undefined;
+let keyCacheMinutes = -1;
+
+const restartKeyCacher = (cacheMinutes: number) => {
+ if (keyCacher) clearInterval(keyCacher);
+
+ keyCacheMinutes = cacheMinutes;
+ keyCacher = setInterval(
+ () => {
+ startTime = performance.now();
+ endTime = -1;
+ animeLists = mediaListCollection(
+ user,
+ $identity,
+ Type.Anime,
+ $anime,
+ $lastPruneTimes.anime,
+ {
+ forcePrune: true,
+ addNotification,
+ },
+ );
+ },
+ cacheMinutes * 1000 * 60,
+ );
+};
+
+onMount(async () => {
+ await hydrateMediaListCache("anime");
+ restartKeyCacher($settings.cacheMinutes);
+
+ startTime = performance.now();
+ animeLists = mediaListCollection(
+ user,
+ $identity,
+ Type.Anime,
+ $anime,
+ $lastPruneTimes.anime,
+ {
+ addNotification,
+ },
+ );
+});
+
+$: if (keyCacher && keyCacheMinutes !== $settings.cacheMinutes)
+ restartKeyCacher($settings.cacheMinutes);
+
+let lastAnimeRevalidation = 0;
+
+$: if ($revalidateAnime > lastAnimeRevalidation) {
+ lastAnimeRevalidation = $revalidateAnime;
+
+ startTime = performance.now();
+ endTime = -1;
+
+ animeLists = mediaListCollection(
+ user,
+ $identity,
+ Type.Anime,
+ $anime,
+ $lastPruneTimes.anime,
+ {
+ forcePrune: true,
+ addNotification,
+ },
+ );
+}
+
+onDestroy(() => {
+ if (keyCacher) clearInterval(keyCacher);
+});
+
+const cleanMedia = (
+ anime: Media[],
+ displayUnresolved: boolean,
+ subsPlease: SubsPlease | null,
+) => {
+ if (anime === undefined) return [];
+
+ let dueAnime = anime
+ .map((media) => injectAiringTime(media, subsPlease))
+ .filter(
+ // Releasing media
+ (media: Media) =>
+ media.status === "RELEASING" &&
+ (media.mediaListEntry || { status: "DROPPED" }).status !==
+ ($settings.displayPausedMedia ? "" : "PAUSED") &&
+ (media.mediaListEntry || { progress: 0 }).progress >=
+ ($settings.displayNotStarted === true ? 0 : 1) &&
+ (media.mediaListEntry || { status: "DROPPED" }).status !== "DROPPED",
+ )
+ .filter((media: Media) =>
+ // Outdated media
+ hasDueEpisodes(media),
+ )
+ .map((media: Media) =>
+ hasNoAiredEpisodes(media)
+ ? {
+ ...media,
+ nextAiringEpisode: {
+ ...(media.nextAiringEpisode || { episode: 0 }),
+ episode: -1,
+ },
+ }
+ : media,
+ );
+
+ if (!displayUnresolved)
+ dueAnime = dueAnime.filter(
+ (media: Media) => media.nextAiringEpisode?.episode !== -1,
+ );
+
+ dueAnime.sort((a: Media, b: Media) => {
+ switch ($settings.displayAnimeSort) {
+ case "difference": {
+ const difference = (anime: Media) =>
+ (anime.nextAiringEpisode?.episode === -1
+ ? 99999
+ : anime.nextAiringEpisode?.episode || -1) -
+ (anime.mediaListEntry || { progress: 0 }).progress;
+
+ return difference(a) - difference(b);
+ }
+
+ case "end_date":
+ return (
+ new Date(a.endDate.year, a.endDate.month - 1).getTime() -
+ new Date(b.endDate.year, b.endDate.month - 1).getTime()
+ );
+
+ case "start_date":
+ return (
+ new Date(a.startDate.year, a.startDate.month - 1).getTime() -
+ new Date(b.startDate.year, b.startDate.month - 1).getTime()
+ );
+
+ case "time_remaining":
+ return (
+ (a.nextAiringEpisode?.airingAt || 9999) -
+ (b.nextAiringEpisode?.airingAt || 9999)
+ );
+
+ default:
+ return 0;
+ }
+ });
+
+ if (!endTime || endTime === -1) endTime = performance.now() - startTime;
+
+ return dueAnime;
+};
</script>
<AnimeList {endTime} {cleanMedia} bind:animeLists {user} title={$locale().lists.due.episodes} />