crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit f2d38c5dfdff9d27448354fdda88068941cc4f9d
parent 628182a7d3be8e54690f066cfcae0a02f3a15777
Author: Michael Camilleri <[email protected]>
Date:   Sun, 19 Jul 2026 19:40:45 +0900

Fix stale state in the New Puzzle sheet

The New Puzzle sheet could capture the previous invitation target
because friend selection and sheet presentation used separate state
changes. The first selection therefore opened with the generic 'New
Puzzle' title, and changing friends could make a later sheet show a
stale name.

This commit drives presentation from one identifiable value that carries
the optional friend. Each sheet is now constructed with the exact target
used by its title and invitation callback.

Co-Authored-By: Codex GPT 5.6 Sol <[email protected]>

Diffstat:
MCrossmate/Views/GameList/GameListView.swift | 22++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/Crossmate/Views/GameList/GameListView.swift b/Crossmate/Views/GameList/GameListView.swift @@ -49,11 +49,10 @@ struct GameListView: View { @State private var acceptingInviteID: NSManagedObjectID? @State private var blockTarget: InviteEntity? - @State private var showingNewGame = false + @State private var newGamePresentation: NewGamePresentation? @State private var showingSettings = false @AppStorage(AppServices.showV4NoticeDefaultsKey) private var showV4Notice = false @State private var showingFriends = false - @State private var newGameInviteTarget: FriendNewGameTarget? @State private var queuedNewGameInviteTarget: FriendNewGameTarget? @State private var deleteTarget: GameSummary? @State private var resignTarget: GameSummary? @@ -71,6 +70,11 @@ struct GameListView: View { private static let completedPageSize = 7 + private struct NewGamePresentation: Identifiable { + let id = UUID() + let inviteTarget: FriendNewGameTarget? + } + var body: some View { VStack(spacing: 0) { accessibilityHeading @@ -127,8 +131,7 @@ struct GameListView: View { } ToolbarItem(placement: .topBarTrailing) { Button { - newGameInviteTarget = nil - showingNewGame = true + newGamePresentation = NewGamePresentation(inviteTarget: nil) } label: { Image(systemName: "plus") } @@ -146,13 +149,13 @@ struct GameListView: View { queuedNewGameInviteTarget = target } } - .sheet(isPresented: $showingNewGame) { + .sheet(item: $newGamePresentation) { presentation in NewGameSheet( store: store, - inviteTargetName: newGameInviteTarget?.displayName + inviteTargetName: presentation.inviteTarget?.displayName ) { gameID in navigationPath.append(gameID) - if let target = newGameInviteTarget { + if let target = presentation.inviteTarget { Task { await inviteNewGame(gameID, to: target) } } } @@ -170,7 +173,7 @@ struct GameListView: View { guard MarketingLaunch.isImportScene else { return } driveMonitor.seedMarketingImports() UserDefaults.standard.set(PuzzleSource.imported.rawValue, forKey: "lastPuzzleSource") - showingNewGame = true + newGamePresentation = NewGamePresentation(inviteTarget: nil) } #endif .onChange(of: pendingInviteNotificationGameID) { _, _ in @@ -340,8 +343,7 @@ struct GameListView: View { private func presentQueuedFriendNewGame() { guard let target = queuedNewGameInviteTarget else { return } queuedNewGameInviteTarget = nil - newGameInviteTarget = target - showingNewGame = true + newGamePresentation = NewGamePresentation(inviteTarget: target) } private func inviteNewGame(_ gameID: UUID, to target: FriendNewGameTarget) async {