import type { Media } from "$lib/Data/AniList/media"; export interface AnimeEpisodeState { progress: number; nextEpisode: number; airedEpisodes: number; } const hasAired = (airingAt: number | undefined, nowEpochSeconds: number) => typeof airingAt === "number" && airingAt <= nowEpochSeconds; export const getAnimeEpisodeState = ( media: Media, nowEpochSeconds = Date.now() / 1000, ): AnimeEpisodeState => { const progress = media.mediaListEntry?.progress || 0; const nextEpisode = media.nextAiringEpisode?.nativeEpisode || media.nextAiringEpisode?.episode || 0; if (nextEpisode <= 0) { return { progress, nextEpisode, airedEpisodes: 0, }; } let airedEpisodes = Math.max(0, nextEpisode - 1); const airingAt = media.nextAiringEpisode?.airingAt; const nativeAiringAt = media.nextAiringEpisode?.nativeAiringAt; // If either source says the "next" episode already aired, treat it as released. if ( hasAired(airingAt, nowEpochSeconds) || hasAired(nativeAiringAt, nowEpochSeconds) ) airedEpisodes = Math.max(airedEpisodes, nextEpisode); return { progress, nextEpisode, airedEpisodes, }; }; export const hasDueEpisodes = ( media: Media, nowEpochSeconds = Date.now() / 1000, ) => { const episodeState = getAnimeEpisodeState(media, nowEpochSeconds); return episodeState.airedEpisodes > episodeState.progress; }; export const hasNoAiredEpisodes = ( media: Media, nowEpochSeconds = Date.now() / 1000, ) => { const episodeState = getAnimeEpisodeState(media, nowEpochSeconds); return episodeState.airedEpisodes <= 0; };