OverrideProfilesRootView.swift 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import CoreData
  2. import SwiftUI
  3. import Swinject
  4. extension OverrideProfilesConfig {
  5. struct RootView: BaseView {
  6. let resolver: Resolver
  7. @StateObject var state = StateModel()
  8. @State private var isEditing = false
  9. @State private var showAlert = false
  10. @State private var showingDetail = false
  11. @State private var isPresented = true
  12. @State private var alertSring = ""
  13. @Environment(\.dismiss) var dismiss
  14. private var formatter: NumberFormatter {
  15. let formatter = NumberFormatter()
  16. formatter.numberStyle = .decimal
  17. formatter.maximumFractionDigits = 0
  18. return formatter
  19. }
  20. private var glucoseFormatter: NumberFormatter {
  21. let formatter = NumberFormatter()
  22. formatter.numberStyle = .decimal
  23. formatter.maximumFractionDigits = 0
  24. if state.units == .mmolL {
  25. formatter.maximumFractionDigits = 1
  26. }
  27. formatter.roundingMode = .halfUp
  28. return formatter
  29. }
  30. var body: some View {
  31. Form {
  32. Section(
  33. header: Text("Override your Basal, ISF, CR and Target profiles"),
  34. footer: Text("" + (!state.isEnabled ? "Currently no Override active" : ""))
  35. ) {
  36. Toggle(isOn: $state.isEnabled) {
  37. Text("Override Profiles")
  38. }._onBindingChange($state.isEnabled, perform: { _ in
  39. if !state.isEnabled {
  40. state.duration = 0
  41. state.percentage = 100
  42. state._indefinite = true
  43. state.override_target = false
  44. state.saveSettings()
  45. }
  46. })
  47. }
  48. if state.isEnabled {
  49. Section(
  50. header: Text("Total Insulin Adjustment"),
  51. footer: Text(
  52. "Your profile basal insulin will be adjusted with the override percentage and your profile ISF and CR will be inversly adjusted with the percentage.\n\nIf you toggle off the override every profile setting will return to normal."
  53. )
  54. ) {
  55. VStack {
  56. Slider(
  57. value: $state.percentage,
  58. in: 10 ... 200,
  59. step: 1,
  60. onEditingChanged: { editing in
  61. isEditing = editing
  62. }
  63. ).accentColor(state.percentage >= 130 ? .red : .blue)
  64. Text("\(state.percentage.formatted(.number)) %")
  65. .foregroundColor(
  66. state
  67. .percentage >= 130 ? .red :
  68. (isEditing ? .orange : .blue)
  69. )
  70. .font(.largeTitle)
  71. Spacer()
  72. Toggle(isOn: $state._indefinite) {
  73. Text("Enable indefinitely")
  74. }
  75. }
  76. if !state._indefinite {
  77. HStack {
  78. Text("Duration")
  79. DecimalTextField("0", value: $state.duration, formatter: formatter, cleanInput: false)
  80. Text("minutes").foregroundColor(.secondary)
  81. }
  82. }
  83. HStack {
  84. Toggle(isOn: $state.override_target) {
  85. Text("Override Profile Target")
  86. }
  87. }
  88. if state.override_target {
  89. HStack {
  90. Text("Target Glucose")
  91. DecimalTextField("0", value: $state.target, formatter: glucoseFormatter, cleanInput: false)
  92. Text(state.units.rawValue).foregroundColor(.secondary)
  93. }
  94. }
  95. Button("Save") {
  96. showAlert.toggle()
  97. alertSring = "Selected Override:\n\n\(state.percentage.formatted(.number)) %, " +
  98. (
  99. state.duration > 0 || !state
  100. ._indefinite ?
  101. (
  102. state
  103. .duration
  104. .formatted(.number.grouping(.never).rounded().precision(.fractionLength(0))) +
  105. " min."
  106. ) :
  107. " infinite duration."
  108. ) +
  109. (
  110. (state.target == 0 || !state.override_target) ? "" :
  111. (" Target: " + state.target.formatted() + " " + state.units.rawValue + ".")
  112. )
  113. +
  114. "\n\n"
  115. +
  116. "Saving this override will change your Profiles and/or your Target Glucose used for looping during the entire selected duration. Tapping save will start your new overide or edit your current active override."
  117. }
  118. .disabled(
  119. !state
  120. .isEnabled || (state.percentage == 100 && !state.override_target) ||
  121. (!state._indefinite && state.duration == 0 || (state.override_target && state.target == 0))
  122. )
  123. .accentColor(.orange)
  124. .buttonStyle(BorderlessButtonStyle())
  125. .font(.callout)
  126. .frame(maxWidth: .infinity, alignment: .center)
  127. .controlSize(.mini)
  128. .alert(
  129. alertSring,
  130. isPresented: $showAlert,
  131. actions: {
  132. Button("Cancel", role: .cancel) {}
  133. Button("Start Override", role: .destructive) {
  134. if state._indefinite {
  135. state.duration = 0
  136. } else if state.duration == 0 {
  137. state.isEnabled = false
  138. }
  139. state.saveSettings()
  140. dismiss()
  141. }
  142. }
  143. )
  144. }
  145. }
  146. }
  147. .onAppear(perform: configureView)
  148. .onAppear { state.savedSettings() }
  149. }
  150. }
  151. }