import { useState, useEffect } from 'react' import { generateToken, loadState, saveState } from './api.js' import { createState } from './gameState.js' import { BACKGROUNDS } from './constants.js' import Shell from './components/Shell.jsx' import Actor from './screens/Actor.jsx' import Forum from './screens/Forum.jsx' import Map from './screens/Map.jsx' import './App.css' import contextsJson from './config/contexts.json' const TOKEN_KEY = 'otivm_token' export default function App() { const [state, setState] = useState(null) const [token, setToken] = useState(null) const [loading, setLoading] = useState(true) const [context, setContext] = useState('actor') useEffect(() => { async function bootstrap() { let tok = localStorage.getItem(TOKEN_KEY) if (!tok) { tok = generateToken() localStorage.setItem(TOKEN_KEY, tok) } setToken(tok) const saved = await loadState(tok) if (saved) { setState(saved) setContext(saved.background_id && saved.background_id !== 'unknown' ? 'forum' : 'actor') } else { const fresh = createState(tok) setState(fresh) await saveState(tok, fresh) setContext('actor') } setLoading(false) } bootstrap() }, []) async function onStateChange(newState) { setState(newState) await saveState(token, newState) } async function onSelectBackground(backgroundId) { const bg = BACKGROUNDS.find(b => b.id === backgroundId) if (!bg) return const updated = { ...state, background_id: backgroundId, den: bg.starting_den } setState(updated) await saveState(token, updated) setContext('forum') } async function onNewGame() { if (state && token) { const abandoned = { ...state, events: [ ...(state.events || []), { type: 'session_abandoned', route_id: null, timestamp_utc: new Date().toISOString() }, ], } await saveState(token, abandoned) } const newTok = generateToken() localStorage.setItem(TOKEN_KEY, newTok) setToken(newTok) const fresh = createState(newTok) setState(fresh) await saveState(newTok, fresh) setContext('actor') } if (loading) { return
Consulting the ledger...
} const activeCtx = contextsJson.find(c => c.id === context) || contextsJson[0] const layout = activeCtx.layout const subitems = activeCtx.subitems || [] return ( {/* ACTOR */} {context === 'actor' && ( )} {/* FORUM */} {context === 'forum' && ( )} {/* MAP */} {context === 'map' && ( )} ) }