From 8a8cf810e4a03453b8254eaad56c27529dc107ef Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.me>
Date: Fri, 22 Dec 2023 06:53:35 -0800
Subject: feat(wrapped): genres and tags

---
 src/lib/Tools/Wrapped.svelte | 74 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

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

diff --git a/src/lib/Tools/Wrapped.svelte b/src/lib/Tools/Wrapped.svelte
index 57ec09b7..0d8f0834 100644
--- a/src/lib/Tools/Wrapped.svelte
+++ b/src/lib/Tools/Wrapped.svelte
@@ -10,7 +10,7 @@
 		fullActivityHistory,
 		activityHistory as getActivityHistory
 	} from '$lib/AniList/activity.js';
-	import { Type, mediaListCollection, type Media } from '$lib/AniList/media.js';
+	import { Type, mediaListCollection, type Media, mediaCover } from '$lib/AniList/media.js';
 	import anime from '../../stores/anime.js';
 	import lastPruneTimes from '../../stores/lastPruneTimes.js';
 	import manga from '../../stores/manga.js';
@@ -50,6 +50,7 @@
 	let excludedKeywordsInput = '';
 	let excludedKeywords: string[] = [];
 	let useFullActivityHistory = false;
+	let topGenresTags = true;
 
 	$: {
 		if (browser && mounted) {
@@ -344,6 +345,17 @@
 	const pruneFullYear = async () => {
 		await database.activities.bulkDelete((await database.activities.toArray()).map((m) => m.page));
 	};
+
+	const mergeArraySort = (a: any, b: any) => [...a, ...b].sort((a, b) => b.meanScore - a.meanScore);
+
+	const randomCoverFromTop10 = (
+		statistics: { anime: any; manga: any },
+		mode: 'tags' | 'genres'
+	) => {
+		const top = mergeArraySort(statistics.anime[mode], statistics.manga[mode]);
+
+		return mediaCover(top[Math.floor(Math.random() * top.length)].mediaIds[0]);
+	};
 </script>
 
 {#if currentUserIdentity.id === -2}
@@ -470,6 +482,64 @@
 						</div>
 					</div>
 				</div>
+				{#if topGenresTags}
+					<div class="categories-grid" style="padding-top: 0;">
+						<div class="category-grid pure-category category">
+							<div class="grid-item image-grid">
+								{#await randomCoverFromTop10(wrapped.statistics, 'genres') then cover}
+									<img
+										src={proxy(cover)}
+										alt="Highest Rated Genre Cover"
+										class="cover-image"
+										on:load={updateWidth}
+									/>
+								{/await}
+								<div>
+									<b>Highest Rated Genres</b>
+									<ol>
+										{#each mergeArraySort(wrapped.statistics.anime.genres, wrapped.statistics.manga.genres).slice(0, highestRatedCount) as genre}
+											<li>
+												<a
+													href={`https://anilist.co/search/anime?genres=${genre.genre}`}
+													target="_blank"
+												>
+													{genre.genre}: {genre.meanScore}%
+												</a>
+											</li>
+										{/each}
+									</ol>
+								</div>
+							</div>
+						</div>
+						<div class="category-grid pure-category category">
+							<div class="grid-item image-grid">
+								{#await randomCoverFromTop10(wrapped.statistics, 'tags') then cover}
+									<img
+										src={proxy(cover)}
+										alt="Highest Rated Tag Cover"
+										class="cover-image"
+										on:load={updateWidth}
+									/>
+								{/await}
+								<div>
+									<b>Highest Rated Tags</b>
+									<ol>
+										{#each mergeArraySort(wrapped.statistics.anime.tags, wrapped.statistics.manga.tags).slice(0, highestRatedCount) as tag}
+											<li>
+												<a
+													href={`https://anilist.co/search/anime?genres=${tag.tag.name}`}
+													target="_blank"
+												>
+													{tag.tag.name}: {tag.meanScore}%
+												</a>
+											</li>
+										{/each}
+									</ol>
+								</div>
+							</div>
+						</div>
+					</div>
+				{/if}
 				{#if !disableActivityHistory}
 					<div class="categories-grid bottom-category" style="padding-top: 0;">
 						<div class="category-grid pure-category">
@@ -501,6 +571,8 @@
 					<input type="checkbox" bind:checked={transparency} /> Enable background transparency<br />
 					<input type="checkbox" bind:checked={lightMode} />
 					Enable light mode<br />
+					<input type="checkbox" bind:checked={topGenresTags} />
+					Enable top genres and tags<br />
 					<input type="checkbox" bind:checked={disableActivityHistory} /> Disable activity history<br
 					/>
 					{#if !disableActivityHistory}
-- 
cgit v1.2.3

