aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Media/Anime/Airing/time.ts
blob: 7f0e896ae56d041e13a7535db91ab9cec453fe0f (plain) (blame)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import type { Media } from "$lib/Data/AniList/media";
import type { MediaPrequel } from "$lib/Data/AniList/prequels";
import type { SubsPlease } from "$lib/Media/Anime/Airing/Subtitled/subsPlease";
import settings from "$stores/settings";
import { injectAiringTime } from "./Subtitled/match";
import { totalEpisodes } from "../episodes";
import { get } from "svelte/store";

export const airingTime = (
	originalAnime: Media,
	subsPlease: SubsPlease | null,
	upcoming = false,
	forceDays = false,
) => {
	const anime = injectAiringTime(originalAnime, subsPlease);
	const airingAt = anime.nextAiringEpisode?.airingAt;
	const untilAiring = airingAt
		? Math.round((airingAt - Date.now() / 1000) * 100) / 100
		: undefined;
	const time = new Date(airingAt ? airingAt * 1000 : 0).toLocaleTimeString([], {
		hour12: !settings.get().display24HourTime,
		hour: "numeric",
		minute: "2-digit",
	});
	let timeFrame = "";
	let hours = null;
	const shortenCountdown = get(settings).displayShortCountdown;

	if (
		(anime as unknown as MediaPrequel).startDate &&
		new Date(
			anime.startDate.year,
			(anime as unknown as MediaPrequel).startDate.month,
			(anime as unknown as MediaPrequel).startDate.day,
		) < new Date()
	)
		return `<span class="opaque">on ${new Date(
			anime.startDate.year,
			(anime as unknown as MediaPrequel).startDate.month,
			(anime as unknown as MediaPrequel).startDate.day,
		).toLocaleDateString()}</span>`;

	if (untilAiring !== undefined) {
		let minutes = untilAiring / 60;
		let few = true;

		if (minutes > 60) {
			hours = minutes / 60;

			if (hours > 24) {
				let weeks = Math.floor(hours / 24) / 7;

				few = false;

				if (weeks >= 1.5 && !forceDays) {
					weeks = Math.round(weeks);

					timeFrame = `${weeks}${shortenCountdown ? "w" : " week"}${
						weeks === 1 || shortenCountdown ? "" : "s"
					}`;
				} else {
					let days = Math.floor(hours / 24);
					let residualHours = Math.round(hours - days * 24);

					if (residualHours === 24) {
						days += 1;
						residualHours = 0;
					}

					timeFrame += `${days.toFixed(0)}${shortenCountdown ? "d" : " day"}${
						days === 1 || shortenCountdown ? "" : "s"
					}`;

					if (residualHours > 0)
						timeFrame += `${shortenCountdown ? "" : " "}${residualHours}${
							shortenCountdown ? "h" : " hour"
						}${residualHours === 1 || shortenCountdown ? "" : "s"}`;
				}
			} else {
				let displayHours = Math.floor(hours);
				let residualMinutes = Math.round(minutes - displayHours * 60);

				if (residualMinutes === 60) {
					displayHours += 1;
					residualMinutes = 0;
				}

				timeFrame += `${displayHours}${shortenCountdown ? "h" : "  hour"}${
					displayHours === 1 || shortenCountdown ? "" : "s"
				}`;

				if (residualMinutes > 0)
					timeFrame += `${shortenCountdown ? "" : " "}${residualMinutes}${
						shortenCountdown ? "m" : " minute"
					}${residualMinutes === 1 || shortenCountdown ? "" : "s"}`;
			}
		} else {
			minutes = Math.round(minutes);

			timeFrame += `${minutes}${shortenCountdown ? "m" : "  minute"}${
				minutes === 1 || shortenCountdown ? "" : "s"
			}`;
		}

		const opacity = Math.max(50, 100 - (untilAiring / 60 / 60 / 24 / 7) * 50);
		const nextEpisode =
			anime.nextAiringEpisode?.nativeAiringAt &&
			!upcoming &&
			anime.nextAiringEpisode.nativeAiringAt <
				Date.now() / 1000 + 1 * 24 * 60 * 60
				? anime.nextAiringEpisode.episode - 1
				: anime.nextAiringEpisode?.episode || 0;
		const dateString =
			new Date(airingAt ? airingAt * 1000 : 0).toLocaleDateString([], {
				weekday: "long",
				year: "numeric",
				month: "long",
				day: "numeric",
			}) +
			" " +
			time;

		if (upcoming)
			return `<span title="${dateString}" style="opacity: ${opacity}%;">${nextEpisode}${totalEpisodes(
				anime,
			)} in ${timeFrame} <span class="opaque">${
				few && get(settings).displayCoverModeAnime ? "<br>" : ""
			}${few ? `(${time})` : ""}</span></span>`;
		else
			return `<span title="${dateString}" style="opacity: ${opacity}%;">${nextEpisode} in ${
				few && get(settings).displayCoverModeAnime ? "<br>" : ""
			}${few ? "<b>" : ""}${timeFrame}${few ? "</b>" : ""} ${few ? `(${time})` : ""}</span>`;
	}

	return "";
};