summaryrefslogblamecommitdiffstatshomepage
path: root/frontend/src/routes/+layout.svelte
blob: 0eefed1beb8932b2dca3f24781a8d7fd8943edeb (plain) (tree)






























































































                                                                                       
<script lang="ts">
	import { addShortcut, handleShortcuts } from '$lib/Shortcuts';
	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, closeModal, openModal } from 'svelte-modals';
	import { fade } from 'svelte/transition';
	import '../app.css';

	initContextClient({
		url: import.meta.env.VITE_GQL_ENDPOINT ?? '/graphql',
		exchanges: [cacheExchange, fetchExchange]
	});

	addShortcut('na', () => openModal(AddArtist));
	addShortcut('nh', () => openModal(AddCharacter));
	addShortcut('ni', () => openModal(AddCircle));
	addShortcut('nn', () => openModal(AddNamespace));
	addShortcut('nt', () => openModal(AddTag));
	addShortcut('nw', () => openModal(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]" />
	</Link>
	<Link href="/comics/" title="Comics" accel="gc">
		<span class="icon-base icon-[material-symbols--menu-book]" />
	</Link>
	<Link href="/namespaces/" title="Namespaces" accel="gn">
		<span class="icon-base icon-[material-symbols--inbox]" />
	</Link>
	<Link href="/tags/" title="Tags" accel="gt">
		<span class="icon-base icon-[material-symbols--label]" />
	</Link>
	<Link href="/artists/" title="Artists" accel="ga">
		<span class="icon-base icon-[material-symbols--person]" />
	</Link>
	<Link href="/circles/" title="Circles" accel="gi">
		<span class="icon-base icon-[material-symbols--group]" />
	</Link>
	<Link href="/characters/" title="Characters" accel="gh">
		<span class="icon-base icon-[material-symbols--face]" />
	</Link>
	<Link href="/worlds/" title="Worlds" accel="gw">
		<span class="icon-base icon-[material-symbols--public]" />
	</Link>
	<Link href="/archives/" title="Archives" accel="gz">
		<span class="icon-base icon-[material-symbols--folder-zip]" />
	</Link>
	<div class="mb-auto" />
	<Link href="/help/" title="Help" accel="?" target="_blank">
		<span class="icon-base icon-[material-symbols--help]" />
	</Link>
</Navigation>

<div class="min-w-[360px] overflow-auto p-4">
	<slot />
</div>

<Modals>
	<!-- svelte-ignore a11y-no-static-element-interactions -->
	<!-- svelte-ignore a11y-click-events-have-key-events -->
	<div
		slot="backdrop"
		on:click={closeModal}
		transition:fade={fadeDefault}
		class="fixed bottom-0 left-0 right-0 top-0 z-20 bg-stone-800/80"
	/>
</Modals>

<SvelteToast options={{ reversed: true, intro: { y: 192 } }} />

<style>
	:root {
		--toastBarHeight: 0;
		--toastContainerTop: auto;
		--toastContainerLeft: 4rem;
		--toastContainerBottom: 1rem;
	}
</style>