aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Media
diff options
context:
space:
mode:
authorFuwn <[email protected]>2023-12-16 18:50:51 -0800
committerFuwn <[email protected]>2023-12-16 18:50:51 -0800
commitb018bd62213b1a72114ecf47c6676204e33bd429 (patch)
tree8b8ece187917e99fc5591fe2f5fa271861e8b260 /src/lib/Media
parentfeat(api): subsplease endpoint (diff)
downloaddue.moe-b018bd62213b1a72114ecf47c6676204e33bd429.tar.xz
due.moe-b018bd62213b1a72114ecf47c6676204e33bd429.zip
feat(anime): subtitle countdown
Diffstat (limited to 'src/lib/Media')
-rw-r--r--src/lib/Media/anime.ts88
1 files changed, 86 insertions, 2 deletions
diff --git a/src/lib/Media/anime.ts b/src/lib/Media/anime.ts
index 927da31b..b9227562 100644
--- a/src/lib/Media/anime.ts
+++ b/src/lib/Media/anime.ts
@@ -5,6 +5,14 @@ import lastPruneTimes from '../../stores/lastPruneTimes';
import type { AniListAuthorisation, UserIdentity } from '../AniList/identity';
import settings from '../../stores/settings';
import type { MediaPrequel } from '$lib/AniList/prequels';
+import type { SubsPlease } from '$lib/subsPlease';
+import levenshtein from 'fast-levenshtein';
+
+interface Time {
+ title: string;
+ time: string;
+ day: string;
+}
export const cleanCache = (user: AniListAuthorisation, identity: UserIdentity) =>
mediaListCollection(user, identity, Type.Anime, get(anime), get(lastPruneTimes).anime, true);
@@ -16,9 +24,85 @@ export const updateMedia = (id: number, progress: number | undefined, callback:
export const totalEpisodes = (anime: Media) =>
anime.episodes === null ? '' : `<span style="opacity: 50%">/${anime.episodes}</span>`;
-export const airingTime = (anime: Media, upcoming = false) => {
+const secondsUntil = (targetTime: string, targetDay: string) => {
+ const now = new Date();
+ const [targetHour, targetMinute] = targetTime.split(':').map(Number);
+ let dayDifference =
+ ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'].indexOf(
+ targetDay
+ ) - now.getDay();
+
+ if (dayDifference < 0) dayDifference += 7;
+
+ const targetDate = new Date(now);
+
+ targetDate.setDate(now.getDate() + dayDifference);
+ targetDate.setHours(targetHour, targetMinute, 0, 0);
+
+ const secondsDifference = (Number(targetDate) - Number(now)) / 1000;
+
+ return secondsDifference > 0 ? secondsDifference : secondsDifference + 7 * 24 * 60 * 60;
+};
+
+const normalizeTitle = (title: string) =>
+ (title || '')
+ .toLowerCase()
+ .replace(/season \d+|s\d+/g, '')
+ .trim();
+
+const findClosestMatch = (times: Time[], titles: string[]) => {
+ let closestMatch = null;
+ let smallestDistance = Infinity;
+
+ titles.forEach((animeTitle) => {
+ const normalizedAnimeTitle = normalizeTitle(animeTitle);
+
+ times.forEach((item) => {
+ const normalizedItemTitle = normalizeTitle(item.title);
+ const distance = levenshtein.get(normalizedAnimeTitle, normalizedItemTitle);
+
+ if (distance < smallestDistance) {
+ smallestDistance = distance;
+ closestMatch = item;
+ }
+ });
+ });
+
+ return closestMatch;
+};
+
+export const airingTime = (anime: Media, subsPlease: SubsPlease, upcoming = false) => {
const airingAt = anime.nextAiringEpisode?.airingAt;
- const untilAiring = airingAt ? Math.round((airingAt - Date.now() / 1000) * 100) / 100 : undefined;
+ let untilAiring;
+
+ if (get(settings).displayNativeCountdown) {
+ untilAiring = airingAt ? Math.round((airingAt - Date.now() / 1000) * 100) / 100 : undefined;
+ } else {
+ const times: Time[] = [];
+
+ for (const [key, value] of Object.entries(subsPlease.schedule)) {
+ const flattenedValue = Array.isArray(value) ? value.flat() : [];
+
+ for (const time of flattenedValue) {
+ times.push({
+ title: time.title,
+ time: time.time,
+ day: key
+ });
+ }
+ }
+
+ const time: Time | null = findClosestMatch(times, [
+ anime.title.romaji,
+ anime.title.english,
+ ...anime.synonyms
+ ]);
+
+ if (time) untilAiring = secondsUntil((time as Time).time, (time as Time).day);
+ else
+ untilAiring = airingAt ? Math.round((airingAt - Date.now() / 1000) * 100) / 100 : undefined;
+ }
+
let timeFrame;
const time = new Date(airingAt ? airingAt * 1000 : 0).toLocaleTimeString([], {
hour12: !settings.get().display24HourTime,