aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/AniList/wrapped.ts47
-rw-r--r--src/lib/Tools/Wrapped.svelte10
2 files changed, 49 insertions, 8 deletions
diff --git a/src/lib/AniList/wrapped.ts b/src/lib/AniList/wrapped.ts
index f9f3c409..1eeeeac2 100644
--- a/src/lib/AniList/wrapped.ts
+++ b/src/lib/AniList/wrapped.ts
@@ -1,6 +1,12 @@
import type { AniListAuthorisation, UserIdentity } from './identity';
import type { Media } from './media';
+export enum SortOptions {
+ SCORE,
+ MINUTES_WATCHED,
+ COUNT
+}
+
export interface WrappedMediaFormat {
startYears: {
startYear: number;
@@ -158,30 +164,40 @@ export interface TopMedia {
topTagMedia: Media;
}
-export const tops = (media: Media[], amount: number, excludedKeywords: string[] = []): TopMedia => {
- const genresMap: { [genre: string]: { totalScore: number; count: number } } = {};
- const tagsMap: { [tag: string]: { totalScore: number; count: number } } = {};
+export const tops = (
+ media: Media[],
+ amount: number,
+ sortMode: SortOptions,
+ excludedKeywords: string[] = []
+): TopMedia => {
+ const genresMap: {
+ [genre: string]: { totalScore: number; count: number; minutesWatched: number };
+ } = {};
+ const tagsMap: { [tag: string]: { totalScore: number; count: number; minutesWatched: number } } =
+ {};
media.forEach((m) => {
if (m.mediaListEntry && m.mediaListEntry.score) {
m.genres.forEach((genre) => {
- if (!genresMap[genre]) genresMap[genre] = { totalScore: 0, count: 0 };
+ if (!genresMap[genre]) genresMap[genre] = { totalScore: 0, count: 0, minutesWatched: 0 };
const score = m.mediaListEntry?.score;
if (score) {
genresMap[genre].totalScore += score;
+ genresMap[genre].minutesWatched += m.duration;
genresMap[genre].count++;
}
});
m.tags.forEach((tag) => {
- if (!tagsMap[tag.name]) tagsMap[tag.name] = { totalScore: 0, count: 0 };
+ if (!tagsMap[tag.name]) tagsMap[tag.name] = { totalScore: 0, count: 0, minutesWatched: 0 };
const score = m.mediaListEntry?.score;
if (score) {
tagsMap[tag.name].totalScore += score;
+ tagsMap[tag.name].minutesWatched += m.duration;
tagsMap[tag.name].count++;
}
});
@@ -201,8 +217,25 @@ export const tops = (media: Media[], amount: number, excludedKeywords: string[]
averageScore: Math.round(tagsMap[tag].totalScore / tagsMap[tag].count)
}));
- genres.sort((a, b) => b.averageScore - a.averageScore);
- tags.sort((a, b) => b.averageScore - a.averageScore);
+ switch (sortMode) {
+ case SortOptions.SCORE:
+ genres = genres.sort((a, b) => b.averageScore - a.averageScore);
+ tags = tags.sort((a, b) => b.averageScore - a.averageScore);
+
+ break;
+ case SortOptions.MINUTES_WATCHED:
+ genres = genres.sort(
+ (a, b) => genresMap[b.genre].minutesWatched - genresMap[a.genre].minutesWatched
+ );
+ tags = tags.sort((a, b) => tagsMap[b.tag].minutesWatched - tagsMap[a.tag].minutesWatched);
+
+ break;
+ case SortOptions.COUNT:
+ genres = genres.sort((a, b) => genresMap[b.genre].count - genresMap[a.genre].count);
+ tags = tags.sort((a, b) => tagsMap[b.tag].count - tagsMap[a.tag].count);
+
+ break;
+ }
genres = genres.slice(0, amount);
tags = tags.slice(0, amount);
diff --git a/src/lib/Tools/Wrapped.svelte b/src/lib/Tools/Wrapped.svelte
index 4f05626f..2ec74a42 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 { tops, wrapped, type TopMedia } from '$lib/AniList/wrapped';
+ import { tops, wrapped, type TopMedia, SortOptions } from '$lib/AniList/wrapped';
import {
fullActivityHistory,
activityHistory as getActivityHistory
@@ -58,6 +58,7 @@
let topMedia: TopMedia;
let highestRatedMediaPercentage = true;
let highestRatedGenreTagPercentage = true;
+ let genreTagsSort = SortOptions.SCORE;
$: {
if (browser && mounted) {
@@ -108,6 +109,7 @@
topMedia = tops(
[...(animeList || []), ...(mangaList || [])],
genreTagCount,
+ genreTagsSort,
excludedKeywords
);
@@ -686,6 +688,12 @@
<a href={'#'} on:click={pruneFullYear}>Refresh data</a>
</SettingHint><br />
<p />
+ <select bind:value={genreTagsSort}>
+ <option value={SortOptions.SCORE}>Score</option>
+ <option value={SortOptions.MINUTES_WATCHED}>Minutes Watched</option>
+ <option value={SortOptions.COUNT}>Count</option>
+ </select>
+ Genre and tag sort<br />
<input type="checkbox" bind:checked={includeMusic} /> Include music<br />
<input type="checkbox" bind:checked={includeRepeats} /> Include rewatches & rereads<br
/>