Migrate pending games into the GameDetail shell - #1008
Conversation
Pending games now land on the shell's phase-scoped game-info route instead of a standalone Home screen, since every pending game already has a real PENDING phase from create_from_template. GameDetailLayout shows only the Game Info tab (no Map/Orders/Chat) and hides the desktop map panel for pending games, avoiding the nation-scoped endpoints that a non-member spectator can't access. The join/leave/ share/add-bot action block moves from Home/GameInfo.tsx into the shared GameInfoContent so both the retired Home route and the shell render identically; the Home /game-info/:gameId route is retired and its remaining callers redirect through /game/:gameId instead. Closes #903 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Warning WIP limit exceeded. There are now 6 open pull requests — the project target is 5 or fewer. Please close or merge an existing PR before continuing with this one. |
✅ Deploy Preview for diplicity-variant-creator canceled.
|
- GameDetailLayout: the main content column kept its fixed 360px desktop width even when the map panel was hidden for pending games, leaving a large blank gap (visible in the first round of PR screenshots) — the width is now conditional on the map panel being shown. - Add QueryErrorBoundary to the shell's GameInfoScreen, matching every sibling GameDetail screen — previously an unhandled fetch error here would crash to the root error boundary, and pending games have no other tab to fall back to. - Remove the retired /game-info/* path from the iOS universal-link config; it no longer matches any route. - Extract the repeated "game-info path or fall back to /game/:id" ternary (GameCard, PlayerInfo) into a shared getGameInfoPath helper. - Fix mock pending-game phase fixtures to carry the classical starting deployment instead of an empty board — create_from_template already populates units/supply centers at game creation, so the mocks were understating what a real pending game's map preview looks like. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
johnpooch
left a comment
There was a problem hiding this comment.
PR Review
This PR routes pending games through the shell's Game Info tab instead of the standalone Home screen, retires the old /game-info/:gameId route, and moves the join/leave/share/add-bot action block into the shared GameInfoContent so both entry points render identically.
I traced the key correctness-sensitive paths:
getGameLandingPath/getGameInfoPathnavigation logic, including the fallback to/whencurrentPhaseIdis null — matches updated test expectations and the mock fixture fix (pending games now always carry a real phase, consistent with backend'screate_from_templateguarantee).- Spectator access: confirmed
GameRetrieveViewandPhaseRetrieveViewboth usepermissions.AllowAnyserver-side, so the new non-member spectator path inGameInfoContent(join button, map preview viauseGamePhaseRetrieve) doesn't hit a permission wall. GameDetailLayout's nav-item filtering and conditional map panel/content-width logic forstatus === "pending"— no dangling references to the removed Home/game-inforoute orHome.GameInfoScreenexport.- Fixture builder change (
makeGamenow takesphases[phases.length - 1]as current phase instead of searching for "active") — verified against all existing callers ingames.ts; order is always chronological with the active/final phase last, so no behavior change for existing fixtures.
Ran npm run test (510 tests, all passing), npx tsc -b --noEmit (clean), and npm run lint (clean).
No issues found — nothing to flag.
Generated by Claude Code
|
<@688641092278681600> I feel like this change is totally wrong: #1008 What do you think? I would have assumed the player could see the map during the pending state. This looks totally weird. Also, these three PRs all feel like a stack: I feel like we should address these one at a time. Otherwise it's overwhelming First i think only "add backend" and "add game-info as shell" (so later chat - and possibly map - can be added) should run Effectively, in my vision, the game detail screen becomes the lobby where the players are waiting for the game to start. It would appear the exact same as it does after the game starts, but the player just can't interact with the map yet. Game info: all about the game and zoomy map Ideally I'd have the "chat" tab open the public press CONTENT immediately, but I thought that was unnecessary complexity. The game info screen looks horrible when stretched out like it is in the PR. This just doesn't feel properly thought through. By far the simplest approach is to do what I'm describing. When you're INTO a game it now shows the 'info' sidebar item (bottom on mobile) where you can see the same info as now, same join/leave/share info - it's the same for members/non-members, only the join element in the game info changes (like now). But in ADDITION you have the 'Chat' sidebar item (bottom on mobile) where you can see the chats (same for members/non members, only members can add to chat). Remove the 'add channel' in this mock up - I forgot to remove that The same for a pending game - 'My games > Staging games > Game content. If I want to go to another staging game, the navigation should be Game content A > Staging Games > Game content B, but I can't - I have to go to Game Content A > My Games > Staging Games > Game Content B'. --- but with this new game shell, I can just press the back button in the top left corner, and I'm back in Staging games (or wherever I came from). This is a bit of a nit but it's additional improvement. Consistency in code, in approach, and in UX The UI when you join a game, I would actually make a pop-up dialog (I know you hate them, but this warrants one as it's an 'important decision' and you can provide the answer. This is the right moment for it) where you write your first message. It then pops up in the Public Press channel, and new messages appear like an unread message as now - same channel, same notifiaction system, same indicators... Here’s what I think: most minimal solution is to just render the pending game within game detail layout, making the orders panel just include a notice. Game info panel is available via sub menu, not ideal a natural enhancement on top of that is to replace the orders panel (useless before game starts) with the game info panel which is more useful before the game starts. I think my main objection is that the game info screen should be a panel in the left command section, keeping the existing layout. Naturally this would mean removing the map from the game info screen. The join game button fits naturally where the confirm orders button is on the orders screen. most minimal solution is to just render the pending game within game detail layout, making the orders panel just include a notice. Game info panel is available via sub menu, not ideal An alternative would be to have it in the small side panel, remove the map and leave the map on the big screen. For mobile, that would indeed be the 'map tab'. Both are fine by me Claude, can you update this with the following feedback? |
|
Read the full discussion. Here's what I believe is agreed, and the one point I want to confirm before reworking, since it's still open as of the last message: Agreed (I'll implement this):
Open question — Game Info's own layout: These produce different amounts of rework and I'd rather build the right one once. @johnpooch — can you confirm which of these two you want, or if you and Joren want to settle it in the thread first? I'll hold off on that specific piece until then, but will start on the tab-swap + Map-uninteractive-view + Home-screen-removal now since those seem settled. Generated by Claude Code |
|
Let's have Game-Info live in the small panel and render the full map next to it. In that case, remove the map preview from the narrow Game-Info. This means that on mobile, we DO have a 'map' tab, similar to how it currently works for running games. So: Running/finished: This should be okay to go - you can proceed, no need to wait for John |
Pending games now mirror the exact structure active games already use, instead of an isolated single-tab shell: - Desktop: narrow Game Info panel on the left (replacing Orders' slot), full board always visible on the right. - Mobile: Map | Game Info bottom tabs (Chat still deferred to #906). The map is reachable and shows the real starting deployment (create_from_template places units immediately), but is read-only — GameMap already collapses to a no-op click handler whenever order options are empty, so skipping the options fetch for pending games (which 403s under IsActiveGame) was the only change needed to make it inert; no new interaction-blocking logic required. GameInfoContent drops its own map preview now that the real map is always shown alongside it. GameInfoScreen gets a GameDropdownMenu when pending, matching how Orders/Map already surface it — this also restores the Delete/Clone actions that were unreachable from a pending game's own view in the previous iteration. Home's redundant PlayerInfo screen is retired alongside GameInfo; GameCard now routes both through the shell via a shared getGamePhasePath helper. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Implemented the agreed design:
Screenshots updated in the PR description. Tests/lint/typecheck all green. Ready for another look whenever you get a chance. Generated by Claude Code |
…6zeg # Conflicts: # packages/web/src/components/GameMap.test.tsx
|
The desktop version of the 'status' (Leave/Join/Share/Add AI player) needs to be changed to the mobile version; before it had the full width of the desktop, but now it is the side panel, it has the same space as a mobile. So - it needs to use the mobile version of that component. Also, there should be some horizontal padding to the sides of the panel - right now it's very cramped. |
The Join/Leave/Share/Add-AI-player buttons and their wrapping layout used Tailwind's viewport-based sm: breakpoint, which stayed "desktop" even though the panel narrowed to sidebar width in the new layout — the buttons rendered in their wide side-by-side form but only had ~330px of actual space, so they were cramped and overflowed. Switch those to @[500px]: container queries, matching the threshold ScreenCard already uses for the same panel. Also add horizontal padding to GameInfoScreen's Panel.Content — the old Home screen got its padding for free from HomeLayout's wrapper, which the GameDetail shell's Panel-based screens don't have. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Good catch — the buttons were using Tailwind's viewport Updated desktop screenshot in the PR description. Generated by Claude Code |
|
Finally, can you add a screenshot of the bottom of the game-info screen - to validate that there is no 'map' anymore? Secondly, it now says 'Game info' in the top - can we make that the NAME of the game (so we move that up and remove 'Game info'. Truncate the name. (Then you also don't need the name duplication in the bottom of 'Gathering forces' - which is the game name). |
The AppBar now shows the game's own name (truncated) instead of the generic "Game Info" label, matching how MapScreen/OrdersScreen show contextual info in their headers rather than a static string. Since the name now lives in the header, the redundant ScreenCard title underneath (which repeated the same name) is removed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Both done:
Generated by Claude Code |
|
Add some slight vertical padding to the top of the 'join/leave/add AI player' bracket so it doesn't directly touch the top bar. |
The pending-action alert box sat flush against the AppBar's separator line in the narrow panel layout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Added a small gap above the alert box so it no longer touches the separator line. Updated desktop screenshot in the PR description. Generated by Claude Code |
|
Right now we have the phase selector in the map screen during staging games (on mobile). This is not relevant, as the phase is always stuck at the first one. Replace that with the game name, and add the "join/leave" component beneath it (mobile only). |
…ames The phase selector/guidance on the Map screen is meaningless while a game is pending — there's only ever one phase, with no previous/next to navigate. Show the game name there instead, and surface the same join/leave/share/add-bot row already used on the Game Info panel directly beneath it (mobile only, since that's the only place a pending game's Map tab is reachable). Extracted the row's mutations (join, leave, share, add-bot sheet state) out of GameInfoContent into a shared PendingGameActions component so MapScreen doesn't need to duplicate them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Can you make screenshots of the latest commit you made and update them in the PR description? This is about the mobile view/map active. |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
Commit 040c9b4 only added the 'open game' (join game) state. Can you show the other states? |
|
This pull request has been inactive for 7 days and will be closed in 7 days unless there is further activity. If it is still being worked on, push a commit or leave a comment. Add the |
|
Sorry for the silence — my connection to GitHub dropped for an extended stretch and I couldn't post anything until now (I kept working locally in the meantime and pushed everything as soon as it came back). To catch up:
Let me know if the padding/sizing on the new Map-tab action row needs the same kind of pass the Game Info one did. Generated by Claude Code |
Fresh mobile screenshots off the current HEAD (already includes the b4087f4 padding fix), side-by-side with the Map tab's zero-padding action row for comparison. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019SuNvfhBiQ5TvNKJjdRU44
|
I checked this against a clean checkout of the current HEAD ( Mobile Game Info — clear gap between the AppBar and the alert box: Mobile Map tab — for comparison, the action row still sits flush against the AppBar here, as intended:
Generated by Claude Code |
|
@johnpooch I think this is good to merge. The screenshots don't show, likely because Claude is not allowed to commit it. MAYBE (Claude, don't do this!) we should allow committing screenshots, then instruct Claude to always clean that folder before merging. That way the screenshots can be used (if my idea about the cause is correct). Can't check now, otherwise just leave it. But let's merge this! And move towards prechat lobby!!! |
|
This pull request has been inactive for 7 days and will be closed in 7 days unless there is further activity. If it is still being worked on, push a commit or leave a comment. Add the |











What this PR does
Pending (staging) games now render inside the existing GameDetail shell using the exact same structure active games already use, rather than a bespoke layout:
Map | Game Infobottom tabs (Chat is still deferred to Add the Chat tab to pending games with a join intro message #906, per the issue's dependency chain).The map is reachable and shows the real starting deployment —
create_from_templateplaces units immediately on the backend — but it's read-only.GameMapalready collapses into a no-op click handler whenever order options are empty, so the only change needed to make it inert for a pending game was skipping the options fetch (which 403s underIsActiveGameanyway); no new interaction-blocking logic was required.GameInfoContentdrops its own map preview now that the real map is always shown alongside it.GameInfoScreengets aGameDropdownMenuwhen the game is pending, matching how the Map/Orders screens already surface it for active games — this also restores the Delete/Clone actions that were unreachable from a pending game's own view. Home's now-redundantPlayerInfoscreen is retired alongsideGameInfo;GameCard's dropdown routes both through the shell via a sharedgetGamePhasePathhelper.The Map tab's phase selector was also replaced with the game name for pending games, since the phase never changes while a game is staging — there's nothing to select between. The join/leave/share/add-bot row now appears directly beneath it on mobile too, in addition to the Game Info panel. That row's mutations (join, leave, share, add-bot sheet state) were extracted into a shared
PendingGameActionscomponent soGameInfoContentandMapScreendon't duplicate them.This direction came out of a design discussion on the PR with @johnpooch and @JorenC after an earlier iteration (isolated single-tab shell, no visible map) didn't match the intended UX — see the thread below for the full back-and-forth.
Screenshots
Desktop — pending game the current user manages: narrow Game Info panel, full board on the right showing the starting deployment:
Mobile —
Map | Game Infotabs:Mobile Map tab (member) — game name + Add AI player/Leave/Share row in place of the phase selector:
Mobile Map tab (non-member) — Join game state:
Full panel (mobile, tall viewport) — confirms no leftover map preview anywhere in the Game Info panel; content ends cleanly at Rules:
Join state (Game Info panel) — pending game the current user hasn't joined:
Closes #903