diff options
| author | Fuwn <[email protected]> | 2024-01-18 01:20:56 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-01-18 01:20:56 -0800 |
| commit | 1bc31e433ae40848bd61ce6d9968312ef61186b8 (patch) | |
| tree | 30a6e84867585bb9cbb9dd646e81e9fa314e713d /src/lib | |
| parent | feat(time): show full date in title (diff) | |
| download | due.moe-1bc31e433ae40848bd61ce6d9968312ef61186b8.tar.xz due.moe-1bc31e433ae40848bd61ce6d9968312ef61186b8.zip | |
refactor(anime): airingTime as component
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/List/Anime/CleanAnimeList.svelte | 10 | ||||
| -rw-r--r-- | src/lib/Media/Anime/Airing/AiringTime.svelte | 142 |
2 files changed, 147 insertions, 5 deletions
diff --git a/src/lib/List/Anime/CleanAnimeList.svelte b/src/lib/List/Anime/CleanAnimeList.svelte index a8804a72..c4c4312f 100644 --- a/src/lib/List/Anime/CleanAnimeList.svelte +++ b/src/lib/List/Anime/CleanAnimeList.svelte @@ -5,7 +5,6 @@ import type { Media } from '$lib/AniList/media'; import { cleanCache, incrementMediaProgress } from '$lib/Media/Anime/cache'; import { totalEpisodes } from '$lib/Media/Anime/episodes'; - import { airingTime } from '$lib/Media/Anime/Airing/time'; import type { AniListAuthorisation, UserIdentity } from '$lib/AniList/identity'; import ListTitle from '../ListTitle.svelte'; import MediaTitle from '../MediaTitleDisplay.svelte'; @@ -21,6 +20,7 @@ } from '$lib/Media/Cover/hoverCover'; import { mediaTitle } from '../mediaTitle'; import tooltip from '$lib/Tooltip/tooltip'; + import AiringTime from '$lib/Media/Anime/Airing/AiringTime.svelte'; export let media: Media[]; export let title: string; @@ -117,10 +117,10 @@ ? 2 : 1)}] <br /> - {@html airingTime(anime, subsPlease)} + <AiringTime originalAnime={anime} {subsPlease} /> {/if} {:else} - {@html airingTime(anime, subsPlease, true)} + <AiringTime originalAnime={anime} {subsPlease} upcoming={true} /> {/if} </div> </div> @@ -204,12 +204,12 @@ ? 2 : 1)}] <span class:countdown={$settings.displayCountdownRightAligned}> - {@html airingTime(anime, subsPlease)} + <AiringTime originalAnime={anime} {subsPlease} /> </span> {/if} {:else} <span class:countdown={$settings.displayCountdownRightAligned}> - {@html airingTime(anime, subsPlease, true)} + <AiringTime originalAnime={anime} {subsPlease} upcoming={true} /> </span> {/if} </span> diff --git a/src/lib/Media/Anime/Airing/AiringTime.svelte b/src/lib/Media/Anime/Airing/AiringTime.svelte new file mode 100644 index 00000000..373478f8 --- /dev/null +++ b/src/lib/Media/Anime/Airing/AiringTime.svelte @@ -0,0 +1,142 @@ +<script lang="ts"> + import type { Media } from '$lib/AniList/media'; + import settings from '$stores/settings'; + import { onMount } from 'svelte'; + import type { SubsPlease } from './Subtitled/subsPlease'; + import type { MediaPrequel } from '$lib/AniList/prequels'; + import { injectAiringTime } from './Subtitled/match'; + + export let originalAnime: Media; + export let subsPlease: SubsPlease | null; + export let upcoming = false; + + const anime = injectAiringTime(originalAnime, subsPlease); + let opacity = 100; + let timeFrame = ''; + let time = ''; + let nextEpisode = 0; + let few = true; + let dateString = ''; + + onMount(() => { + const airingAt = anime.nextAiringEpisode?.airingAt; + const untilAiring = airingAt + ? Math.round((airingAt - Date.now() / 1000) * 100) / 100 + : undefined; + let hours = null; + const shortenCountdown = $settings.displayShortCountdown; + + time = new Date(airingAt ? airingAt * 1000 : 0).toLocaleTimeString([], { + hour12: !$settings.display24HourTime, + hour: 'numeric', + minute: '2-digit' + }); + + 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 style="opacity: 50%">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; + + few = true; + + if (minutes > 60) { + hours = minutes / 60; + + if (hours > 24) { + let weeks = Math.floor(hours / 24) / 7; + + few = false; + + if (weeks >= 1.5) { + 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' + }`; + } + + opacity = Math.max(50, 100 - (untilAiring / 60 / 60 / 24 / 7) * 50); + nextEpisode = + anime.nextAiringEpisode?.nativeAiringAt && + !upcoming && + anime.nextAiringEpisode.nativeAiringAt < Date.now() / 1000 + 1 * 24 * 60 * 60 + ? anime.nextAiringEpisode.episode - 1 + : anime.nextAiringEpisode?.episode || 0; + dateString = + new Date(airingAt ? airingAt * 1000 : 0).toLocaleDateString([], { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }) + + ' ' + + time; + } + }); +</script> + +{#if upcoming} + <span title={dateString} style={`opacity: ${opacity}%;`}> + {nextEpisode}{#if anime.episodes !== null}<span class="hint">/{anime.episodes}</span> + {/if} in {timeFrame} + <span class="hint"> + {#if few && $settings.displayCoverMode}<br />{/if}{few ? `(${time})` : ''} + </span> + </span> +{:else} + <span title={dateString} style={`opacity: ${opacity}%;`}> + {nextEpisode} in {#if few && $settings.displayCoverMode}<br />{/if}{#if few}<b> + {timeFrame} + </b>{:else}{timeFrame}{/if} + {few ? `(${time})` : ''} + </span> +{/if} + +<style> + .hint { + opacity: 50%; + } +</style> |