commit c502f3e58561fa059e1930d2628a03a46c9f7657
parent 2a593b08d9d0923931b903884407a6b0747b1b96
Author: Michael Camilleri <[email protected]>
Date: Fri, 1 May 2026 20:04:55 +0900
Use panel rather than sheet on puzzle completion
Prior to this commit, a sheet would be shown on puzzle completion. This
commit replaces the sheet with a panel that appears in place of the
keyboard (since it is no longer required).
Co-Authored-By: Claude Opus 4.7 <[email protected]>
Diffstat:
2 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/Crossmate/Views/KeyboardView.swift b/Crossmate/Views/KeyboardView.swift
@@ -14,6 +14,8 @@ struct KeyboardView: View {
private let spacing: CGFloat = 6
private let keyHeight: CGFloat = 46
+ static let standardHeight: CGFloat = 170
+
var body: some View {
VStack(spacing: spacing) {
KeyboardRow(referenceColumns: 10, spacing: spacing, keyHeight: keyHeight) {
diff --git a/Crossmate/Views/PuzzleView.swift b/Crossmate/Views/PuzzleView.swift
@@ -9,7 +9,6 @@ struct PuzzleView: View {
@Environment(\.dismiss) private var dismiss
@State private var isRenaming = false
@State private var renameDraft = ""
- @State private var showSuccessScreen = false
@State private var showErrorsAlert = false
@State private var isConfirmingLeave = false
@State private var leaveError: String?
@@ -180,7 +179,6 @@ struct PuzzleView: View {
session.togglePencil()
}
onComplete?()
- showSuccessScreen = true
}
}
.alert("Not Quite Right", isPresented: $showErrorsAlert) {
@@ -188,9 +186,6 @@ struct PuzzleView: View {
} message: {
Text("One or more squares are incorrect.")
}
- .sheet(isPresented: $showSuccessScreen) {
- SuccessScreen(session: session)
- }
.alert("Leave Puzzle?", isPresented: $isConfirmingLeave) {
Button("Leave", role: .destructive) {
Task { await leaveSharedGame() }
@@ -264,9 +259,22 @@ struct PuzzleView: View {
private var controlsArea: some View {
VStack(spacing: 0) {
ClueBarSlot(session: session)
- KeyboardView(session: session)
- .disabled(isSolved)
- .background(Color(.systemGroupedBackground))
+ ZStack {
+ if isSolved {
+ SuccessPanel(session: session)
+ .transition(.move(edge: .bottom))
+ } else {
+ KeyboardView(session: session)
+ .transition(.move(edge: .bottom))
+ }
+ }
+ .frame(height: KeyboardView.standardHeight)
+ .clipped()
+ .background {
+ Color(.systemGroupedBackground)
+ .ignoresSafeArea(edges: .bottom)
+ }
+ .animation(.smooth(duration: 0.4), value: isSolved)
}
}
@@ -450,40 +458,23 @@ private struct ClueBar: View {
}
}
-private struct SuccessScreen: View {
+private struct SuccessPanel: View {
let session: PlayerSession
- @Environment(\.dismiss) private var dismiss
var body: some View {
- NavigationStack {
- VStack(spacing: 24) {
- VStack(spacing: 8) {
- Image(systemName: "checkmark.seal.fill")
- .font(.system(size: 64))
- .foregroundStyle(.tint)
- Text("Solved!")
- .font(.largeTitle.weight(.bold))
- Text(session.puzzle.title)
- .font(.headline)
- .foregroundStyle(.secondary)
- .multilineTextAlignment(.center)
- if let author = session.puzzle.author {
- Text(author)
- .font(.subheadline)
- .foregroundStyle(.secondary)
- }
- }
- Spacer()
- }
- .frame(maxWidth: .infinity)
- .padding(.top, 48)
- .padding(.horizontal)
- .toolbar {
- ToolbarItem(placement: .topBarTrailing) {
- Button("Done") { dismiss() }
- }
+ VStack(spacing: 8) {
+ Image(systemName: "checkmark.seal.fill")
+ .font(.system(size: 44))
+ .foregroundStyle(.tint)
+ Text("Solved!")
+ .font(.title2.weight(.bold))
+ if let author = session.puzzle.author {
+ Text("By \(author)")
+ .font(.subheadline)
+ .foregroundStyle(.secondary)
}
}
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
}
}