Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
dfe3bc4bba
commit
172e224a42
@ -21,8 +21,10 @@ struct ActionButtonsView: View {
|
|||||||
switch state.currentPhase {
|
switch state.currentPhase {
|
||||||
case .betting:
|
case .betting:
|
||||||
bettingButtons
|
bettingButtons
|
||||||
|
.transition(.opacity.combined(with: .scale(scale: 0.9)))
|
||||||
case .playerTurn:
|
case .playerTurn:
|
||||||
playerTurnButtons
|
playerTurnButtons
|
||||||
|
.transition(.opacity.combined(with: .scale(scale: 0.9)))
|
||||||
case .roundComplete:
|
case .roundComplete:
|
||||||
// Empty - handled by result banner
|
// Empty - handled by result banner
|
||||||
EmptyView()
|
EmptyView()
|
||||||
@ -31,6 +33,7 @@ struct ActionButtonsView: View {
|
|||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.animation(.spring(duration: Design.Animation.springDuration), value: state.currentPhase)
|
||||||
}
|
}
|
||||||
.frame(height: containerHeight)
|
.frame(height: containerHeight)
|
||||||
.padding(.horizontal, Design.Spacing.large)
|
.padding(.horizontal, Design.Spacing.large)
|
||||||
@ -51,54 +54,86 @@ struct ActionButtonsView: View {
|
|||||||
|
|
||||||
// MARK: - Player Turn Buttons
|
// MARK: - Player Turn Buttons
|
||||||
|
|
||||||
|
/// Available player actions based on current game state.
|
||||||
|
private var availableActions: [PlayerAction] {
|
||||||
|
PlayerAction.allCases.filter { action in
|
||||||
|
switch action {
|
||||||
|
case .hit: state.canHit
|
||||||
|
case .stand: state.canStand
|
||||||
|
case .double: state.canDouble
|
||||||
|
case .split: state.canSplit
|
||||||
|
case .surrender: state.canSurrender
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tracks available actions for animation purposes.
|
||||||
|
@State private var animatedActions: [PlayerAction] = []
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var playerTurnButtons: some View {
|
private var playerTurnButtons: some View {
|
||||||
// All player actions in a single row
|
|
||||||
HStack(spacing: Design.Spacing.medium) {
|
HStack(spacing: Design.Spacing.medium) {
|
||||||
if state.canHit {
|
ForEach(animatedActions) { action in
|
||||||
ActionButton(
|
ActionButton(
|
||||||
String(localized: "Hit"),
|
action.title,
|
||||||
style: .custom(Color.Button.hit)
|
style: .custom(action.color)
|
||||||
) {
|
) {
|
||||||
Task { await state.hit() }
|
Task { await performAction(action) }
|
||||||
|
}
|
||||||
|
.transition(.scale.combined(with: .opacity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
animatedActions = availableActions
|
||||||
|
}
|
||||||
|
.onChange(of: availableActions) { _, newActions in
|
||||||
|
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: 0.15)) {
|
||||||
|
animatedActions = newActions
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.canStand {
|
/// Performs the given player action.
|
||||||
ActionButton(
|
private func performAction(_ action: PlayerAction) async {
|
||||||
String(localized: "Stand"),
|
switch action {
|
||||||
style: .custom(Color.Button.stand)
|
case .hit: await state.hit()
|
||||||
) {
|
case .stand: await state.stand()
|
||||||
Task { await state.stand() }
|
case .double: await state.doubleDown()
|
||||||
|
case .split: await state.split()
|
||||||
|
case .surrender: await state.surrender()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Player Action
|
||||||
|
|
||||||
|
/// Represents a player action button during their turn.
|
||||||
|
private enum PlayerAction: String, CaseIterable, Identifiable {
|
||||||
|
case hit
|
||||||
|
case stand
|
||||||
|
case double
|
||||||
|
case split
|
||||||
|
case surrender
|
||||||
|
|
||||||
|
var id: String { rawValue }
|
||||||
|
|
||||||
|
var title: String {
|
||||||
|
switch self {
|
||||||
|
case .hit: String(localized: "Hit")
|
||||||
|
case .stand: String(localized: "Stand")
|
||||||
|
case .double: String(localized: "Double")
|
||||||
|
case .split: String(localized: "Split")
|
||||||
|
case .surrender: String(localized: "Surrender")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.canDouble {
|
var color: Color {
|
||||||
ActionButton(
|
switch self {
|
||||||
String(localized: "Double"),
|
case .hit: Color.Button.hit
|
||||||
style: .custom(Color.Button.doubleDown)
|
case .stand: Color.Button.stand
|
||||||
) {
|
case .double: Color.Button.doubleDown
|
||||||
Task { await state.doubleDown() }
|
case .split: Color.Button.split
|
||||||
}
|
case .surrender: Color.Button.surrender
|
||||||
}
|
|
||||||
|
|
||||||
if state.canSplit {
|
|
||||||
ActionButton(
|
|
||||||
String(localized: "Split"),
|
|
||||||
style: .custom(Color.Button.split)
|
|
||||||
) {
|
|
||||||
Task { await state.split() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if state.canSurrender {
|
|
||||||
ActionButton(
|
|
||||||
String(localized: "Surrender"),
|
|
||||||
style: .custom(Color.Button.surrender)
|
|
||||||
) {
|
|
||||||
Task { await state.surrender() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user