feat(ui): app-shell core — single-route dispatcher, route collapse, nav→state
Collapse the game UI to one route (`/`): a screen dispatcher renders login/lobby/lobby-create/game from `appScreen`/`activeView` state instead of URL routes. Move screen components to lib/screens & lib/game; the game shell reads the game id from `appScreen.gameId` and re-inits per-game stores via an $effect; in-game views render from `activeView`. Flip ~23 goto/href nav sites to store mutations; drop the `?sidebar=` URL coupling. Auth gate is now state-based. WIP: browser-history (Back→lobby), restore-validation, the return-to-lobby button, push deep-links, and the test migration are follow-ups on this branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,32 @@
|
||||
<script lang="ts">
|
||||
// The app root renders no content of its own. The root layout's auth
|
||||
// guard redirects "/" to /lobby (authenticated) or /login
|
||||
// (anonymous); this placeholder only shows for the brief moment
|
||||
// before that client-side redirect resolves.
|
||||
import { i18n } from "$lib/i18n/index.svelte";
|
||||
// Single-route screen dispatcher for the app-shell. There are no
|
||||
// per-screen routes: the visible screen is selected from in-memory
|
||||
// state (`session.status` for the auth gate, `appScreen.screen` for
|
||||
// the authenticated screen) rather than from the URL. The root
|
||||
// layout intercepts the `loading` and `unsupported` session states
|
||||
// before this component renders, so here `session.status` is either
|
||||
// `anonymous` (login) or `authenticated` (lobby / create / game).
|
||||
import { session } from "$lib/session-store.svelte";
|
||||
import { appScreen } from "$lib/app-nav.svelte";
|
||||
import LoginScreen from "$lib/screens/login-screen.svelte";
|
||||
import LobbyScreen from "$lib/screens/lobby-screen.svelte";
|
||||
import LobbyCreateScreen from "$lib/screens/lobby-create-screen.svelte";
|
||||
import GameShell from "$lib/game/game-shell.svelte";
|
||||
</script>
|
||||
|
||||
<main class="status">
|
||||
<p>{i18n.t("common.loading")}</p>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.status {
|
||||
padding: var(--space-6);
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
</style>
|
||||
{#if session.status === "authenticated"}
|
||||
{#if appScreen.screen === "lobby-create"}
|
||||
<LobbyCreateScreen />
|
||||
{:else if appScreen.screen === "game" && appScreen.gameId !== null}
|
||||
<GameShell />
|
||||
{:else}
|
||||
<!--
|
||||
Default authenticated screen. Covers `lobby`, a stale `login`
|
||||
screen restored from a previous anonymous session, and a `game`
|
||||
screen with no active game id (a snapshot that lost its id).
|
||||
-->
|
||||
<LobbyScreen />
|
||||
{/if}
|
||||
{:else}
|
||||
<LoginScreen />
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user