Files
i-want-to-heal-2/src/App.tsx
T

113 lines
3.1 KiB
TypeScript

import { useEffect, useState } from 'react'
import {
hydrateLocalSaveFromServer,
loadSession,
localCloudSave,
logoutAccount,
pushCloudSave,
type AuthSession,
} from './actionApi'
import type { ActionMechanicConfig } from './actionBoss/actionEncounterConfig'
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)
}
function handlePlayOffline() {
setSession({ account: null, offline: true })
setMessage('')
setScreenKey((current) => current + 1)
}
async function handleLogout() {
if (!session?.offline) await logoutAccount()
setSession({ account: null })
setMessage(session?.offline ? 'Offline mode ended.' : 'Signed out.')
}
function syncCharacter() {
if (!session?.account) return
pushCloudSave(localCloudSave()).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 && !session?.offline) {
return (
<AuthScreen
onAuthenticated={handleAuthenticated}
onPlayOffline={handlePlayOffline}
serverMessage={message}
/>
)
}
return (
<ActionModeScreen
key={screenKey}
account={session.account ?? undefined}
authActionLabel={session.offline ? 'Sign In' : 'Logout'}
onCharacterSaved={syncCharacter}
onLogout={handleLogout}
onMechanicsSaved={syncMechanics}
/>
)
}