diff options
| author | Fuwn <[email protected]> | 2026-01-28 23:55:47 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-28 23:55:47 -0800 |
| commit | 079290f881e422b03e504da27f89d4e997e63a25 (patch) | |
| tree | 33f36945d6ec78f8ae5caa88c5527a2e21e54151 /src | |
| parent | feat: Add hero for landing and welcome page (diff) | |
| download | due.moe-079290f881e422b03e504da27f89d4e997e63a25.tar.xz due.moe-079290f881e422b03e504da27f89d4e997e63a25.zip | |
feat(Landing): Update to match LandingHero
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/Landing.svelte | 553 | ||||
| -rw-r--r-- | src/lib/List/Anime/AnimeListTemplate.svelte | 3 | ||||
| -rw-r--r-- | src/lib/List/Anime/CleanAnimeList.svelte | 2 | ||||
| -rw-r--r-- | src/lib/List/Anime/CompletedAnimeList.svelte | 58 | ||||
| -rw-r--r-- | src/lib/List/CleanGrid.svelte | 4 | ||||
| -rw-r--r-- | src/lib/List/Manga/CleanMangaList.svelte | 3 | ||||
| -rw-r--r-- | src/lib/List/Manga/MangaListTemplate.svelte | 44 | ||||
| -rw-r--r-- | src/routes/+page.svelte | 6 |
8 files changed, 499 insertions, 174 deletions
diff --git a/src/lib/Landing.svelte b/src/lib/Landing.svelte index 8fb8f72b..4c824a8d 100644 --- a/src/lib/Landing.svelte +++ b/src/lib/Landing.svelte @@ -1,154 +1,481 @@ <script lang="ts"> - import Spacer from '$lib/Layout/Spacer.svelte'; import root from './Utility/root'; import { env } from '$env/dynamic/public'; - import tooltip from './Tooltip/tooltip'; import CompletedAnimeList from './List/Anime/CompletedAnimeList.svelte'; import MangaListTemplate from './List/Manga/MangaListTemplate.svelte'; import localforage from 'localforage'; + import { onMount } from 'svelte'; + + let sectionsVisible = $state<boolean[]>([false, false, false]); + let mangaContainer: HTMLElement; + let animeContainer: HTMLElement; + let gridLimit = $state<number | undefined>(undefined); + let demoFocused = $state(false); + const COVER_WIDTH = 100; + const COVER_GAP = 12; + const dummyCount = 20; + + const calculateLimit = () => { + const container = mangaContainer || animeContainer; + + if (!container) return; + + const containerWidth = container.clientWidth; + const itemWidth = COVER_WIDTH + COVER_GAP; + const padding = containerWidth < 500 ? 48 : 36; + + gridLimit = Math.max(2, Math.floor((containerWidth - padding) / itemWidth)); + }; + + onMount(() => { + const intersectionObserver = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const index = Number(entry.target.getAttribute('data-section')); + + sectionsVisible[index] = true; + } + }); + }, + { threshold: 0.1 } + ); + + document.querySelectorAll('.landing-section').forEach((el) => intersectionObserver.observe(el)); + + calculateLimit(); + + const resizeObserver = new ResizeObserver(calculateLimit); + + if (mangaContainer) resizeObserver.observe(mangaContainer); + if (animeContainer) resizeObserver.observe(animeContainer); + + const handleKeydown = (e: KeyboardEvent) => { + if (e.key === 'Escape' && demoFocused) demoFocused = false; + }; + + document.addEventListener('keydown', handleKeydown); + + return () => { + intersectionObserver.disconnect(); + resizeObserver.disconnect(); + document.removeEventListener('keydown', handleKeydown); + }; + }); </script> -<div class="example-item card"> - <div class="item-content"> - <details class="list" open> - <MangaListTemplate due={true} dummy displayUnresolved={false} disableFilter /> - </details> - </div> +<div class="landing"> + <section class="landing-section" class:visible={sectionsVisible[0]} data-section="0"> + <div class="section-row"> + <div class="section-demo card" bind:this={mangaContainer}> + <details class="list" open> + <MangaListTemplate + due={true} + dummy + displayUnresolved={false} + disableFilter + {dummyCount} + limit={gridLimit} + /> + </details> + </div> - <div class="card item-description"> - <span class="big-text">Manga, Without the Guesswork</span> + <div class="section-info card"> + <p class="section-label">Manga Tracking</p> - <p> - <a href={root('/')}>due.moe</a> automatically keeps your manga and light novel lists up to date—checking - for new chapters, notifying you of new releases, and reminding you to update your volume count if - you fall behind. Completed and ongoing series stay neatly organized so you can instantly see what - needs your attention. Staying on top of your reading has never been easier. - </p> + <h2 class="section-title">Without the Guesswork</h2> - <small class="bottom"> - This demo view contains simulated data which may include concluded manga. - </small> - </div> -</div> + <p class="section-description"> + Automatically track new chapters, get notified of releases, and stay organised. Completed + and ongoing series stay neatly arranged so you can instantly see what needs your + attention. + </p> + <p class="demo-note">Simulated data shown</p> + </div> + </div> + </section> -<Spacer /> + <section class="landing-section" class:visible={sectionsVisible[1]} data-section="1"> + <div class="section-row reverse"> + <div class="section-info card"> + <p class="section-label">Anime Tracking</p> -<div class="example-item card"> - <div class="card item-description"> - <span class="big-text">Anime, Made Smarter</span> + <h2 class="section-title">Made Smarter</h2> - <p> - Track your anime effortlessly. <a href={root('/')}>due.moe</a> shows which episodes you still need - to watch, keeps you updated on upcoming releases, and even counts down to the next subtitled episode—so - you're always on time. - </p> + <p class="section-description"> + See what you need to watch, track upcoming releases, and count down to the next subtitled + episode. Never fall behind on seasonal anime again. + </p> + <p class="demo-note">Simulated data shown</p> + </div> - <small class="bottom"> - This demo view contains simulated data which may include concluded anime. - </small> - </div> - <div class="item-content"> - <details class="list" open> - <CompletedAnimeList dummy disableFilter /> - </details> - </div> + <div class="section-demo card" bind:this={animeContainer}> + <details class="list" open> + <CompletedAnimeList dummy disableFilter {dummyCount} limit={gridLimit} /> + </details> + </div> + </div> + </section> + + <section + class="landing-section tools-section" + class:visible={sectionsVisible[2]} + data-section="2" + > + <div class="section-row"> + <div class="section-info card"> + <p class="section-label">Beyond Tracking</p> + + <h2 class="section-title">A Suite of Tools</h2> + + <p class="section-description"> + Everything you need to enhance your AniList experience. From year-in-review stats to + subtitle schedules, it's all here. + </p> + + <a + href={`https://anilist.co/api/v2/oauth/authorize?client_id=${env.PUBLIC_ANILIST_CLIENT_ID}&redirect_uri=${env.PUBLIC_ANILIST_REDIRECT_URI}&response_type=code`} + class="cta" + onclick={async () => { + await localforage.setItem( + 'redirect', + window.location.origin + window.location.pathname + window.location.search + ); + }} + > + Connect with AniList + </a> + </div> + + <div class="tools-and-demo"> + <div class="tools-grid"> + <a href={root('/wrapped')} class="tool-card card"> + <h3 class="tool-title">AniList Wrapped</h3> + + <p class="tool-description">Your year on AniList, visualised</p> + </a> + + <div class="tool-card card"> + <h3 class="tool-title">Badge Wall</h3> + + <p class="tool-description">All your badges in one place, including AWC</p> + </div> + + <a href={root('/schedule')} class="tool-card card"> + <h3 class="tool-title">Subtitle Schedule</h3> + + <p class="tool-description">Know when subtitles drop for simulcasts</p> + </a> + + <a href={root('/birthdays')} class="tool-card card"> + <h3 class="tool-title">Character Birthdays</h3> + + <p class="tool-description">Never miss your favourites' special day</p> + </a> + + <a href={root('/tools/sequel_spy')} class="tool-card card"> + <h3 class="tool-title">Sequel Spy</h3> + + <p class="tool-description">Find prequels you might have missed</p> + </a> + </div> + + <div + class="demo-card card" + onclick={() => (demoFocused = true)} + role="button" + tabindex="0" + onkeydown={(e) => e.key === 'Enter' && (demoFocused = true)} + > + <img src="https://i.imgur.com/j5vfKbx.gif" alt="Demo" title="Click to expand" /> + </div> + </div> + </div> + </section> </div> -<Spacer /> - -<div class="example-item card"> - <div class="item-content"> - <span class="big-text">Smarter Tools, Better Experience</span> - - <p> - <a href={root('/')}>due.moe</a> isn't just tracking—it's a full suite of tools designed to enhance - your AniList experience. From Wrapped to Sequel Spy, everything you need is right here. - </p> - - <ul> - <li><a href={root('/wrapped')}>AniList Wrapped</a> — Your Year on AniList</li> - <li> - Badge Wall — A unified badge collection experience for AniList - <blockquote style="margin: 0 0 0 1.5rem;"> - Easily display all of your earned badges in a single place, with your Anime Watching Club - (AWC) badges automatically included! - </blockquote> - </li> - <li> - <a href={root('/schedule')}>Subtitle Schedule</a> — A release calendar which displaying the - scheduled <b>subtitle release times</b> for simulcast anime! - </li> - <li> - <a href={root('/birthdays')}>Today's Character Birthdays</a> — A calendar to help you stay up - to date with your favourite characters' birthdays, featuring an even bigger character database - than AniList! - </li> - <li> - <a href={root('/tools/sequel_spy')}>Sequel Spy</a> — Find media with prequels you haven't seen - for any simulcast season - </li> - </ul> - - <br /><br /> - - <span class="medium-text"> - <a - href={`https://anilist.co/api/v2/oauth/authorize?client_id=${env.PUBLIC_ANILIST_CLIENT_ID}&redirect_uri=${env.PUBLIC_ANILIST_REDIRECT_URI}&response_type=code`} - onclick={async () => { - await localforage.setItem( - 'redirect', - window.location.origin + window.location.pathname + window.location.search - ); - }}>Log in</a - > - with AniList, and <a href={root('/')}>due.moe</a> does the rest. - </span> - </div> +{#if demoFocused} + <div + class="demo-overlay" + onclick={() => (demoFocused = false)} + role="button" + tabindex="0" + onkeydown={(e) => e.key === 'Escape' && (demoFocused = false)} + > + <div class="demo-focused"> + <img src="https://i.imgur.com/j5vfKbx.gif" alt="Demo" /> - <div class="item-description demo"> - <a href="https://imgur.com/j5vfKbx.mp4" target="_blank"> - <img src="https://imgur.com/j5vfKbx.gif" alt="Demo" title="Demo" use:tooltip /> - </a> + <p class="demo-hint">Click anywhere to close</p> + </div> </div> -</div> +{/if} <style> - .example-item { + .landing { + display: flex; + flex-direction: column; + gap: 2rem; + } + + .landing-section { + opacity: 0; + transform: translateY(30px); + transition: + opacity 0.6s ease, + transform 0.6s ease; + } + + .landing-section.visible { + opacity: 1; + transform: translateY(0); + } + + .section-row { display: flex; - flex-wrap: wrap; + gap: 1rem; } - .demo { + .section-row.reverse { + flex-direction: row-reverse; + } + + .section-demo { + flex: 1 1 60%; + min-width: 0; + } + + .section-info { + flex: 1 1 40%; display: flex; flex-direction: column; - justify-content: center; - padding: 1rem; } - .demo img { - border-radius: 8px; - margin: 0.15rem; + .section-label { + font-size: 0.85rem; + letter-spacing: 0.15em; + color: var(--base04); + margin: 0 0 0.75rem 0; + font-weight: 500; + } + + .section-title { + font-size: clamp(1.5rem, 4vw, 2rem); + font-weight: 700; + margin: 0 0 1rem 0; + color: var(--base06); + line-height: 1.2; + letter-spacing: -0.02em; + } + + .section-description { + font-size: 1rem; + color: var(--base04); + margin: 0 0 1.5rem 0; + line-height: 1.6; + } + + .demo-note { + font-size: 0.8rem; + color: var(--base03); + margin: auto 0 0 0; + } + + .tools-section .section-info { + flex: 0 0 420px; + } + + .tools-and-demo { + flex: 1; + display: grid; + grid-template-columns: 1fr 1fr 2fr; + grid-template-rows: auto auto auto; + gap: 1rem; + min-width: 0; + } + + .tools-grid { + display: contents; + } + + .tool-card { + display: flex; + flex-direction: column; + padding: 1.25rem; + text-decoration: none; + color: inherit; + transition: + transform 0.2s ease, + box-shadow 0.2s ease; + } + + .tool-card:hover { + transform: translateY(-3px); + text-decoration: none; + } + + .tool-title { + font-size: 1rem; + font-weight: 600; + margin: 0 0 0.35rem 0; + color: var(--base06); + } + + .tool-description { + font-size: 0.85rem; + color: var(--base04); + margin: 0; + line-height: 1.4; + } + + .demo-card { + grid-column: 3; + grid-row: 1 / 4; + padding: 0; + overflow: hidden; + display: flex; + aspect-ratio: 230 / 123; + cursor: pointer; + transition: + transform 0.2s ease, + box-shadow 0.2s ease; + } + + .demo-card:hover { + transform: scale(1.02); + } + + .demo-card img { width: 100%; + height: 100%; + object-fit: fill; + border-radius: 8px; + } + + .cta { + display: inline-block; + padding: 0.75rem 1.5rem; + background-color: var(--base06); + color: var(--base00); + font-weight: 600; + font-size: 0.9rem; + border-radius: 6px; + text-decoration: none; + transition: + transform 0.2s ease, + box-shadow 0.2s ease; + align-self: flex-start; + } + + .cta:hover { + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + } + + .demo-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.85); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + cursor: pointer; + animation: fadeIn 0.2s ease; + } + + .demo-focused { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + animation: scaleIn 0.2s ease; } - .item-content { - flex: 1 1 50%; + .demo-focused img { + max-width: 90vw; + max-height: 80vh; + border-radius: 12px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); } - .item-description { - flex: 1 1 50%; + .demo-hint { + color: var(--base03); + font-size: 0.85rem; + margin: 0; } - .medium-text { - font-size: 1.125rem; + @keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } } - .big-text { - font-size: 1.25rem; + @keyframes scaleIn { + from { + transform: scale(0.9); + opacity: 0; + } + + to { + transform: scale(1); + opacity: 1; + } } - .bottom { - position: absolute; - bottom: 1em; + @media (max-width: 1000px) { + .tools-and-demo { + grid-template-columns: 1fr 1fr; + } + + .demo-card { + grid-column: 2; + grid-row: 1 / 4; + } + } + + @media (max-width: 800px) { + .section-row, + .section-row.reverse { + flex-direction: column; + } + + .section-demo, + .section-info { + flex: 1 1 100%; + } + + .section-info { + order: -1; + } + + .tools-section .section-info { + flex: 1 1 100%; + } + + .tools-and-demo { + grid-template-columns: 1fr 1fr; + grid-template-rows: auto auto auto; + } + + .demo-card { + grid-column: 1 / 3; + grid-row: auto; + max-height: 250px; + } + } + + @media (max-width: 500px) { + .tools-and-demo { + grid-template-columns: 1fr; + } + + .demo-card { + grid-column: 1; + } } </style> diff --git a/src/lib/List/Anime/AnimeListTemplate.svelte b/src/lib/List/Anime/AnimeListTemplate.svelte index 6e8d6d6c..bcd4e806 100644 --- a/src/lib/List/Anime/AnimeListTemplate.svelte +++ b/src/lib/List/Anime/AnimeListTemplate.svelte @@ -31,6 +31,7 @@ export let notYetReleased = false; export let dummy = false; export let disableFilter = false; + export let limit: number | undefined = undefined; let lastUpdatedMedia = -1; let previousAnimeList: Media[]; @@ -69,6 +70,7 @@ bind:pendingUpdate {dummy} {disableFilter} + {limit} /> {:else} <PlaceholderList count={lastListSize} {title} /> @@ -91,6 +93,7 @@ bind:pendingUpdate {dummy} {disableFilter} + {limit} /> {/if} {:catch} diff --git a/src/lib/List/Anime/CleanAnimeList.svelte b/src/lib/List/Anime/CleanAnimeList.svelte index fef76c03..04b1d03c 100644 --- a/src/lib/List/Anime/CleanAnimeList.svelte +++ b/src/lib/List/Anime/CleanAnimeList.svelte @@ -33,6 +33,7 @@ export let notYetReleased = false; export let dummy = false; export let disableFilter = false; + export let limit: number | undefined = undefined; let showRoulette = false; let keyCacher: NodeJS.Timeout; @@ -183,6 +184,7 @@ {upcoming} {notYetReleased} reverseSort={$settings.displayReverseSort} + {limit} > <div slot="title" let:title={anime} let:progress> {#if !upcoming && !notYetReleased} diff --git a/src/lib/List/Anime/CompletedAnimeList.svelte b/src/lib/List/Anime/CompletedAnimeList.svelte index 8e914ef6..b9e86ba0 100644 --- a/src/lib/List/Anime/CompletedAnimeList.svelte +++ b/src/lib/List/Anime/CompletedAnimeList.svelte @@ -18,7 +18,9 @@ tokenType: '' }; export let dummy = false; + export let dummyCount = 7; export let disableFilter = false; + export let limit: number | undefined = undefined; let animeLists: Promise<Media[]>; let startTime: number; let endTime: number; @@ -27,40 +29,29 @@ startTime = performance.now(); if (dummy) { + // Use deterministic selection for consistent display + const filtered = sampleAnime.filter( + (anime) => + anime.episodes && + !anime.tags.some((tag) => tag.name === 'Nudity') && + !anime.tags.some((tag) => tag.name === 'Rape') && + !anime.tags.some((tag) => tag.name === 'Tragedy') && + !anime.tags.some((tag) => tag.name === 'Bondage') && + !anime.genres.some((genre) => genre === 'Hentai') && + anime.genres.some((genre) => genre === 'Comedy') && + anime.status !== 'NOT_YET_RELEASED' && + anime.episodes > 1 + ); animeLists = Promise.resolve( - sampleAnime - .filter( - (anime) => - anime.episodes && - !anime.tags.some((tag) => tag.name === 'Nudity') && - !anime.tags.some((tag) => tag.name === 'Rape') && - !anime.tags.some((tag) => tag.name === 'Tragedy') && - !anime.tags.some((tag) => tag.name === 'Bondage') && - !anime.genres.some((genre) => genre === 'Hentai') && - anime.genres.some((genre) => genre === 'Comedy') && - anime.status !== 'NOT_YET_RELEASED' && - anime.episodes > 1 - ) - .sort(() => 0.5 - Math.random()) - .map((anime) => { - const nextEpisode = Math.floor(Math.random() * (anime.episodes || 0)) + 1 || 1; - - anime.status = 'FINISHED'; - anime.nextAiringEpisode = { - airingAt: - Math.floor(Date.now() / 1000) + - Math.floor(Math.random() * 7 * 24 * 60 * 60) + - 60 * 60, - episode: Math.floor(Math.random() * (anime.episodes || 0)) + 1 || 1 - }; - anime.mediaListEntry.progress = Math.floor(Math.random() * nextEpisode) || 1; - - return anime; - }) - .sort( - (a, b) => (a.nextAiringEpisode?.airingAt || 0) - (b.nextAiringEpisode?.airingAt || 0) - ) - .slice(0, 7) as unknown as Media[] + filtered.slice(0, dummyCount).map((anime, index) => { + anime.status = 'FINISHED'; + anime.nextAiringEpisode = { + airingAt: Math.floor(Date.now() / 1000) + (index + 1) * 24 * 60 * 60, + episode: Math.floor((anime.episodes || 12) * 0.8) + }; + anime.mediaListEntry.progress = Math.floor((anime.nextAiringEpisode.episode || 5) * 0.6); + return anime; + }) as unknown as Media[] ); } else { animeLists = mediaListCollection(user, $identity, Type.Anime, $anime, $lastPruneTimes.anime, { @@ -127,4 +118,5 @@ completed {dummy} {disableFilter} + {limit} /> diff --git a/src/lib/List/CleanGrid.svelte b/src/lib/List/CleanGrid.svelte index 119e4d71..ed4a9733 100644 --- a/src/lib/List/CleanGrid.svelte +++ b/src/lib/List/CleanGrid.svelte @@ -13,10 +13,12 @@ export let upcoming = false; export let notYetReleased = false; export let reverseSort = false; + export let limit: number | undefined = undefined; let uniqueID = new Date().getTime(); - $: processedMedia = reverseSort ? media.reverse() : media; + $: sortedMedia = reverseSort ? media.reverse() : media; + $: processedMedia = limit !== undefined ? sortedMedia.slice(0, limit) : sortedMedia; </script> <div diff --git a/src/lib/List/Manga/CleanMangaList.svelte b/src/lib/List/Manga/CleanMangaList.svelte index c337a053..f5af25fc 100644 --- a/src/lib/List/Manga/CleanMangaList.svelte +++ b/src/lib/List/Manga/CleanMangaList.svelte @@ -33,6 +33,7 @@ export let authorised: boolean; export let dummy = false; export let disableFilter = false; + export let limit: number | undefined = undefined; let showRoulette = false; let serviceStatusResponse: Promise<Response>; @@ -165,7 +166,7 @@ {/if} {#if $settings.displayCoverModeManga || dummy} - <CleanGrid media={filteredMedia} {dummy} type="manga"> + <CleanGrid media={filteredMedia} {dummy} type="manga" {limit}> <div slot="title" let:title={manga} let:progress> {pendingUpdate === manga.id ? progress + 1 : progress}{#if !due} <span class="opaque">/{manga.chapters || '?'}</span> diff --git a/src/lib/List/Manga/MangaListTemplate.svelte b/src/lib/List/Manga/MangaListTemplate.svelte index 16665d56..c2fc0513 100644 --- a/src/lib/List/Manga/MangaListTemplate.svelte +++ b/src/lib/List/Manga/MangaListTemplate.svelte @@ -31,7 +31,9 @@ export let displayUnresolved: boolean; export let due: boolean; export let dummy = $settings.debugDummyLists || false; + export let dummyCount = 7; export let disableFilter = false; + export let limit: number | undefined = undefined; const authorised = privilegedUser($identity.id); let mangaLists: Promise<Media[]>; let startTime: number; @@ -67,28 +69,25 @@ startTime = performance.now(); if (dummy) { + // Use deterministic selection for consistent display + const filtered = sampleManga.filter( + (manga) => + manga.chapters && + !manga.tags.some((tag) => tag.name === 'Nudity') && + !manga.tags.some((tag) => tag.name === 'Rape') && + !manga.tags.some((tag) => tag.name === 'Tragedy') && + !manga.tags.some((tag) => tag.name === 'Bondage') && + !manga.genres.some((genre) => genre === 'Hentai') && + manga.genres.some((genre) => genre === 'Comedy') && + manga.status !== 'NOT_YET_RELEASED' + ); mangaLists = Promise.resolve( - sampleManga - .filter( - (manga) => - manga.chapters && - !manga.tags.some((tag) => tag.name === 'Nudity') && - !manga.tags.some((tag) => tag.name === 'Rape') && - !manga.tags.some((tag) => tag.name === 'Tragedy') && - !manga.tags.some((tag) => tag.name === 'Bondage') && - !manga.genres.some((genre) => genre === 'Hentai') && - manga.genres.some((genre) => genre === 'Comedy') && - manga.status !== 'NOT_YET_RELEASED' - ) - .sort(() => 0.5 - Math.random()) - .map((manga) => { - manga.status = 'FINISHED'; - manga.episodes = Math.floor(Math.random() * (manga.chapters || 0)) as unknown as null; - manga.mediaListEntry.progress = Math.floor(Math.random() * (manga.episodes || 0)) + 1; - - return manga; - }) - .slice(0, 7) as unknown as Media[] + filtered.slice(0, dummyCount).map((manga) => { + manga.status = 'FINISHED'; + manga.episodes = Math.floor((manga.chapters || 10) * 0.7) as unknown as null; + manga.mediaListEntry.progress = Math.floor((manga.episodes || 5) * 0.5) + 1; + return manga; + }) as unknown as Media[] ); } else { mangaLists = mediaListCollection(user, $identity, Type.Manga, $manga, $lastPruneTimes.manga, { @@ -262,6 +261,7 @@ {authorised} {dummy} {disableFilter} + {limit} /> {:else} {#if !authorised} @@ -310,6 +310,7 @@ {authorised} {dummy} {disableFilter} + {limit} /> {:else} {#if !authorised} @@ -378,6 +379,7 @@ {authorised} {dummy} {disableFilter} + {limit} /> {:catch} {#if authorised} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index a66d10c2..ca356724 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -36,11 +36,7 @@ {#if data.user === undefined} <LandingHero /> - <Spacer /> - - <div class="card">Please log in to view due media.</div> - - <Spacer /> + <Spacer size="lg" /> <Landing /> {:else} |