The round summary used to disappear after a fixed 5 seconds. It is now derived from the game state: the previous round's result is shown while the new round is in bidding and hides once card play starts. This also survives a page reload. - Drop the client-side round timer from useWizard - On narrow screens show the summary in the page flow so it does not cover the bid buttons Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import { useEffect } from 'react'
|
|
import styles from './App.module.css'
|
|
import { useWizard } from './api/useWizard'
|
|
import { Toasts } from './components/Toasts/Toasts'
|
|
import { GameScreen } from './screens/GameScreen/GameScreen'
|
|
import { HomeScreen } from './screens/HomeScreen/HomeScreen'
|
|
import { LobbyScreen } from './screens/LobbyScreen/LobbyScreen'
|
|
|
|
const STATUS_MESSAGES = {
|
|
connecting: 'Connecting to the server…',
|
|
closed: 'Connection lost. Reconnecting…',
|
|
replaced: 'This game was opened in another window. Reload the page to continue here.',
|
|
} as const
|
|
|
|
function App() {
|
|
const { status, playerId, lobby, game, completedTrick, toasts, dismissToast, actions } = useWizard()
|
|
const lobbyCode = lobby?.code
|
|
|
|
// Keep the lobby code in the address bar so the URL can be shared as an invite link.
|
|
useEffect(() => {
|
|
if (lobbyCode) {
|
|
window.history.replaceState(null, '', `?lobby=${lobbyCode}`)
|
|
} else if (status === 'open' && window.location.search) {
|
|
window.history.replaceState(null, '', window.location.pathname)
|
|
}
|
|
}, [lobbyCode, status])
|
|
|
|
let screen
|
|
if (!lobby || !playerId) {
|
|
screen = <HomeScreen connected={status === 'open'} actions={actions} />
|
|
} else if (lobby.status === 'waiting' || !game) {
|
|
screen = <LobbyScreen lobby={lobby} playerId={playerId} actions={actions} />
|
|
} else {
|
|
screen = (
|
|
<GameScreen
|
|
lobby={lobby}
|
|
game={game}
|
|
playerId={playerId}
|
|
completedTrick={completedTrick}
|
|
actions={actions}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className={styles.app}>
|
|
{status !== 'open' && <div className={styles.banner}>{STATUS_MESSAGES[status]}</div>}
|
|
{screen}
|
|
<Toasts toasts={toasts} onDismiss={dismissToast} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default App
|