Signed-off-by: Matt Bruce <matt.bruce1@toyota.com>
This commit is contained in:
parent
8cbd85dcce
commit
34455378fc
@ -35,10 +35,8 @@ struct ActionButtonsView: View {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
.animation(.spring(duration: Design.Animation.quick), value: state.currentPhase)
|
||||
.animation(.easeInOut(duration: Design.Animation.standard), value: state.currentBet > 0)
|
||||
}
|
||||
.frame(minHeight: containerHeight)
|
||||
.frame(height: containerHeight)
|
||||
.padding(.horizontal, Design.Spacing.large)
|
||||
}
|
||||
|
||||
|
||||
@ -130,20 +130,22 @@ struct GameTableView: View {
|
||||
)
|
||||
.frame(maxWidth: maxContentWidth)
|
||||
|
||||
// Chip selector - only shown during betting phase
|
||||
if state.currentPhase == .betting {
|
||||
Spacer()
|
||||
.debugBorder(showDebugBorders, color: .yellow, label: "ChipSpacer")
|
||||
|
||||
// Chip selector - only shown during betting phase AND when result banner is NOT showing
|
||||
if state.currentPhase == .betting && !state.showResultBanner {
|
||||
ChipSelectorView(
|
||||
selectedChip: $selectedChip,
|
||||
balance: state.balance,
|
||||
currentBet: state.minBetForChipSelector, // Use min bet so chips stay enabled if any bet type can accept more
|
||||
currentBet: state.minBetForChipSelector,
|
||||
maxBet: state.settings.maxBet
|
||||
)
|
||||
.frame(maxWidth: maxContentWidth)
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
.debugBorder(showDebugBorders, color: .pink, label: "ChipSelector")
|
||||
.onAppear {
|
||||
print("🎰 Chip selector APPEARED (banner showing: \(state.showResultBanner))")
|
||||
}
|
||||
.onDisappear {
|
||||
print("🎰 Chip selector DISAPPEARED")
|
||||
}
|
||||
}
|
||||
|
||||
// Action buttons - minimal spacing during player turn
|
||||
@ -152,21 +154,33 @@ struct GameTableView: View {
|
||||
.padding(.bottom, Design.Spacing.small)
|
||||
.debugBorder(showDebugBorders, color: .blue, label: "ActionBtns")
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(maxWidth: .infinity, alignment: .top)
|
||||
.zIndex(1)
|
||||
.onChange(of: state.currentPhase) { oldPhase, newPhase in
|
||||
print("🔄 Phase changed: \(oldPhase) → \(newPhase)")
|
||||
}
|
||||
|
||||
// Insurance popup overlay (covers entire screen)
|
||||
if state.currentPhase == .insurance {
|
||||
Color.clear
|
||||
.overlay(alignment: .center) {
|
||||
InsurancePopupView(
|
||||
betAmount: state.currentBet / 2,
|
||||
balance: state.balance,
|
||||
onTake: { Task { await state.takeInsurance() } },
|
||||
onDecline: { state.declineInsurance() }
|
||||
)
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
.allowsHitTesting(true)
|
||||
.transition(.opacity.combined(with: .scale(scale: 0.9)))
|
||||
.zIndex(100)
|
||||
}
|
||||
|
||||
// Result banner overlay
|
||||
if state.showResultBanner, let result = state.lastRoundResult {
|
||||
Color.clear
|
||||
.overlay(alignment: .center) {
|
||||
ResultBannerView(
|
||||
result: result,
|
||||
currentBalance: state.balance,
|
||||
@ -174,20 +188,43 @@ struct GameTableView: View {
|
||||
onNewRound: { state.newRound() },
|
||||
onPlayAgain: { state.resetGame() }
|
||||
)
|
||||
.onAppear {
|
||||
print("🎯 RESULT BANNER APPEARED")
|
||||
}
|
||||
.onDisappear {
|
||||
print("❌ RESULT BANNER DISAPPEARED")
|
||||
}
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
.allowsHitTesting(true)
|
||||
.zIndex(100)
|
||||
}
|
||||
|
||||
// Confetti for wins (matching Baccarat pattern)
|
||||
if state.showResultBanner && (state.lastRoundResult?.totalWinnings ?? 0) > 0 {
|
||||
ConfettiView()
|
||||
.zIndex(101)
|
||||
}
|
||||
|
||||
// Game over
|
||||
if state.isGameOver && !state.showResultBanner {
|
||||
Color.clear
|
||||
.overlay(alignment: .center) {
|
||||
GameOverView(
|
||||
roundsPlayed: state.roundsPlayed,
|
||||
onPlayAgain: { state.resetGame() }
|
||||
)
|
||||
}
|
||||
.ignoresSafeArea()
|
||||
.allowsHitTesting(true)
|
||||
.zIndex(100)
|
||||
}
|
||||
}
|
||||
.onChange(of: state.playerHands.count) { oldCount, newCount in
|
||||
print("👥 Player hands count: \(oldCount) → \(newCount)")
|
||||
}
|
||||
.onChange(of: state.balance) { oldBalance, newBalance in
|
||||
print("💰 Balance: \(oldBalance) → \(newBalance)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,6 @@ struct ResultBannerView: View {
|
||||
ZStack {
|
||||
// Full screen dark background
|
||||
Color.black.opacity(Design.Opacity.strong)
|
||||
.ignoresSafeArea()
|
||||
|
||||
// Content card
|
||||
VStack(spacing: Design.Spacing.xLarge) {
|
||||
@ -193,18 +192,18 @@ struct ResultBannerView: View {
|
||||
.shadow(color: mainResultColor.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusXLarge)
|
||||
.frame(maxWidth: CasinoDesign.Size.maxModalWidth)
|
||||
.padding(.horizontal, Design.Spacing.large) // Prevent clipping on sides
|
||||
.scaleEffect(showContent ? 1.0 : 0.8)
|
||||
.scaleEffect(showContent ? Design.Scale.normal : Design.Scale.slightShrink)
|
||||
.opacity(showContent ? 1.0 : 0)
|
||||
}
|
||||
.onAppear {
|
||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: 0.3)) {
|
||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce)) {
|
||||
showContent = true
|
||||
}
|
||||
|
||||
// Play game over sound if out of chips (after a delay so it doesn't overlap with result sound)
|
||||
if isGameOver {
|
||||
Task {
|
||||
try? await Task.sleep(for: .seconds(1))
|
||||
try? await Task.sleep(for: .seconds(Design.Delay.gameOverSound))
|
||||
SoundManager.shared.play(.gameOver)
|
||||
}
|
||||
}
|
||||
@ -222,6 +221,8 @@ struct ResultRow: View {
|
||||
let result: HandResult
|
||||
var amount: Int? = nil
|
||||
|
||||
private var showDebugBorders: Bool { Design.showDebugBorders }
|
||||
|
||||
private var amountText: String? {
|
||||
guard let amount = amount else { return nil }
|
||||
if amount > 0 {
|
||||
@ -243,24 +244,31 @@ struct ResultRow: View {
|
||||
var body: some View {
|
||||
HStack {
|
||||
Text(label)
|
||||
.font(.system(size: Design.BaseFontSize.body))
|
||||
.font(.system(size: Design.BaseFontSize.medium))
|
||||
.foregroundStyle(.white.opacity(Design.Opacity.strong))
|
||||
.debugBorder(showDebugBorders, color: .blue, label: "Label")
|
||||
|
||||
Spacer()
|
||||
.debugBorder(showDebugBorders, color: .yellow, label: "Spacer")
|
||||
|
||||
// Show amount if provided
|
||||
if let amountText = amountText {
|
||||
Text(amountText)
|
||||
.font(.system(size: Design.BaseFontSize.body, weight: .semibold, design: .rounded))
|
||||
.font(.system(size: Design.BaseFontSize.medium, weight: .semibold, design: .rounded))
|
||||
.foregroundStyle(amountColor)
|
||||
.frame(width: 70, alignment: .trailing)
|
||||
.frame(width: Design.Size.resultRowAmountWidth, alignment: .trailing)
|
||||
.debugBorder(showDebugBorders, color: .green, label: "Amount")
|
||||
}
|
||||
|
||||
Text(result.displayText)
|
||||
.font(.system(size: Design.BaseFontSize.body, weight: .bold))
|
||||
.font(.system(size: Design.BaseFontSize.large, weight: .bold))
|
||||
.foregroundStyle(result.color)
|
||||
.frame(width: 100, alignment: .trailing)
|
||||
.frame(width: Design.Size.resultRowResultWidth, alignment: .trailing)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(Design.MinScaleFactor.comfortable)
|
||||
.debugBorder(showDebugBorders, color: .red, label: "Result")
|
||||
}
|
||||
.debugBorder(showDebugBorders, color: .white, label: "ResultRow")
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,6 +280,8 @@ struct SideBetResultRow: View {
|
||||
let isWin: Bool
|
||||
let amount: Int
|
||||
|
||||
private var showDebugBorders: Bool { Design.showDebugBorders }
|
||||
|
||||
private var amountText: String {
|
||||
if amount > 0 {
|
||||
return "+$\(amount)"
|
||||
@ -295,23 +305,28 @@ struct SideBetResultRow: View {
|
||||
var body: some View {
|
||||
HStack {
|
||||
Text(label)
|
||||
.font(.system(size: Design.BaseFontSize.body))
|
||||
.font(.system(size: Design.BaseFontSize.medium))
|
||||
.foregroundStyle(.white.opacity(Design.Opacity.strong))
|
||||
.debugBorder(showDebugBorders, color: .blue, label: "Label")
|
||||
|
||||
Spacer()
|
||||
.debugBorder(showDebugBorders, color: .yellow, label: "Spacer")
|
||||
|
||||
Text(amountText)
|
||||
.font(.system(size: Design.BaseFontSize.body, weight: .semibold, design: .rounded))
|
||||
.font(.system(size: Design.BaseFontSize.medium, weight: .semibold, design: .rounded))
|
||||
.foregroundStyle(amountColor)
|
||||
.frame(width: 70, alignment: .trailing)
|
||||
.frame(width: Design.Size.resultRowAmountWidth, alignment: .trailing)
|
||||
.debugBorder(showDebugBorders, color: .green, label: "Amount")
|
||||
|
||||
Text(resultText)
|
||||
.font(.system(size: Design.BaseFontSize.body, weight: .bold))
|
||||
.font(.system(size: Design.BaseFontSize.large, weight: .bold))
|
||||
.foregroundStyle(resultColor)
|
||||
.frame(width: 100, alignment: .trailing)
|
||||
.frame(width: Design.Size.resultRowResultWidth, alignment: .trailing)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(Design.MinScaleFactor.comfortable)
|
||||
.debugBorder(showDebugBorders, color: .red, label: "Result")
|
||||
}
|
||||
.debugBorder(showDebugBorders, color: .white, label: "SideBetRow")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user