BolusConfirmationView.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import Foundation
  2. import SwiftUI
  3. import WatchKit
  4. struct BolusConfirmationView: View {
  5. @Binding var navigationPath: NavigationPath
  6. let state: WatchState
  7. @Binding var bolusAmount: Double
  8. @Binding var confirmationProgress: Double
  9. @FocusState private var isCrownFocused: 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 bolusIncrement = Double(truncating: state.bolusIncrement as NSNumber)
  17. let adjustedBolusAmount = floor(bolusAmount / bolusIncrement) * bolusIncrement
  18. VStack(spacing: 10) {
  19. Spacer()
  20. VStack {
  21. if state.carbsAmount > 0 {
  22. HStack {
  23. Text("Carbs:")
  24. Spacer()
  25. Text("\(state.carbsAmount) g")
  26. .bold()
  27. .foregroundStyle(.orange)
  28. }.padding(.horizontal)
  29. }
  30. HStack {
  31. Text("Bolus")
  32. Spacer()
  33. Text(String(format: "%.2f \(String(localized: "U", comment: "Insulin unit"))", adjustedBolusAmount))
  34. .bold()
  35. .foregroundStyle(Color.insulin)
  36. }.padding(.horizontal)
  37. }
  38. ProgressView(value: confirmationProgress, total: 1.0)
  39. .tint(confirmationProgress >= 1.0 ? .loopGreen : .gray)
  40. .padding(.horizontal)
  41. Text("To confirm, dial crown.").font(.footnote)
  42. Spacer()
  43. Button("Cancel") {
  44. if state.carbsAmount > 0 {
  45. state.carbsAmount = 0 // reset carbs in state
  46. }
  47. bolusAmount = 0 // reset bolus in state
  48. confirmationProgress = 0 // reset auth progress
  49. navigationPath.removeLast(navigationPath.count)
  50. }
  51. .buttonStyle(.bordered)
  52. }
  53. .focusable(true)
  54. .focused($isCrownFocused)
  55. .digitalCrownRotation(
  56. $confirmationProgress,
  57. from: 0.0,
  58. through: 1.0,
  59. by: state.confirmBolusFaster ? 0.5 : 0.05,
  60. sensitivity: .medium,
  61. isContinuous: false,
  62. isHapticFeedbackEnabled: true
  63. )
  64. .onAppear {
  65. isCrownFocused = true
  66. }
  67. .onChange(of: confirmationProgress) { _, newValue in
  68. if newValue >= 1.0 {
  69. WKInterfaceDevice.current().play(.success)
  70. DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
  71. if state.carbsAmount > 0 {
  72. state.sendCarbsRequest(state.carbsAmount, Date())
  73. state.carbsAmount = 0 // reset carbs in state
  74. }
  75. state.activeBolusAmount = bolusAmount
  76. state.sendBolusRequest(Decimal(bolusAmount))
  77. bolusAmount = 0 // reset bolus in state
  78. confirmationProgress = 0 // reset auth progress
  79. navigationPath.append(NavigationDestinations.acknowledgmentPending)
  80. }
  81. } else if newValue > 0 {
  82. WKInterfaceDevice.current().play(.click)
  83. }
  84. }
  85. .navigationTitle("Confirm")
  86. .background(trioBackgroundColor)
  87. .toolbar {
  88. ToolbarItem(placement: .topBarTrailing) {
  89. Image(
  90. systemName: WKInterfaceDevice.current()
  91. .wristLocation == .left ? "digitalcrown.arrow.clockwise.fill" : "digitalcrown.arrow.counterclockwise.fill"
  92. )
  93. .symbolRenderingMode(.palette)
  94. .foregroundStyle(Color.insulin, Color.primary)
  95. .symbolEffect(
  96. .variableColor.reversing,
  97. options: .speed(100).repeating
  98. )
  99. }
  100. }
  101. .blur(radius: state.showBolusProgressOverlay ? 3 : 0)
  102. .overlay {
  103. if state.showBolusProgressOverlay {
  104. BolusProgressOverlay(state: state) {
  105. state.shouldNavigateToRoot = false
  106. navigationPath.append(NavigationDestinations.acknowledgmentPending)
  107. }.transition(.opacity)
  108. }
  109. }
  110. }
  111. }