crossmate

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

commit 9acd53cc5e91be8b16ac95c3d83c3f3ca020ff13
parent 266a0c5c47c0f1e75391fed0873a8d29c86ab786
Author: Michael Camilleri <[email protected]>
Date:   Sun, 24 May 2026 14:39:25 +0900

Add confirmation dialog when revealing

Diffstat:
MCrossmate/Views/PuzzleView.swift | 59++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 56 insertions(+), 3 deletions(-)

diff --git a/Crossmate/Views/PuzzleView.swift b/Crossmate/Views/PuzzleView.swift @@ -1,5 +1,27 @@ import SwiftUI +private enum RevealScope { + case square + case word + case puzzle + + var title: String { + switch self { + case .square: "Reveal Square?" + case .word: "Reveal Word?" + case .puzzle: "Reveal Puzzle?" + } + } + + var message: String { + switch self { + case .square: "This will reveal the current square." + case .word: "This will reveal the current word." + case .puzzle: "This will reveal the entire puzzle and mark it complete." + } + } +} + struct PuzzleView: View { @Bindable var session: PlayerSession var shareController: ShareController? = nil @@ -17,6 +39,8 @@ struct PuzzleView: View { @State private var isConfirmingResign = false @State private var isConfirmingDelete = false @State private var isConfirmingLeave = false + @State private var isConfirmingReveal = false + @State private var pendingRevealScope: RevealScope = .square @State private var leaveError: String? @State private var destructiveActionError: String? @State private var isShowingShareSheet = false @@ -90,6 +114,8 @@ struct PuzzleView: View { isConfirmingResign: $isConfirmingResign, isConfirmingDelete: $isConfirmingDelete, isConfirmingLeave: $isConfirmingLeave, + isConfirmingReveal: $isConfirmingReveal, + pendingRevealScope: $pendingRevealScope, isShowingShareSheet: $isShowingShareSheet )) .modifier(PuzzleLifecycleModifier( @@ -108,6 +134,8 @@ struct PuzzleView: View { isConfirmingResign: $isConfirmingResign, isConfirmingDelete: $isConfirmingDelete, isConfirmingLeave: $isConfirmingLeave, + isConfirmingReveal: $isConfirmingReveal, + pendingRevealScope: $pendingRevealScope, leaveError: $leaveError, destructiveActionError: $destructiveActionError, isShowingShareSheet: $isShowingShareSheet, @@ -729,6 +757,8 @@ private struct PuzzleToolbarModifier: ViewModifier { @Binding var isConfirmingResign: Bool @Binding var isConfirmingDelete: Bool @Binding var isConfirmingLeave: Bool + @Binding var isConfirmingReveal: Bool + @Binding var pendingRevealScope: RevealScope @Binding var isShowingShareSheet: Bool @Environment(PlayerPreferences.self) private var preferences @AppStorage("debugMode") private var debugMode = false @@ -810,9 +840,9 @@ private struct PuzzleToolbarModifier: ViewModifier { Button("Check Puzzle") { session.checkPuzzle() } } Section { - Button("Reveal Square") { session.revealSquare() } - Button("Reveal Word") { session.revealCurrentWord() } - Button("Reveal Puzzle") { session.revealPuzzle() } + Button("Reveal Square") { confirmReveal(.square) } + Button("Reveal Word") { confirmReveal(.word) } + Button("Reveal Puzzle") { confirmReveal(.puzzle) } } } label: { Label("Hints", systemImage: "lightbulb") @@ -820,6 +850,11 @@ private struct PuzzleToolbarModifier: ViewModifier { .disabled(isSolved) } + private func confirmReveal(_ scope: RevealScope) { + pendingRevealScope = scope + isConfirmingReveal = true + } + private var playersMenu: some View { Menu { playerRosterSection @@ -962,6 +997,8 @@ private struct PuzzlePresentationModifier: ViewModifier { @Binding var isConfirmingResign: Bool @Binding var isConfirmingDelete: Bool @Binding var isConfirmingLeave: Bool + @Binding var isConfirmingReveal: Bool + @Binding var pendingRevealScope: RevealScope @Binding var leaveError: String? @Binding var destructiveActionError: String? @Binding var isShowingShareSheet: Bool @@ -1001,6 +1038,14 @@ private struct PuzzlePresentationModifier: ViewModifier { } message: { Text("You will lose access to \"\(session.puzzle.title)\".") } + .alert(pendingRevealScope.title, isPresented: $isConfirmingReveal) { + Button("Reveal", role: .destructive) { + performReveal(pendingRevealScope) + } + Button("Cancel", role: .cancel) {} + } message: { + Text(pendingRevealScope.message) + } .alert( "Couldn't Leave", isPresented: .init( @@ -1051,6 +1096,14 @@ private struct PuzzlePresentationModifier: ViewModifier { } } + private func performReveal(_ scope: RevealScope) { + switch scope { + case .square: session.revealSquare() + case .word: session.revealCurrentWord() + case .puzzle: session.revealPuzzle() + } + } + private var deleteConfirmationMessage: Text { if session.mutator.isOwned && session.mutator.isShared { Text("This will permanently delete \"\(session.puzzle.title)\" from iCloud for everyone.")