CarbsInputView.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import Foundation
  2. import SwiftUI
  3. // MARK: - Carbs Input View
  4. struct CarbsInputView: View {
  5. @ObservedObject var navigationState: NavigationState
  6. @State private var carbsAmount: Double = 0.0 // Needs to be Double due to .digitalCrownRotation() stride
  7. @FocusState private var isCrownFocused: Bool // Manage crown focus
  8. let state: WatchState
  9. let continueToBolus: Bool
  10. var trioBackgroundColor = LinearGradient(
  11. gradient: Gradient(colors: [Color.bgDarkBlue, Color.bgDarkerDarkBlue]),
  12. startPoint: .top,
  13. endPoint: .bottom
  14. )
  15. var body: some View {
  16. let buttonLabel = continueToBolus ? "Proceed" : "Log Carbs"
  17. // TODO: introduce meal setting fpu enablement to conditional handle FPU
  18. VStack {
  19. Spacer()
  20. HStack {
  21. // "-" Button
  22. Button(action: {
  23. if carbsAmount > 0 { carbsAmount -= 1 }
  24. }) {
  25. Image(systemName: "minus.circle.fill")
  26. .font(.title3)
  27. .foregroundColor(.orange)
  28. }
  29. .buttonStyle(.borderless)
  30. .disabled(carbsAmount < 1)
  31. Spacer()
  32. // Display the current carb amount
  33. Text(String(format: "%.0f g", carbsAmount))
  34. .fontWeight(.bold)
  35. .font(.system(.title2, design: .rounded))
  36. .foregroundColor(.primary)
  37. .focusable(true)
  38. .focused($isCrownFocused)
  39. .digitalCrownRotation(
  40. $carbsAmount,
  41. from: 0,
  42. through: 150.0, // TODO: introduce maxCarbs here
  43. by: 1,
  44. sensitivity: .medium,
  45. isContinuous: false,
  46. isHapticFeedbackEnabled: true
  47. )
  48. Spacer()
  49. // TODO: introduce maxCarbs here, disable button if carbsAmount > maxCarbs
  50. // "+" Button
  51. Button(action: {
  52. carbsAmount += 1
  53. }) {
  54. Image(systemName: "plus.circle.fill")
  55. .font(.title3)
  56. .foregroundColor(.orange)
  57. }
  58. .buttonStyle(.borderless)
  59. }.padding(.horizontal)
  60. Text("Carbohydrates")
  61. .font(.subheadline)
  62. .foregroundColor(.secondary)
  63. .padding(.bottom)
  64. Spacer()
  65. Button(buttonLabel) {
  66. if continueToBolus {
  67. state.carbsAmount = Int(carbsAmount)
  68. navigationState.path.append(NavigationDestinations.bolusInput)
  69. } else {
  70. state.sendCarbsRequest(Int(carbsAmount))
  71. // TODO: add a fancy success animation
  72. navigationState.resetToRoot()
  73. }
  74. }
  75. .buttonStyle(.bordered)
  76. .tint(.orange)
  77. .disabled(!(carbsAmount > 0.0))
  78. }
  79. .background(trioBackgroundColor)
  80. .toolbar {
  81. ToolbarItem(placement: .topBarTrailing) {
  82. Image(systemName: "fork.knife")
  83. .resizable()
  84. .aspectRatio(contentMode: .fit)
  85. .frame(width: 14, height: 14)
  86. .padding()
  87. .background(Color.orange)
  88. .foregroundStyle(.white)
  89. .clipShape(Circle())
  90. }
  91. }
  92. }
  93. }