diff --git a/wizard_website/src/App.tsx b/wizard_website/src/App.tsx index 3fb4343..9b314a9 100644 --- a/wizard_website/src/App.tsx +++ b/wizard_website/src/App.tsx @@ -13,8 +13,7 @@ const STATUS_MESSAGES = { } as const function App() { - const { status, playerId, lobby, game, completedTrick, completedRound, toasts, dismissToast, actions } = - useWizard() + 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. @@ -38,7 +37,6 @@ function App() { game={game} playerId={playerId} completedTrick={completedTrick} - completedRound={completedRound} actions={actions} /> ) diff --git a/wizard_website/src/api/useWizard.ts b/wizard_website/src/api/useWizard.ts index a01f66c..ba9a260 100644 --- a/wizard_website/src/api/useWizard.ts +++ b/wizard_website/src/api/useWizard.ts @@ -5,7 +5,6 @@ import type { GameOptions, GameView, Lobby, - RoundResult, ServerMessage, TrickResult, } from './types' @@ -20,7 +19,6 @@ export interface Toast { // Per tab, so several tabs can act as different players; survives reloads. const TOKEN_KEY = 'wizard.token' const TRICK_DISPLAY_MS = 2200 -const ROUND_DISPLAY_MS = 5000 const TOAST_MS = 4000 const MAX_RETRY_DELAY_MS = 10000 // Close code the server uses when the session was opened in another tab. @@ -60,8 +58,6 @@ export function useWizard() { const [game, setGame] = useState(null) // The most recently completed trick, shown for a moment before it is cleared. const [completedTrick, setCompletedTrick] = useState(null) - // Result of the round that just ended, shown as a short summary. - const [completedRound, setCompletedRound] = useState(null) const [toasts, setToasts] = useState([]) const socketRef = useRef(null) @@ -82,7 +78,6 @@ export function useWizard() { let attempt = 0 let retryTimer: ReturnType | undefined let trickTimer: ReturnType | undefined - let roundTimer: ReturnType | undefined const handleMessage = (message: ServerMessage) => { switch (message.type) { @@ -99,16 +94,7 @@ export function useWizard() { clearTimeout(trickTimer) trickTimer = setTimeout(() => setCompletedTrick(null), TRICK_DISPLAY_MS) } - const round = message.events.find((event) => event.type === 'round_completed') - if (round) { - setCompletedRound(round.result) - clearTimeout(roundTimer) - roundTimer = setTimeout(() => setCompletedRound(null), ROUND_DISPLAY_MS) - } - if (!message.game) { - setCompletedTrick(null) - setCompletedRound(null) - } + if (!message.game) setCompletedTrick(null) break } case 'error': @@ -155,7 +141,6 @@ export function useWizard() { disposed = true clearTimeout(retryTimer) clearTimeout(trickTimer) - clearTimeout(roundTimer) socketRef.current?.close() socketRef.current = null } @@ -188,7 +173,7 @@ export function useWizard() { [send], ) - return { status, playerId, lobby, game, completedTrick, completedRound, toasts, dismissToast, actions } + return { status, playerId, lobby, game, completedTrick, toasts, dismissToast, actions } } export type WizardActions = ReturnType['actions'] diff --git a/wizard_website/src/screens/GameScreen/GameScreen.tsx b/wizard_website/src/screens/GameScreen/GameScreen.tsx index 5f8e961..a64226c 100644 --- a/wizard_website/src/screens/GameScreen/GameScreen.tsx +++ b/wizard_website/src/screens/GameScreen/GameScreen.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import type { GameView, Lobby, RoundResult, TrickResult } from '../../api/types' +import type { GameView, Lobby, TrickResult } from '../../api/types' import type { WizardActions } from '../../api/useWizard' import { Button } from '../../components/Button/Button' import { Modal } from '../../components/Modal/Modal' @@ -19,11 +19,10 @@ interface GameScreenProps { game: GameView playerId: string completedTrick: TrickResult | null - completedRound: RoundResult | null actions: WizardActions } -export function GameScreen({ lobby, game, playerId, completedTrick, completedRound, actions }: GameScreenProps) { +export function GameScreen({ lobby, game, playerId, completedTrick, actions }: GameScreenProps) { const [showScores, setShowScores] = useState(false) const [confirmLeave, setConfirmLeave] = useState(false) @@ -62,6 +61,12 @@ export function GameScreen({ lobby, game, playerId, completedTrick, completedRou else if (trumpCard?.kind === 'wizard') trumpText = 'Wizard turned up — no trump' else if (trumpCard?.kind === 'jester') trumpText = 'Jester turned up — no trump' + // The result of the previous round stays visible until everyone has bid in + // the new round (i.e. until the round moves on to playing cards). + const previousRound = obs.round_history.at(-1) + const showPreviousRound = + obs.phase === 'bidding' && previousRound !== undefined && previousRound.round_number === obs.round_number - 1 + return (
@@ -82,6 +87,8 @@ export function GameScreen({ lobby, game, playerId, completedTrick, completedRou
+ {showPreviousRound && } +
{opponents.map((seat) => ( @@ -112,7 +119,6 @@ export function GameScreen({ lobby, game, playerId, completedTrick, completedRou
- {completedRound && obs.phase !== 'finished' && } {showScores && ( setShowScores(false)}> diff --git a/wizard_website/src/screens/GameScreen/RoundSummary.module.css b/wizard_website/src/screens/GameScreen/RoundSummary.module.css index ddf5a46..a528fb8 100644 --- a/wizard_website/src/screens/GameScreen/RoundSummary.module.css +++ b/wizard_website/src/screens/GameScreen/RoundSummary.module.css @@ -66,12 +66,11 @@ } } +/* On small screens it would cover the bid buttons; show it in the page flow instead. */ @media (max-width: 720px) { .summary { - top: auto; - right: 50%; - bottom: 16px; - transform: translateX(50%); - animation: none; + position: static; + width: 100%; + box-shadow: none; } }