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 `on ${new Date( anime.startDate.year, (anime as unknown as MediaPrequel).startDate.month, (anime as unknown as MediaPrequel).startDate.day, ).toLocaleDateString()}`; 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 { const days = Math.round(Math.floor(hours / 24)); const residualHours = Math.floor(hours - days * 24); 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 { const residualMinutes = Math.round(minutes - Math.floor(hours) * 60); timeFrame += `${hours.toFixed(0)}${shortenCountdown ? "h" : " hour"}${ hours === 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 `${nextEpisode}${totalEpisodes( anime, )} in ${timeFrame} ${ few && get(settings).displayCoverModeAnime ? "
" : "" }${few ? `(${time})` : ""}
`; else return `${nextEpisode} in ${ few && get(settings).displayCoverModeAnime ? "
" : "" }${few ? "" : ""}${timeFrame}${few ? "" : ""} ${few ? `(${time})` : ""}
`; } return ""; };