diff options
Diffstat (limited to 'src/lib/List/Anime/DueAnimeList.svelte')
| -rw-r--r-- | src/lib/List/Anime/DueAnimeList.svelte | 281 |
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} /> |