Replace the writable+derived store pipeline in state.ts with a state.svelte.ts module: a deep $state inputState mutated only through the exported update functions, each of which persists the snapshot and re-validates it asynchronously into validatedState.current (with urls.current derived from it). Store subscriptions in components become $effect blocks, and the rough/grid toggles use function bindings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
88 lines
2.1 KiB
Svelte
88 lines
2.1 KiB
Svelte
<script lang="ts">
|
|
import { Toaster } from '$/components/ui/sonner/index.js';
|
|
import { loadingStateStore } from '$/util/loading';
|
|
import { toggleDarkTheme } from '$/util/state.svelte';
|
|
import { initHandler } from '$/util/util';
|
|
import { base } from '$app/paths';
|
|
import { mode, ModeWatcher } from 'mode-watcher';
|
|
import { onMount, type Snippet } from 'svelte';
|
|
import '../app.css';
|
|
|
|
interface Props {
|
|
children: Snippet;
|
|
}
|
|
|
|
let { children }: Props = $props();
|
|
|
|
// This can be removed once https://github.com/sveltejs/kit/issues/1612 is fixed.
|
|
// Then move it into src and vite will bundle it automatically.
|
|
onMount(() => {
|
|
window.addEventListener('hashchange', () => {
|
|
void initHandler();
|
|
});
|
|
|
|
if ('serviceWorker' in navigator) {
|
|
navigator.serviceWorker
|
|
.register(`${base}/service-worker.js`, { scope: `${base}/` })
|
|
.then(function (registration) {
|
|
console.log('Registration successful, scope is:', registration.scope);
|
|
})
|
|
.catch(function (error) {
|
|
console.log('Service worker registration failed, error:', error);
|
|
});
|
|
}
|
|
});
|
|
|
|
$effect(() => {
|
|
toggleDarkTheme(mode.current === 'dark');
|
|
});
|
|
</script>
|
|
|
|
<ModeWatcher />
|
|
<Toaster />
|
|
|
|
<main class="h-dvh">
|
|
{@render children()}
|
|
</main>
|
|
|
|
{#if $loadingStateStore.loading}
|
|
<div
|
|
class="absolute top-0 left-0 z-50 flex h-screen w-screen justify-center bg-gray-600 align-middle opacity-50">
|
|
<div class="my-auto text-4xl font-bold text-indigo-100">
|
|
<div class="loader mx-auto"></div>
|
|
<div>{$loadingStateStore.message}</div>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<style>
|
|
.loader {
|
|
border: 0.45em solid #f3f3f3;
|
|
border-radius: 50%;
|
|
border-top: 0.45em solid #6365f1;
|
|
width: 3em;
|
|
height: 3em;
|
|
-webkit-animation: spin 2s linear infinite; /* Safari */
|
|
animation: spin 2s linear infinite;
|
|
}
|
|
|
|
/* Safari */
|
|
@-webkit-keyframes spin {
|
|
0% {
|
|
-webkit-transform: rotate(0deg);
|
|
}
|
|
100% {
|
|
-webkit-transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
</style>
|