From aa8d7df0b39980d804afa7d764561c69476e0455 Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.me>
Date: Wed, 10 Jan 2024 02:26:18 -0800
Subject: feat(wrapped): show previous ongoing media

---
 src/lib/Tools/Wrapped.svelte | 143 +++++++++++++++++++++++++++++++++----------
 1 file changed, 110 insertions(+), 33 deletions(-)

(limited to 'src/lib/Tools/Wrapped.svelte')

diff --git a/src/lib/Tools/Wrapped.svelte b/src/lib/Tools/Wrapped.svelte
index 9605b189..ab17113d 100644
--- a/src/lib/Tools/Wrapped.svelte
+++ b/src/lib/Tools/Wrapped.svelte
@@ -45,6 +45,8 @@
 	let minutesWatched = 0;
 	let animeList: Media[] | undefined = undefined;
 	let mangaList: Media[] | undefined = undefined;
+	let calculatedAnimeList: Media[] | undefined = undefined;
+	let calculatedMangaList: Media[] | undefined = undefined;
 	let originalAnimeList: Media[] | undefined = undefined;
 	let originalMangaList: Media[] | undefined = undefined;
 	let transparency = false;
@@ -72,6 +74,7 @@
 	let includeMovies = true;
 	let includeOVAs = true;
 	let activityHistoryPosition: 'TOP' | 'BELOW_TOP' | 'ORIGINAL' = 'ORIGINAL';
+	let includeOngoingMediaFromPreviousYears = false;
 
 	$: {
 		if (browser && mounted) {
@@ -114,6 +117,7 @@
 		includeMovies = includeMovies;
 		includeOVAs = includeOVAs;
 		selectedYear = selectedYear;
+		includeOngoingMediaFromPreviousYears = includeOngoingMediaFromPreviousYears;
 
 		update().then(updateWidth).catch(updateWidth);
 	}
@@ -281,20 +285,19 @@
 	const update = async () => {
 		if (currentUserIdentity.id === -1) return;
 
-		animeList = (
-			await mediaListCollection(
-				user,
-				currentUserIdentity,
-				Type.Anime,
-				$anime,
-				$lastPruneTimes.anime,
-				{
-					forcePrune: true,
-					includeCompleted: true,
-					all: true
-				}
-			)
-		)
+		let rawAnimeList = await mediaListCollection(
+			user,
+			currentUserIdentity,
+			Type.Anime,
+			$anime,
+			$lastPruneTimes.anime,
+			{
+				forcePrune: true,
+				includeCompleted: true,
+				all: true
+			}
+		);
+		calculatedAnimeList = rawAnimeList
 			.filter(
 				(item, index, self) =>
 					self.findIndex((itemToCompare) => itemToCompare.id === item.id) === index &&
@@ -332,20 +335,85 @@
 						else return b.mediaListEntry?.score - a.mediaListEntry?.score;
 				}
 			});
-		mangaList = (
-			await mediaListCollection(
-				user,
-				currentUserIdentity,
-				Type.Manga,
-				$manga,
-				$lastPruneTimes.manga,
-				{
-					forcePrune: true,
-					includeCompleted: true,
-					all: true
+
+		animeList = rawAnimeList
+			.filter(
+				(item, index, self) =>
+					self.findIndex((itemToCompare) => itemToCompare.id === item.id) === index &&
+					(includeMusic ? true : item.format !== 'MUSIC') &&
+					(includeRepeats
+						? true
+						: item.startDate.year === selectedYear || item.endDate.year === selectedYear
+						? true
+						: item.mediaListEntry?.repeat === 0) &&
+					(item.mediaListEntry?.startedAt.year === selectedYear ||
+						item.mediaListEntry?.completedAt.year === selectedYear ||
+						((item.mediaListEntry?.createdAt
+							? new Date(item.mediaListEntry?.createdAt * 1000).getFullYear() === selectedYear
+							: false) && item.mediaListEntry
+							? item.mediaListEntry?.progress >= 1
+							: false) ||
+						(includeOngoingMediaFromPreviousYears
+							? (item.mediaListEntry?.updatedAt
+									? new Date(item.mediaListEntry?.updatedAt * 1000).getFullYear() === selectedYear
+									: false) && item.mediaListEntry
+								? item.mediaListEntry?.status === 'CURRENT'
+								: false
+							: false)) &&
+					(includeMovies ? true : item.format !== 'MOVIE') &&
+					(includeSpecials ? true : item.format !== 'SPECIAL') &&
+					(includeOVAs ? true : item.format !== 'OVA')
+			)
+			.sort((a, b) => {
+				switch (mediaSort) {
+					case SortOptions.MINUTES_WATCHED:
+						if (a.duration === undefined || a.mediaListEntry?.progress === undefined) return 1;
+						else if (b.duration === undefined || b.mediaListEntry?.progress === undefined)
+							return -1;
+						else
+							return (
+								b.duration * b.mediaListEntry.progress - a.duration * a.mediaListEntry.progress
+							);
+					case SortOptions.SCORE:
+					default:
+						if (a.mediaListEntry?.score === undefined) return 1;
+						else if (b.mediaListEntry?.score === undefined) return -1;
+						else return b.mediaListEntry?.score - a.mediaListEntry?.score;
 				}
+			});
+
+		let rawMangaList = await mediaListCollection(
+			user,
+			currentUserIdentity,
+			Type.Manga,
+			$manga,
+			$lastPruneTimes.manga,
+			{
+				forcePrune: true,
+				includeCompleted: true,
+				all: true
+			}
+		);
+		calculatedMangaList = rawMangaList
+			.filter(
+				(item, index, self) =>
+					self.findIndex((itemToCompare) => itemToCompare.id === item.id) === index &&
+					(includeRepeats ? true : item.mediaListEntry?.repeat === 0) &&
+					(item.mediaListEntry?.startedAt.year === selectedYear ||
+						item.mediaListEntry?.completedAt.year === selectedYear ||
+						((item.mediaListEntry?.createdAt
+							? new Date(item.mediaListEntry?.createdAt * 1000).getFullYear() === selectedYear
+							: false) && item.mediaListEntry
+							? item.mediaListEntry?.progress >= 1
+							: false))
 			)
-		)
+			.sort((a, b) => {
+				if (a.mediaListEntry?.score === undefined) return 1;
+				else if (b.mediaListEntry?.score === undefined) return -1;
+				else return b.mediaListEntry?.score - a.mediaListEntry?.score;
+			});
+
+		mangaList = rawMangaList
 			.filter(
 				(item, index, self) =>
 					self.findIndex((itemToCompare) => itemToCompare.id === item.id) === index &&
@@ -356,6 +424,13 @@
 							? new Date(item.mediaListEntry?.createdAt * 1000).getFullYear() === selectedYear
 							: false) && item.mediaListEntry
 							? item.mediaListEntry?.progress >= 1
+							: false) ||
+						(includeOngoingMediaFromPreviousYears
+							? (item.mediaListEntry?.updatedAt
+									? new Date(item.mediaListEntry?.updatedAt * 1000).getFullYear() === selectedYear
+									: false) && item.mediaListEntry
+								? item.mediaListEntry?.status === 'CURRENT'
+								: false
 							: false))
 			)
 			.sort((a, b) => {
@@ -368,12 +443,12 @@
 		minutesWatched = 0;
 		chapters = 0;
 
-		for (const media of animeList) {
+		for (const media of calculatedAnimeList) {
 			episodes += media.mediaListEntry?.progress || 0;
 			minutesWatched += (media.mediaListEntry?.progress || 0) * media.duration || 0;
 		}
 
-		for (const media of mangaList) chapters += media.mediaListEntry?.progress || 0;
+		for (const media of calculatedMangaList) chapters += media.mediaListEntry?.progress || 0;
 	};
 
 	/* eslint-disable @typescript-eslint/no-explicit-any */
@@ -533,8 +608,8 @@
 								{useFullActivityHistory}
 								{updateWidth}
 							/>
-							<Anime {animeList} {minutesWatched} {episodes} />
-							<Manga {mangaList} {chapters} />
+							<Anime animeList={calculatedAnimeList} {minutesWatched} {episodes} />
+							<Manga mangaList={calculatedMangaList} {chapters} />
 						</div>
 						{#if !disableActivityHistory && activityHistoryPosition === 'BELOW_TOP' && activities.length > 0 && selectedYear === currentYear}
 							<ActivityHistory {user} {activities} year={selectedYear} {activityHistoryPosition} />
@@ -607,10 +682,12 @@
 							rated media percentages<br />
 							<input type="checkbox" bind:checked={highestRatedGenreTagPercentage} /> Show highest
 							rated genre and tag percentages<br />
+							<input type="checkbox" bind:checked={includeOngoingMediaFromPreviousYears} /> Show
+							ongoing media from previous years<br />
 							<select bind:value={activityHistoryPosition}>
-								<option value="ORIGINAL">Original</option>
-								<option value="TOP">Top</option>
-								<option value="BELOW_TOP">Below Top</option>
+								<option value="TOP">Above Top Row</option>
+								<option value="BELOW_TOP">Below Top Row</option>
+								<option value="ORIGINAL">Bottom</option>
 							</select>
 							Activity history position<br />
 							<select bind:value={highestRatedCount}>
-- 
cgit v1.2.3

