BolusRootView.swift 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import SwiftUI
  2. import Swinject
  3. extension Bolus {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. let waitForSuggestion: Bool
  7. let manualBolus: Bool
  8. @StateObject var state = StateModel()
  9. @State private var isAddInsulinAlertPresented = false
  10. private var formatter: NumberFormatter {
  11. let formatter = NumberFormatter()
  12. formatter.numberStyle = .decimal
  13. formatter.maximumFractionDigits = 2
  14. return formatter
  15. }
  16. var body: some View {
  17. Form {
  18. Section {
  19. if state.waitForSuggestion {
  20. HStack {
  21. Text("Wait please").foregroundColor(.secondary)
  22. Spacer()
  23. ActivityIndicator(isAnimating: .constant(true), style: .medium) // fix iOS 15 bug
  24. }
  25. } else {
  26. if state.manual {
  27. HStack {
  28. Text("Insulin recommended")
  29. Spacer()
  30. Text(
  31. formatter
  32. .string(from: state.insulinRecommended as NSNumber)! +
  33. NSLocalizedString(" U", comment: "Insulin unit")
  34. ).foregroundColor(.secondary)
  35. }.contentShape(Rectangle())
  36. .onTapGesture {
  37. state.amount = state.insulinRecommended
  38. }
  39. } else {
  40. HStack {
  41. Text("Insulin required").foregroundColor(.secondary)
  42. Spacer()
  43. Text(
  44. formatter
  45. .string(from: state.insulinRequired as NSNumber)! +
  46. NSLocalizedString(" U", comment: "Insulin unit")
  47. ).foregroundColor(.secondary)
  48. }.contentShape(Rectangle())
  49. .onTapGesture {
  50. state.amount = state.insulinRequired
  51. }
  52. HStack {
  53. Text("Insulin recommended")
  54. Spacer()
  55. Text(
  56. formatter
  57. .string(from: state.insulinRecommended as NSNumber)! +
  58. NSLocalizedString(" U", comment: "Insulin unit")
  59. ).foregroundColor(.secondary)
  60. }.contentShape(Rectangle())
  61. .onTapGesture {
  62. state.amount = state.insulinRecommended
  63. }
  64. }
  65. }
  66. }
  67. header: { Text("Recommendation") }
  68. if !state.waitForSuggestion {
  69. Section {
  70. HStack {
  71. Text("Amount")
  72. Spacer()
  73. DecimalTextField(
  74. "0",
  75. value: $state.amount,
  76. formatter: formatter,
  77. autofocus: true,
  78. cleanInput: true
  79. )
  80. Text("U").foregroundColor(.secondary)
  81. }
  82. }
  83. header: { Text("Bolus") }
  84. Section {
  85. Button { state.add() }
  86. label: { Text("Enact bolus") }
  87. .disabled(state.amount <= 0)
  88. }
  89. Section {
  90. if waitForSuggestion {
  91. Button { state.showModal(for: nil) }
  92. label: { Text("Continue without bolus") }
  93. } else {
  94. Button { isAddInsulinAlertPresented = true }
  95. label: { Text("Add insulin without actually bolusing") }
  96. .disabled(state.amount <= 0)
  97. }
  98. }
  99. }
  100. }
  101. .alert(isPresented: $isAddInsulinAlertPresented) {
  102. let amount = formatter
  103. .string(from: state.amount as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
  104. return Alert(
  105. title: Text("Are you sure?"),
  106. message: Text("Add \(amount) without bolusing"),
  107. primaryButton: .destructive(
  108. Text("Add"),
  109. action: { state.addWithoutBolus() }
  110. ),
  111. secondaryButton: .cancel()
  112. )
  113. }
  114. .onAppear {
  115. configureView {
  116. state.waitForSuggestionInitial = waitForSuggestion
  117. state.waitForSuggestion = waitForSuggestion
  118. state.manual = manualBolus
  119. }
  120. }
  121. .navigationTitle("Enact Bolus")
  122. .navigationBarTitleDisplayMode(.automatic)
  123. .navigationBarItems(leading: Button("Close", action: state.hideModal))
  124. }
  125. }
  126. }
  127. // fix iOS 15 bug
  128. struct ActivityIndicator: UIViewRepresentable {
  129. @Binding var isAnimating: Bool
  130. let style: UIActivityIndicatorView.Style
  131. func makeUIView(context _: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
  132. UIActivityIndicatorView(style: style)
  133. }
  134. func updateUIView(_ uiView: UIActivityIndicatorView, context _: UIViewRepresentableContext<ActivityIndicator>) {
  135. isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
  136. }
  137. }