1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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;
};
|