diff options
Diffstat (limited to 'src/lib/Media/Anime/Airing/classify.ts')
| -rw-r--r-- | src/lib/Media/Anime/Airing/classify.ts | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/lib/Media/Anime/Airing/classify.ts b/src/lib/Media/Anime/Airing/classify.ts new file mode 100644 index 00000000..9b7487d2 --- /dev/null +++ b/src/lib/Media/Anime/Airing/classify.ts @@ -0,0 +1,53 @@ +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; +}; |