BolusRootView.swift 5.1 KB

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