I Want To Heal 2 build v1.0.2

This commit is contained in:
Warren H
2026-06-24 11:51:44 -04:00
parent de0a892484
commit 8abb44ea02
15 changed files with 897 additions and 36 deletions
+101
View File
@@ -0,0 +1,101 @@
import { useEffect, useState } from 'react'
import {
hydrateLocalSaveFromServer,
loadSession,
localCloudSave,
logoutAccount,
pushCloudSave,
type AuthSession,
} from './actionApi'
import type { ActionMechanicConfig } from './actionBoss/actionEncounterConfig'
import type { ActionCharacter } from './actionMode'
import { ActionModeScreen } from './components/ActionModeScreen'
import { AuthScreen } from './components/AuthScreen'
export function App() {
const [session, setSession] = useState<AuthSession | null>(null)
const [loading, setLoading] = useState(true)
const [message, setMessage] = useState('')
const [screenKey, setScreenKey] = useState(0)
useEffect(() => {
let cancelled = false
async function start() {
try {
const nextSession = await loadSession()
if (!nextSession.account) {
if (!cancelled) setSession(nextSession)
return
}
const syncStatus = await hydrateLocalSaveFromServer()
if (!cancelled) {
setSession(nextSession)
setScreenKey((current) => current + 1)
setMessage(syncStatus === 'loaded' ? 'Server save loaded.' : '')
}
} catch {
if (!cancelled) setMessage('Server unavailable. Sign in when it comes back online.')
} finally {
if (!cancelled) setLoading(false)
}
}
start()
return () => {
cancelled = true
}
}, [])
async function handleAuthenticated(nextSession: AuthSession) {
if (nextSession.account) {
const syncStatus = await hydrateLocalSaveFromServer()
setMessage(syncStatus === 'loaded' ? 'Server save loaded.' : 'Local save uploaded.')
setScreenKey((current) => current + 1)
}
setSession(nextSession)
}
async function handleLogout() {
await logoutAccount()
setSession({ account: null })
setMessage('Signed out.')
}
function syncCharacter(character: ActionCharacter) {
if (!session?.account) return
pushCloudSave({ ...localCloudSave(), character }).catch(() => null)
}
function syncMechanics(mechanics: ActionMechanicConfig) {
if (!session?.account) return
pushCloudSave({ ...localCloudSave(), mechanics }).catch(() => null)
}
if (loading) {
return (
<main className="auth-shell">
<section className="auth-panel single">
<div className="auth-card">
<p className="eyebrow">Loading</p>
<h1>Connecting</h1>
<p className="auth-message">Checking server session.</p>
</div>
</section>
</main>
)
}
if (!session?.account) {
return <AuthScreen onAuthenticated={handleAuthenticated} serverMessage={message} />
}
return (
<ActionModeScreen
key={screenKey}
account={session.account}
onCharacterSaved={syncCharacter}
onLogout={handleLogout}
onMechanicsSaved={syncMechanics}
serverMessage={message}
/>
)
}