90 lines
2.4 KiB
Svelte
90 lines
2.4 KiB
Svelte
<script>
|
|
import "./app.css";
|
|
import Header from "./lib/Header.svelte";
|
|
import Library from "./pages/Library.svelte";
|
|
import GameDetail from "./pages/GameDetail.svelte";
|
|
import Play from "./pages/Play.svelte";
|
|
|
|
let route = $state("/");
|
|
let gameId = $state(null);
|
|
|
|
function parseRoute() {
|
|
// Check pathname first (full page navigations from Stop button)
|
|
const path = window.location.pathname.replace(/\/+$/, "") || "/";
|
|
if (path !== "/") {
|
|
const parts = path.split("/").filter(Boolean);
|
|
if (parts.length >= 2) {
|
|
const [routeName, routeId] = parts;
|
|
if (routeName === "game" || routeName === "play") {
|
|
route = "/" + routeName;
|
|
gameId = routeId;
|
|
// Sync the hash so hash-based links still work
|
|
window.history.replaceState(null, "", "#/" + routeName + "/" + routeId);
|
|
return;
|
|
}
|
|
}
|
|
// Unknown path, reset to home
|
|
route = "/";
|
|
gameId = null;
|
|
return;
|
|
}
|
|
|
|
// Fall back to hash-based routing (SPA transitions)
|
|
const hash = window.location.hash.slice(1) || "/";
|
|
const parts = hash.split("/").filter(Boolean);
|
|
if (parts.length === 0 || (parts.length === 1 && parts[0] === "")) {
|
|
route = "/";
|
|
gameId = null;
|
|
} else if (parts[0] === "game" && parts[1]) {
|
|
route = "/game";
|
|
gameId = parts[1];
|
|
} else if (parts[0] === "play" && parts[1]) {
|
|
route = "/play";
|
|
gameId = parts[1];
|
|
} else {
|
|
route = "/";
|
|
gameId = null;
|
|
}
|
|
}
|
|
|
|
// Listen for hash changes and page loads
|
|
$effect(() => {
|
|
parseRoute();
|
|
const handler = () => parseRoute();
|
|
window.addEventListener("hashchange", handler);
|
|
// Also listen for popstate (for browser back/forward)
|
|
window.addEventListener("popstate", handler);
|
|
return () => {
|
|
window.removeEventListener("hashchange", handler);
|
|
window.removeEventListener("popstate", handler);
|
|
};
|
|
});
|
|
</script>
|
|
|
|
<Header />
|
|
|
|
<main class="container">
|
|
{#if route === "/"}
|
|
<Library />
|
|
{:else if route === "/game" && gameId}
|
|
<GameDetail id={gameId} />
|
|
{:else if route === "/play" && gameId}
|
|
<Play id={gameId} />
|
|
{:else}
|
|
<div class="empty">
|
|
<h2>Page not found</h2>
|
|
<a href="#/">Back to Library</a>
|
|
</div>
|
|
{/if}
|
|
</main>
|
|
|
|
<style>
|
|
.empty {
|
|
text-align: center;
|
|
padding: 80px 20px;
|
|
}
|
|
.empty h2 {
|
|
margin-bottom: 16px;
|
|
}
|
|
</style>
|