initial commit

This commit is contained in:
Moon.eth
2026-07-29 09:16:38 +09:00
commit 586b599d4c
67 changed files with 9906 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
<script lang="ts">
/**
* Shell: restore the session, then render chrome plus whichever route matched.
*/
import { router } from '$lib/router.svelte'
import { session } from '$lib/stores/session.svelte'
import SiteHeader from '$components/chrome/SiteHeader.svelte'
import SiteNav from '$components/chrome/SiteNav.svelte'
import SiteFooter from '$components/chrome/SiteFooter.svelte'
import Home from '$routes/Home.svelte'
import Profile from '$routes/Profile.svelte'
import Timeline from '$routes/Timeline.svelte'
import StatusPage from '$routes/StatusPage.svelte'
import Mail from '$routes/Mail.svelte'
import Browse from '$routes/Browse.svelte'
import Search from '$routes/Search.svelte'
import Login from '$routes/Login.svelte'
import Settings from '$routes/Settings.svelte'
import Compose from '$routes/Compose.svelte'
import NotFound from '$routes/NotFound.svelte'
import type { TimelineKind } from '$lib/api/endpoints'
let booted = $state(false)
$effect(() => {
void (async () => {
const landing = await session.restore()
booted = true
if (landing) {
router.go(landing)
} else if (!session.host && router.current.name !== 'login') {
// No server chosen yet — everything else would 404 against nothing.
router.replace('#/login')
}
})()
})
const route = $derived(router.current)
/** Route names that are usable before a server is chosen. */
const ALWAYS_AVAILABLE = new Set(['login', 'settings', 'notfound'])
const TIMELINE_KINDS: readonly TimelineKind[] = ['home', 'public', 'local']
const timelineKind = $derived<TimelineKind>(
TIMELINE_KINDS.includes(route.params.kind as TimelineKind)
? (route.params.kind as TimelineKind)
: 'public',
)
</script>
<div class="site">
<SiteHeader />
<SiteNav />
{#if !booted}
<div class="page">
<p class="loading-note">Starting up&hellip;</p>
</div>
{:else if !session.host && !ALWAYS_AVAILABLE.has(route.name)}
<Login />
{:else if route.name === 'home'}
<Home />
{:else if route.name === 'profile'}
<Profile acct={route.params.acct} view="profile" />
{:else if route.name === 'profile.blog'}
<Profile acct={route.params.acct} view="blog" />
{:else if route.name === 'profile.friends'}
<Profile acct={route.params.acct} view="friends" />
{:else if route.name === 'profile.pics'}
<Profile acct={route.params.acct} view="pics" />
{:else if route.name === 'timeline'}
<Timeline kind={timelineKind} />
{:else if route.name === 'tag'}
<Timeline kind="tag" tag={route.params.tag} />
{:else if route.name === 'blog.entry'}
<StatusPage id={route.params.id} />
{:else if route.name === 'mail'}
<Mail folder="inbox" />
{:else if route.name === 'mail.folder'}
<Mail folder={route.params.folder} />
{:else if route.name === 'browse'}
<Browse />
{:else if route.name === 'search'}
<Search q={route.query.get('q') ?? ''} />
{:else if route.name === 'compose'}
<Compose to={route.query.get('to') ?? undefined} />
{:else if route.name === 'login'}
<Login />
{:else if route.name === 'settings'}
<Settings />
{:else}
<NotFound />
{/if}
<SiteFooter />
</div>