diff options
Diffstat (limited to 'src/lib/Media')
| -rw-r--r-- | src/lib/Media/Anime/Airing/AiringTime.svelte | 61 | ||||
| -rw-r--r-- | src/lib/Media/Anime/Airing/format.ts | 61 | ||||
| -rw-r--r-- | src/lib/Media/Anime/Airing/time.ts | 66 |
3 files changed, 67 insertions, 121 deletions
diff --git a/src/lib/Media/Anime/Airing/AiringTime.svelte b/src/lib/Media/Anime/Airing/AiringTime.svelte index 02e80d1f..6553c769 100644 --- a/src/lib/Media/Anime/Airing/AiringTime.svelte +++ b/src/lib/Media/Anime/Airing/AiringTime.svelte @@ -5,6 +5,7 @@ import type { MediaPrequel } from "$lib/Data/AniList/prequels"; import tooltip from "$lib/Tooltip/tooltip"; import locale from "$stores/locale"; import airingNow from "$stores/airingNow"; +import { formatCountdown } from "./format"; export let originalAnime: Media; export let upcoming = false; @@ -25,8 +26,6 @@ const setAiringTime = () => { const untilAiring = airingAt ? Math.round((airingAt - $airingNow / 1000) * 100) / 100 : undefined; - let hours = null; - const shortenCountdown = $settings.displayShortCountdown; time = new Date(airingAt ? airingAt * 1000 : 0).toLocaleTimeString([], { hour12: !$settings.display24HourTime, @@ -49,62 +48,10 @@ const setAiringTime = () => { ).toLocaleDateString()}</span>`; if (untilAiring !== undefined) { - let minutes = Math.round(untilAiring / 60); - - few = true; - - if (minutes > 60) { - hours = minutes / 60; - - if (hours > 24) { - const totalHours = Math.round(hours); - const days = Math.floor(totalHours / 24); - const residualHours = totalHours % 24; - const weeks = Math.floor(days / 7); - const residualDays = days % 7; - - few = false; - - if (weeks >= 1.5) { - timeFrame = `${weeks}${shortenCountdown ? "w" : " week"}${ - weeks === 1 || shortenCountdown ? "" : "s" - }`; - - if (residualDays > 0) - timeFrame += `${shortenCountdown ? "" : " "}${residualDays}${ - shortenCountdown ? "d" : " day" - }${residualDays === 1 || shortenCountdown ? "" : "s"}`; - } else { - timeFrame += `${days}${shortenCountdown ? "d" : " day"}${ - days === 1 || shortenCountdown ? "" : "s" - }`; - } - - if (residualHours > 0) - timeFrame += `${shortenCountdown ? "" : " "}${residualHours}${ - shortenCountdown ? "h" : " hour" - }${residualHours === 1 || shortenCountdown ? "" : "s"}`; - } else { - const displayHours = Math.floor(minutes / 60); - const residualMinutes = minutes % 60; - - 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 formatted = formatCountdown(untilAiring); + timeFrame = formatted.text; + few = formatted.few; opacity = Math.max(50, 100 - (untilAiring / 60 / 60 / 24 / 7) * 50); dateString = $locale().dateFormatter( new Date(airingAt ? airingAt * 1000 : 0), diff --git a/src/lib/Media/Anime/Airing/format.ts b/src/lib/Media/Anime/Airing/format.ts new file mode 100644 index 00000000..5fec3cc8 --- /dev/null +++ b/src/lib/Media/Anime/Airing/format.ts @@ -0,0 +1,61 @@ +import settings from "$stores/settings"; +import { get } from "svelte/store"; + +type Options = { + forceDays?: boolean; +}; + +type Result = { + text: string; + few: boolean; +}; + +const plural = (value: number, short: boolean, longUnit: string, shortUnit: string) => + `${value}${short ? shortUnit : ` ${longUnit}`}${value === 1 || short ? "" : "s"}`; + +export const formatCountdown = ( + secondsUntil: number, + options: Options = {}, +): Result => { + const short = get(settings).displayShortCountdown; + const minutes = Math.round(secondsUntil / 60); + + if (minutes <= 60) + return { text: plural(minutes, short, "minute", "m"), few: true }; + + const hours = minutes / 60; + + if (hours <= 24) { + const displayHours = Math.floor(minutes / 60); + const residualMinutes = minutes % 60; + + let text = plural(displayHours, short, "hour", "h"); + + if (residualMinutes > 0) + text += `${short ? "" : " "}${plural(residualMinutes, short, "minute", "m")}`; + + return { text, few: true }; + } + + const totalHours = Math.round(hours); + const days = Math.floor(totalHours / 24); + const residualHours = totalHours % 24; + const weeks = Math.floor(days / 7); + const residualDays = days % 7; + + let text: string; + + if (weeks >= 2 && !options.forceDays) { + text = plural(weeks, short, "week", "w"); + + if (residualDays > 0) + text += `${short ? "" : " "}${plural(residualDays, short, "day", "d")}`; + } else { + text = plural(days, short, "day", "d"); + } + + if (residualHours > 0) + text += `${short ? "" : " "}${plural(residualHours, short, "hour", "h")}`; + + return { text, few: false }; +}; diff --git a/src/lib/Media/Anime/Airing/time.ts b/src/lib/Media/Anime/Airing/time.ts index 7f0e896a..b7547dd2 100644 --- a/src/lib/Media/Anime/Airing/time.ts +++ b/src/lib/Media/Anime/Airing/time.ts @@ -2,6 +2,7 @@ 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 { formatCountdown } from "./format"; import { injectAiringTime } from "./Subtitled/match"; import { totalEpisodes } from "../episodes"; import { get } from "svelte/store"; @@ -22,9 +23,6 @@ export const airingTime = ( hour: "numeric", minute: "2-digit", }); - let timeFrame = ""; - let hours = null; - const shortenCountdown = get(settings).displayShortCountdown; if ( (anime as unknown as MediaPrequel).startDate && @@ -41,67 +39,7 @@ export const airingTime = ( ).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 { text: timeFrame, few } = formatCountdown(untilAiring, { forceDays }); const opacity = Math.max(50, 100 - (untilAiring / 60 / 60 / 24 / 7) * 50); const nextEpisode = anime.nextAiringEpisode?.nativeAiringAt && |