Fix save/resume after refresh + map basemap
Map (basemap was rendering black): - Inline MapLibre style (dark-navy background + subtle OpenFreeMap ne2sr raster) instead of the remote "dark" style, whose vector tiles are empty at world zoom and gated the choropleth on a remote styledata fetch. - Explicit prod worker URL (maplibre-gl-worker via ?url) so GeoJSON sources process in the production bundle. - Hardened the choropleth against geo load-order races (empty sources up front, ownership stamped once data lands) and bumped fill opacity so the vivid per-nation colors are the star on the non-black background. Save/resume (a refresh used to drop users to the home screen): - Persist the active game id in localStorage (history.activeGameId) on create and resume; clear it when explicitly starting a new game. - Auto-resume the last game on a page refresh (GET /api/games/:id + /map), re-attaching the SSE stream; fall back to home gracefully if it's gone. - Home screen: prominent "Resume last game" button + a "Saved games" section (newest first). New GET /api/games list endpoint. e2e: two new deterministic tests — auto-resume-on-reload and explicit resume from the home screen (both under LLM_STUB=1). Quality gates: typecheck, lint, 21 unit tests, 3 e2e tests — all pass.
This commit is contained in:
+4
-1
@@ -2,7 +2,7 @@
|
||||
// proxied by Vite in dev and served by Express in prod), so no origin is ever
|
||||
// hardcoded — this works unchanged behind the Traefik proxy.
|
||||
import type { GameState, Preset, PresetMeta } from '@shared/types';
|
||||
import type { AdvisorResponse, CreateGameResponse, TurnResponse } from '@shared/protocol';
|
||||
import type { AdvisorResponse, CreateGameResponse, GameSummary, TurnResponse } from '@shared/protocol';
|
||||
|
||||
async function req<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(path, {
|
||||
@@ -25,6 +25,9 @@ export const api = {
|
||||
body: JSON.stringify({ presetId, playerNationId }),
|
||||
}),
|
||||
getGame: (id: string) => req<{ game: GameState }>(`/api/games/${id}`),
|
||||
// Every saved game as a lightweight summary, newest-updated first (for the
|
||||
// home screen's "Saved games" section / resume affordances).
|
||||
listGames: () => req<{ games: GameSummary[] }>('/api/games'),
|
||||
turn: (id: string, action?: string, chat?: { to: string; message: string }) =>
|
||||
req<TurnResponse>(`/api/games/${id}/turn`, {
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user