diff options
Diffstat (limited to 'src/lib/Landing.svelte')
| -rw-r--r-- | src/lib/Landing.svelte | 96 |
1 files changed, 81 insertions, 15 deletions
diff --git a/src/lib/Landing.svelte b/src/lib/Landing.svelte index dd493be4..604becee 100644 --- a/src/lib/Landing.svelte +++ b/src/lib/Landing.svelte @@ -1,8 +1,6 @@ <script lang="ts"> import root from "./Utility/root"; import { env } from "$env/dynamic/public"; -import CompletedAnimeList from "./List/Anime/CompletedAnimeList.svelte"; -import MangaListTemplate from "./List/Manga/MangaListTemplate.svelte"; import localforage from "localforage"; import { onMount } from "svelte"; @@ -11,10 +9,40 @@ let mangaContainer: HTMLElement; let animeContainer: HTMLElement; let gridLimit = $state<number | undefined>(undefined); let demoFocused = $state(false); +let MangaDemoComponent: typeof import("./LandingMangaDemo.svelte").default | null = + $state(null); +let AnimeDemoComponent: typeof import("./LandingAnimeDemo.svelte").default | null = + $state(null); +let mangaDemoImport: Promise<void> | null = null; +let animeDemoImport: Promise<void> | null = null; const COVER_WIDTH = 100; const COVER_GAP = 12; const dummyCount = 20; +const loadMangaDemo = () => { + if (MangaDemoComponent || mangaDemoImport) return; + + mangaDemoImport = import("./LandingMangaDemo.svelte") + .then((module) => { + MangaDemoComponent = module.default; + }) + .finally(() => { + mangaDemoImport = null; + }); +}; + +const loadAnimeDemo = () => { + if (AnimeDemoComponent || animeDemoImport) return; + + animeDemoImport = import("./LandingAnimeDemo.svelte") + .then((module) => { + AnimeDemoComponent = module.default; + }) + .finally(() => { + animeDemoImport = null; + }); +}; + const calculateLimit = () => { const container = mangaContainer || animeContainer; @@ -64,22 +92,25 @@ onMount(() => { document.removeEventListener("keydown", handleKeydown); }; }); + +$effect(() => { + if (sectionsVisible[0]) loadMangaDemo(); +}); + +$effect(() => { + if (sectionsVisible[1]) loadAnimeDemo(); +}); </script> <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> + {#if MangaDemoComponent} + <MangaDemoComponent {dummyCount} limit={gridLimit} /> + {:else} + <div class="demo-placeholder" aria-hidden="true"></div> + {/if} </div> <div class="section-info card"> @@ -112,9 +143,11 @@ onMount(() => { </div> <div class="section-demo card" bind:this={animeContainer}> - <details class="list" open> - <CompletedAnimeList dummy disableFilter {dummyCount} limit={gridLimit} /> - </details> + {#if AnimeDemoComponent} + <AnimeDemoComponent {dummyCount} limit={gridLimit} /> + {:else} + <div class="demo-placeholder" aria-hidden="true"></div> + {/if} </div> </div> </section> @@ -257,6 +290,25 @@ onMount(() => { min-width: 0; } + .demo-placeholder { + min-height: 28rem; + border-radius: inherit; + background: + linear-gradient( + 110deg, + color-mix(in srgb, var(--base01) 85%, transparent) 8%, + color-mix(in srgb, var(--base02) 70%, transparent) 18%, + color-mix(in srgb, var(--base01) 85%, transparent) 33% + ), + linear-gradient( + 180deg, + color-mix(in srgb, var(--base01) 88%, transparent), + color-mix(in srgb, var(--base00) 96%, transparent) + ); + background-size: 220% 100%, 100% 100%; + animation: demoPlaceholderShift 1.8s ease-in-out infinite; + } + .section-info { flex: 1 1 40%; display: flex; @@ -441,6 +493,16 @@ onMount(() => { } } + @keyframes demoPlaceholderShift { + 0% { + background-position: 100% 0, 0 0; + } + + 100% { + background-position: -100% 0, 0 0; + } + } + @media (max-width: 1000px) { .tools-and-demo { grid-template-columns: 1fr 1fr; @@ -463,6 +525,10 @@ onMount(() => { flex: 1 1 100%; } + .demo-placeholder { + min-height: 20rem; + } + .section-info { order: -1; } |