aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/AniList/media.ts4
-rw-r--r--src/lib/AniList/wrapped.ts76
-rw-r--r--src/lib/Tools/Wrapped.svelte85
3 files changed, 128 insertions, 37 deletions
diff --git a/src/lib/AniList/media.ts b/src/lib/AniList/media.ts
index 52d7da85..3fdd54dc 100644
--- a/src/lib/AniList/media.ts
+++ b/src/lib/AniList/media.ts
@@ -87,7 +87,9 @@ export const flattenLists = (
self.findIndex((itemToCompare) => itemToCompare.id === item.id) === index
);
- if (!all) {
+ if (all) {
+ for (const list of lists) flattenedList.push(...list.entries.map((entry) => entry.media));
+ } else {
for (const list of lists) {
if (list.name.toLowerCase().includes('#dueinclude')) {
dueInclude = true;
diff --git a/src/lib/AniList/wrapped.ts b/src/lib/AniList/wrapped.ts
index 35ce7554..40a81957 100644
--- a/src/lib/AniList/wrapped.ts
+++ b/src/lib/AniList/wrapped.ts
@@ -1,4 +1,5 @@
import type { AniListAuthorisation, UserIdentity } from './identity';
+import type { Media } from './media';
export interface WrappedMediaFormat {
startYears: {
@@ -143,3 +144,78 @@ export const wrapped = async (
avatar: wrappedResponse['data']['User']['avatar']
};
};
+
+export interface TopMedia {
+ genres: {
+ genre: string;
+ averageScore: number;
+ }[];
+ tags: {
+ tag: string;
+ averageScore: number;
+ }[];
+ topGenreMedia: Media;
+ topTagMedia: Media;
+}
+
+export const tops = (media: Media[], amount: number): TopMedia => {
+ const genresMap: { [genre: string]: { totalScore: number; count: number } } = {};
+ const tagsMap: { [tag: string]: { totalScore: number; count: number } } = {};
+
+ media.forEach((m) => {
+ if (m.mediaListEntry && m.mediaListEntry.score) {
+ m.genres.forEach((genre) => {
+ if (!genresMap[genre]) genresMap[genre] = { totalScore: 0, count: 0 };
+
+ const score = m.mediaListEntry?.score;
+
+ if (score) {
+ genresMap[genre].totalScore += score;
+ genresMap[genre].count++;
+ }
+ });
+
+ m.tags.forEach((tag) => {
+ if (!tagsMap[tag.name]) tagsMap[tag.name] = { totalScore: 0, count: 0 };
+
+ const score = m.mediaListEntry?.score;
+
+ if (score) {
+ tagsMap[tag.name].totalScore += score;
+ tagsMap[tag.name].count++;
+ }
+ });
+ }
+ });
+
+ // const limitNumber = (n: number) => {
+ // const formatted = Number(n).toFixed(2);
+
+ // return formatted.endsWith('00') ? Number(formatted).toString() : formatted;
+ // };
+
+ let genres = Object.keys(genresMap).map((genre) => ({
+ genre,
+ averageScore: Math.round(genresMap[genre].totalScore / genresMap[genre].count)
+ }));
+ let tags = Object.keys(tagsMap).map((tag) => ({
+ tag,
+ averageScore: Math.round(tagsMap[tag].totalScore / tagsMap[tag].count)
+ }));
+
+ genres = genres.slice(0, amount);
+ tags = tags.slice(0, amount);
+
+ const topGenreMedia = media.find((m) => m.genres.includes(genres[0].genre)) || media[0];
+ const topTagMedia = media.find((m) => m.tags.some((tag) => tag.name === tags[0].tag)) || media[0];
+
+ // if (topGenreMedia.id === topTagMedia.id)
+ // topTagMedia = media.find((m) => m.id !== topGenreMedia.id) || media[1];
+
+ return {
+ genres,
+ tags,
+ topGenreMedia,
+ topTagMedia
+ };
+};
diff --git a/src/lib/Tools/Wrapped.svelte b/src/lib/Tools/Wrapped.svelte
index 6c7e16d1..0e8ad66d 100644
--- a/src/lib/Tools/Wrapped.svelte
+++ b/src/lib/Tools/Wrapped.svelte
@@ -5,7 +5,7 @@
type AniListAuthorisation
} from '$lib/AniList/identity';
import { onMount } from 'svelte';
- import { wrapped } from '$lib/AniList/wrapped.js';
+ import { tops, wrapped, type TopMedia } from '$lib/AniList/wrapped.js';
import {
fullActivityHistory,
activityHistory as getActivityHistory
@@ -51,6 +51,7 @@
let excludedKeywords: string[] = [];
let useFullActivityHistory = false;
let topGenresTags = true;
+ let topMedia: TopMedia;
$: {
if (browser && mounted) {
@@ -174,9 +175,7 @@
currentUserIdentity.name = currentUserIdentity.name;
} else currentUserIdentity.id = -2;
- await update();
-
- mounted = true;
+ await update().then(() => (mounted = true));
});
const update = async () => {
@@ -191,7 +190,8 @@
$lastPruneTimes.anime,
{
forcePrune: true,
- includeCompleted: true
+ includeCompleted: true,
+ all: true
}
)
)
@@ -217,7 +217,8 @@
$lastPruneTimes.manga,
{
forcePrune: true,
- includeCompleted: true
+ includeCompleted: true,
+ all: true
}
)
)
@@ -244,6 +245,8 @@
}
for (const media of mangaList) chapters += media.mediaListEntry?.progress || 0;
+
+ topMedia = tops([...animeList, ...mangaList], 5);
};
/* eslint-disable @typescript-eslint/no-explicit-any */
@@ -350,29 +353,29 @@
await database.activities.bulkDelete((await database.activities.toArray()).map((m) => m.page));
};
- const mergeArraySort = (a: any, b: any, mode: 'tags' | 'genres') => {
- let merged = [...a, ...b].sort((a, b) => b.meanScore - a.meanScore);
+ // const mergeArraySort = (a: any, b: any, mode: 'tags' | 'genres') => {
+ // let merged = [...a, ...b].sort((a, b) => b.meanScore - a.meanScore);
- merged = merged.filter(
- (item, index, self) =>
- self.findIndex((itemToCompare) =>
- mode === 'genres'
- ? itemToCompare.genre === item.genre
- : itemToCompare.tag.name === item.tag.name
- ) === index
- );
+ // merged = merged.filter(
+ // (item, index, self) =>
+ // self.findIndex((itemToCompare) =>
+ // mode === 'genres'
+ // ? itemToCompare.genre === item.genre
+ // : itemToCompare.tag.name === item.tag.name
+ // ) === index
+ // );
- return merged;
- };
+ // return merged;
+ // };
- const randomCoverFromTop10 = (
- statistics: { anime: any; manga: any },
- mode: 'tags' | 'genres'
- ) => {
- const top = mergeArraySort(statistics.anime[mode], statistics.manga[mode], mode);
+ // const randomCoverFromTop10 = (
+ // statistics: { anime: any; manga: any },
+ // mode: 'tags' | 'genres'
+ // ) => {
+ // const top = mergeArraySort(statistics.anime[mode], statistics.manga[mode], mode);
- return mediaCover(top[Math.floor(Math.random() * top.length)].mediaIds[0]);
- };
+ // return mediaCover(top[Math.floor(Math.random() * top.length)].mediaIds[0]);
+ // };
</script>
{#if currentUserIdentity.id === -2}
@@ -503,24 +506,29 @@
<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}
+ <a
+ href={`https://anilist.co/${topMedia.topGenreMedia.type.toLowerCase()}/${
+ topMedia.topGenreMedia.id
+ }`}
+ target="_blank"
+ >
<img
- src={proxy(cover)}
+ src={proxy(topMedia.topGenreMedia.coverImage.extraLarge)}
alt="Highest Rated Genre Cover"
class="cover-image"
on:load={updateWidth}
/>
- {/await}
+ </a>
<div>
<b>Highest Rated Genres</b>
<ol>
- {#each mergeArraySort(wrapped.statistics.anime.genres, wrapped.statistics.manga.genres, 'genres').slice(0, highestRatedCount) as genre}
+ {#each topMedia.genres as genre}
<li>
<a
href={`https://anilist.co/search/anime?genres=${genre.genre}`}
target="_blank"
>
- {genre.genre}: {genre.meanScore}%
+ {genre.genre}: {genre.averageScore}%
</a>
</li>
{/each}
@@ -530,24 +538,29 @@
</div>
<div class="category-grid pure-category category">
<div class="grid-item image-grid">
- {#await randomCoverFromTop10(wrapped.statistics, 'tags') then cover}
+ <a
+ href={`https://anilist.co/${topMedia.topTagMedia.type.toLowerCase()}/${
+ topMedia.topTagMedia.id
+ }`}
+ target="_blank"
+ >
<img
- src={proxy(cover)}
+ src={proxy(topMedia.topTagMedia.coverImage.extraLarge)}
alt="Highest Rated Tag Cover"
class="cover-image"
on:load={updateWidth}
/>
- {/await}
+ </a>
<div>
<b>Highest Rated Tags</b>
<ol>
- {#each mergeArraySort(wrapped.statistics.anime.tags, wrapped.statistics.manga.tags, 'tags').slice(0, highestRatedCount) as tag}
+ {#each topMedia.tags as tag}
<li>
<a
- href={`https://anilist.co/search/anime?genres=${tag.tag.name}`}
+ href={`https://anilist.co/search/anime?genres=${tag.tag}`}
target="_blank"
>
- {tag.tag.name}: {tag.meanScore}%
+ {tag.tag}: {tag.averageScore}%
</a>
</li>
{/each}