diff options
| author | Fuwn <[email protected]> | 2024-01-03 22:05:24 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-01-03 22:05:24 -0800 |
| commit | 1d0ffdba530fa166ac577ef1fba3b5a0a959959a (patch) | |
| tree | d9264c043a7ee39d982654e88b766e51a217fe16 /src/lib/Tools/Wrapped | |
| parent | feat(badges): put returns badges (diff) | |
| download | due.moe-1d0ffdba530fa166ac577ef1fba3b5a0a959959a.tar.xz due.moe-1d0ffdba530fa166ac577ef1fba3b5a0a959959a.zip | |
refactor(wrapped): move panels to components
Diffstat (limited to 'src/lib/Tools/Wrapped')
| -rw-r--r-- | src/lib/Tools/Wrapped/ActivityHistory.svelte | 21 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/Media.svelte | 98 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/MediaExtras.svelte | 74 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/Top/Activity.svelte | 43 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/Top/Anime.svelte | 20 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/Top/Manga.svelte | 22 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/Watermark.svelte | 5 | ||||
| -rw-r--r-- | src/lib/Tools/Wrapped/wrapped.css | 100 |
8 files changed, 383 insertions, 0 deletions
diff --git a/src/lib/Tools/Wrapped/ActivityHistory.svelte b/src/lib/Tools/Wrapped/ActivityHistory.svelte new file mode 100644 index 00000000..7c972eb9 --- /dev/null +++ b/src/lib/Tools/Wrapped/ActivityHistory.svelte @@ -0,0 +1,21 @@ +<script lang="ts"> + import type { ActivityHistoryEntry } from '$lib/AniList/activity'; + import type { AniListAuthorisation } from '$lib/AniList/identity'; + import ActivityHistoryGrid from '../ActivityHistory/Grid.svelte'; + + export let user: AniListAuthorisation; + export let activities: ActivityHistoryEntry[]; + export let year: number; + export let activityHistoryPosition: 'TOP' | 'BELOW_TOP' | 'ORIGINAL'; +</script> + +<div + class="categories-grid" + style={`padding-${activityHistoryPosition === 'ORIGINAL' ? 'top' : 'bottom'}: 0;`} +> + <div class="category-grid bottom-category pure-category category"> + <div id="activity-history"> + <ActivityHistoryGrid {user} activityData={activities} currentYear={year} /> + </div> + </div> +</div> diff --git a/src/lib/Tools/Wrapped/Media.svelte b/src/lib/Tools/Wrapped/Media.svelte new file mode 100644 index 00000000..08092a28 --- /dev/null +++ b/src/lib/Tools/Wrapped/Media.svelte @@ -0,0 +1,98 @@ +<script lang="ts"> + import type { Media } from '$lib/AniList/media'; + import type { Wrapped } from '$lib/AniList/wrapped'; + import MediaTitleDisplay from '$lib/List/MediaTitleDisplay.svelte'; + import proxy from '$lib/Utility/proxy'; + + export let animeList: Media[] | undefined; + export let mangaList: Media[] | undefined; + export let wrapped: Wrapped; + export let updateWidth: () => void; + export let highestRatedMediaPercentage: boolean; + export let highestRatedCount: number; + export let animeMostTitle: string; + export let mangaMostTitle: string; +</script> + +{#if animeList !== undefined || mangaList !== undefined} + <div class="categories-grid"> + <div class="category-grid pure-category category middle-category"> + <div class="grid-item image-grid"> + <a + href={animeList && animeList[0] ? `https://anilist.co/anime/${animeList[0].id}` : '#'} + target="_blank" + > + <img + src={proxy( + animeList && animeList[0] ? animeList[0].coverImage.extraLarge : wrapped.avatar.large + )} + alt="Highest Rated Anime Cover" + class="cover-image" + on:load={updateWidth} + /> + </a> + <div> + <b>{animeMostTitle} Anime</b> + <ol> + {#if animeList !== undefined && animeList.length !== 0} + {#each animeList?.slice(0, highestRatedCount) as anime} + <li> + <a href={`https://anilist.co/anime/${anime.id}`} target="_blank"> + <MediaTitleDisplay title={anime.title} /> + </a>{highestRatedMediaPercentage && + anime.mediaListEntry && + anime.mediaListEntry?.score > 0 + ? `: ${anime.mediaListEntry?.score}%` + : ''} + </li> + {/each} + {:else} + <li> + <p style="opacity: 50%;">(⌣_⌣”)</p> + </li> + {/if} + </ol> + </div> + </div> + </div> + <div class="category-grid pure-category category middle-category"> + <div class="grid-item image-grid"> + <a + href={mangaList && mangaList[0] ? `https://anilist.co/manga/${mangaList[0].id}` : '#'} + target="_blank" + > + <img + src={proxy( + mangaList && mangaList[0] ? mangaList[0].coverImage.extraLarge : wrapped.avatar.large + )} + alt="Highest Rated Manga Cover" + class="cover-image" + on:load={updateWidth} + /> + </a> + <div> + <b>{mangaMostTitle} Manga</b> + <ol> + {#if mangaList !== undefined && mangaList.length !== 0} + {#each mangaList?.slice(0, highestRatedCount) as manga} + <li> + <a href={`https://anilist.co/manga/${manga.id}`} target="_blank"> + <MediaTitleDisplay title={manga.title} /> + </a>{highestRatedMediaPercentage && + manga.mediaListEntry && + manga.mediaListEntry?.score > 0 + ? `: ${manga.mediaListEntry?.score}%` + : ''} + </li> + {/each} + {:else} + <li> + <p style="opacity: 50%;">(⌣_⌣”)</p> + </li> + {/if} + </ol> + </div> + </div> + </div> + </div> +{/if} diff --git a/src/lib/Tools/Wrapped/MediaExtras.svelte b/src/lib/Tools/Wrapped/MediaExtras.svelte new file mode 100644 index 00000000..00417c54 --- /dev/null +++ b/src/lib/Tools/Wrapped/MediaExtras.svelte @@ -0,0 +1,74 @@ +<script lang="ts"> + import type { TopMedia } from '$lib/AniList/wrapped'; + import proxy from '$lib/Utility/proxy'; + + export let topMedia: TopMedia; + export let updateWidth: () => void; + export let highestRatedGenreTagPercentage: boolean; + export let genreTagTitle: string; +</script> + +<div class="categories-grid" style="padding-top: 0;"> + {#if topMedia.topGenreMedia && topMedia.genres.length > 0} + <div class="category-grid pure-category category"> + <div class="grid-item image-grid"> + <a + href={`https://anilist.co/${topMedia.topGenreMedia.type.toLowerCase()}/${ + topMedia.topGenreMedia.id + }`} + target="_blank" + > + <img + src={proxy(topMedia.topGenreMedia.coverImage.extraLarge)} + alt="Highest Rated Genre Cover" + class="cover-image" + on:load={updateWidth} + /> + </a> + <div> + <b>{genreTagTitle} Genres</b> + <ol> + {#each topMedia.genres as genre} + <li> + <a href={`https://anilist.co/search/anime?genres=${genre.genre}`} target="_blank"> + {genre.genre}{highestRatedGenreTagPercentage ? `: ${genre.averageScore}%` : ''} + </a> + </li> + {/each} + </ol> + </div> + </div> + </div> + {/if} + {#if topMedia.topTagMedia && topMedia.tags.length > 0} + <div class="category-grid pure-category category"> + <div class="grid-item image-grid"> + <a + href={`https://anilist.co/${topMedia.topTagMedia.type.toLowerCase()}/${ + topMedia.topTagMedia.id + }`} + target="_blank" + > + <img + src={proxy(topMedia.topTagMedia.coverImage.extraLarge)} + alt="Highest Rated Tag Cover" + class="cover-image" + on:load={updateWidth} + /> + </a> + <div> + <b>{genreTagTitle} Tags</b> + <ol> + {#each topMedia.tags as tag} + <li> + <a href={`https://anilist.co/search/anime?genres=${tag.tag}`} target="_blank"> + {tag.tag}{highestRatedGenreTagPercentage ? `: ${tag.averageScore}%` : ''} + </a> + </li> + {/each} + </ol> + </div> + </div> + </div> + {/if} +</div> diff --git a/src/lib/Tools/Wrapped/Top/Activity.svelte b/src/lib/Tools/Wrapped/Top/Activity.svelte new file mode 100644 index 00000000..a000389c --- /dev/null +++ b/src/lib/Tools/Wrapped/Top/Activity.svelte @@ -0,0 +1,43 @@ +<script lang="ts"> + import type { ActivityHistoryEntry } from '$lib/AniList/activity'; + import type { UserIdentity } from '$lib/AniList/identity'; + import type { Wrapped } from '$lib/AniList/wrapped'; + import proxy from '$lib/Utility/proxy'; + + export let wrapped: Wrapped; + export let identity: UserIdentity; + export let year: number; + export let activities: ActivityHistoryEntry[]; + export let useFullActivityHistory: boolean; + export let updateWidth: () => void; + + const currentYear = new Date(Date.now()).getFullYear(); +</script> + +<div class="grid-item image-grid avatar-grid category top-category"> + <a href={`https://anilist.co/user/${identity.name}`} target="_blank"> + <img src={proxy(wrapped.avatar.large)} alt="User Avatar" on:load={updateWidth} /> + </a> + <div> + <div> + <a href={`https://anilist.co/user/${identity.name}`} target="_blank"> + <b> + {identity.name} + </b> + </a> + </div> + <div> + Status Posts: {wrapped.activities.statusCount} + </div> + <div> + Messages: {wrapped.activities.messageCount} + </div> + <div> + Days Active: {#if year !== currentYear} + ?/365 + {:else} + {activities.length}/{useFullActivityHistory ? 365 : 189} + {/if} + </div> + </div> +</div> diff --git a/src/lib/Tools/Wrapped/Top/Anime.svelte b/src/lib/Tools/Wrapped/Top/Anime.svelte new file mode 100644 index 00000000..8ea1277f --- /dev/null +++ b/src/lib/Tools/Wrapped/Top/Anime.svelte @@ -0,0 +1,20 @@ +<script lang="ts"> + import type { Media } from '$lib/AniList/media'; + + export let minutesWatched: number; + export let animeList: Media[] | undefined; + export let episodes: number; +</script> + +<div class="category-grid pure-category category top-category"> + <div class="grid-item"> + <b>Anime</b> + </div> + <div class="grid-item"> + Time Watched: {((minutesWatched || 0) / 60 / 24).toFixed(2)} days + </div> + <div class="grid-item"> + Completed: {animeList?.length || 0} + </div> + <div class="grid-item">Episodes: {episodes}</div> +</div> diff --git a/src/lib/Tools/Wrapped/Top/Manga.svelte b/src/lib/Tools/Wrapped/Top/Manga.svelte new file mode 100644 index 00000000..b0d78b6e --- /dev/null +++ b/src/lib/Tools/Wrapped/Top/Manga.svelte @@ -0,0 +1,22 @@ +<script lang="ts"> + import type { Media } from '$lib/AniList/media'; + import { estimatedDayReading } from '$lib/Media/Manga/time'; + + export let mangaList: Media[] | undefined; + export let chapters: number; +</script> + +<div class="category-grid pure-category category top-category"> + <div class="grid-item"> + <b>Manga</b> + </div> + <div class="grid-item"> + Time Read: {estimatedDayReading(chapters).toFixed(2)} days + </div> + <div class="grid-item"> + Completed: {mangaList?.length || 0} + </div> + <div class="grid-item"> + Chapters: {chapters} + </div> +</div> diff --git a/src/lib/Tools/Wrapped/Watermark.svelte b/src/lib/Tools/Wrapped/Watermark.svelte new file mode 100644 index 00000000..2e8dd838 --- /dev/null +++ b/src/lib/Tools/Wrapped/Watermark.svelte @@ -0,0 +1,5 @@ +<div class="categories-grid" style="padding-top: 0;"> + <div class="category-grid pure-category" id="watermark"> + <a href="https://due.moe/wrapped" target="_blank">due.moe/wrapped</a> + </div> +</div> diff --git a/src/lib/Tools/Wrapped/wrapped.css b/src/lib/Tools/Wrapped/wrapped.css new file mode 100644 index 00000000..1ac01d85 --- /dev/null +++ b/src/lib/Tools/Wrapped/wrapped.css @@ -0,0 +1,100 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700'); +@import url('https://fonts.googleapis.com/css?family=Overpass:400,600,700,800'); + +.categories-grid { + display: flex; + flex-wrap: wrap; + row-gap: 1.5em; + column-gap: 1.5em; + padding: 2%; + justify-content: center; + font-family: Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, + Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + background-color: #0b1622; +} + +.categories-grid b { + font-family: Overpass, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, + Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: 600; +} + +.category-grid, +.image-grid { + background-color: #151f2e; + border-radius: 4px; + color: rgb(159, 173, 189); +} + +.pure-category, +.avatar-grid { + padding: 1.5%; +} + +.category-grid { + display: grid; +} + +.image-grid { + display: flex; + column-gap: 1em; + flex-wrap: wrap; +} + +.image-grid img { + width: 6em; + height: auto; + border-radius: 3px; +} + +.categories-grid a { + text-decoration: none; + color: unset; +} + +.transparent .categories-grid { + background-color: transparent !important; +} + +.light-theme .categories-grid { + background-color: #edf1f5; +} + +.light-theme .category-grid { + background-color: #fafafa; + color: rgb(92, 114, 138); +} + +.light-theme .image-grid { + background-color: #fafafa; + color: rgb(92, 114, 138); +} + +ol { + margin: 0 !important; +} + +#watermark { + color: rgb(61, 180, 242); +} + +#wrapped-final { + height: auto; + width: 50%; +} + +#list-container { + display: flex; + gap: 1rem; + flex-wrap: wrap; + align-items: start; +} + +.list { + flex-grow: 1; + flex-basis: 1%; +} + +#wrapped { + overflow-y: scroll; +} |