aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-01-18 01:20:56 -0800
committerFuwn <[email protected]>2024-01-18 01:20:56 -0800
commit1bc31e433ae40848bd61ce6d9968312ef61186b8 (patch)
tree30a6e84867585bb9cbb9dd646e81e9fa314e713d /src/lib
parentfeat(time): show full date in title (diff)
downloaddue.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.svelte10
-rw-r--r--src/lib/Media/Anime/Airing/AiringTime.svelte142
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>