<script lang="ts"> import { addShortcut, handleShortcuts } from '$lib/Shortcuts'; import { toastFinally } from '$lib/Toasts'; import { fadeDefault } from '$lib/Transitions'; import AddArtist from '$lib/dialogs/AddArtist.svelte'; import AddCharacter from '$lib/dialogs/AddCharacter.svelte'; import AddCircle from '$lib/dialogs/AddCircle.svelte'; import AddNamespace from '$lib/dialogs/AddNamespace.svelte'; import AddTag from '$lib/dialogs/AddTag.svelte'; import AddWorld from '$lib/dialogs/AddWorld.svelte'; import Link from '$lib/navigation/Link.svelte'; import Navigation from '$lib/navigation/Navigation.svelte'; import { cacheExchange, fetchExchange, initContextClient } from '@urql/svelte'; import { SvelteToast } from '@zerodevx/svelte-toast'; import { Modals, modals, type ModalComponent } from 'svelte-modals'; import { fade } from 'svelte/transition'; import '../app.css'; initContextClient({ url: import.meta.env.VITE_GQL_ENDPOINT ?? '/graphql', exchanges: [cacheExchange, fetchExchange] }); function open(modal: ModalComponent) { modals.open(modal).catch(toastFinally); } addShortcut('na', () => open(AddArtist)); addShortcut('nh', () => open(AddCharacter)); addShortcut('ni', () => open(AddCircle)); addShortcut('nn', () => open(AddNamespace)); addShortcut('nt', () => open(AddTag)); addShortcut('nw', () => open(AddWorld)); function keydown(event: KeyboardEvent) { handleShortcuts(event); } </script> <svelte:document on:keydown={keydown} /> <Navigation> <Link matchExact href="/" title="Home" accel="go"> <span class="icon-base icon-[material-symbols--home]"></span> </Link> <Link href="/comics/" title="Comics" accel="gc"> <span class="icon-base icon-[material-symbols--menu-book]"></span> </Link> <Link href="/namespaces/" title="Namespaces" accel="gn"> <span class="icon-base icon-[material-symbols--inbox]"></span> </Link> <Link href="/tags/" title="Tags" accel="gt"> <span class="icon-base icon-[material-symbols--label]"></span> </Link> <Link href="/artists/" title="Artists" accel="ga"> <span class="icon-base icon-[material-symbols--person]"></span> </Link> <Link href="/circles/" title="Circles" accel="gi"> <span class="icon-base icon-[material-symbols--group]"></span> </Link> <Link href="/characters/" title="Characters" accel="gh"> <span class="icon-base icon-[material-symbols--face]"></span> </Link> <Link href="/worlds/" title="Worlds" accel="gw"> <span class="icon-base icon-[material-symbols--public]"></span> </Link> <Link href="/archives/" title="Archives" accel="gz"> <span class="icon-base icon-[material-symbols--folder-zip]"></span> </Link> <div class="mb-auto"></div> <Link href="/statistics/" title="Statistics" accel="gs"> <span class="icon-base icon-[material-symbols--bar-chart]"></span> </Link> <Link href="/help/" title="Help" accel="?" target="_blank"> <span class="icon-base icon-[material-symbols--help]"></span> </Link> </Navigation> <div class="min-w-[360px] overflow-auto p-4" tabindex="-1"> <slot /> </div> <Modals> {#snippet backdrop({ close })} <!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-click-events-have-key-events --> <div onclick={() => close()} transition:fade={fadeDefault} class="fixed bottom-0 left-0 right-0 top-0 z-20 bg-stone-800/80" ></div> {/snippet} </Modals> <SvelteToast options={{ reversed: true, intro: { y: 192 } }} /> <style> :root { --toastBarHeight: 0; --toastContainerTop: auto; --toastContainerLeft: 4rem; --toastContainerBottom: 1rem; } </style>