TargetBehavoirRootView.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import SwiftUI
  2. import Swinject
  3. extension TargetBehavoir {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @StateObject var state = StateModel()
  7. @State private var shouldDisplayHint: Bool = false
  8. @State var hintDetent = PresentationDetent.large
  9. @State var selectedVerboseHint: AnyView?
  10. @State var hintLabel: String?
  11. @State private var decimalPlaceholder: Decimal = 0.0
  12. @State private var booleanPlaceholder: Bool = false
  13. @State private var showAutosensMaxAlert = false
  14. @Environment(\.colorScheme) var colorScheme
  15. @EnvironmentObject var appIcons: Icons
  16. @Environment(AppState.self) var appState
  17. var body: some View {
  18. List {
  19. SettingInputSection(
  20. decimalValue: $decimalPlaceholder,
  21. booleanValue: $state.highTemptargetRaisesSensitivity,
  22. shouldDisplayHint: $shouldDisplayHint,
  23. selectedVerboseHint: Binding(
  24. get: { selectedVerboseHint },
  25. set: {
  26. selectedVerboseHint = $0.map { AnyView($0) }
  27. hintLabel = String(
  28. localized:
  29. "High Temp Target Raises Sensitivity",
  30. comment: "High Temp Target Raises Sensitivity"
  31. )
  32. }
  33. ),
  34. units: state.units,
  35. type: .boolean,
  36. label: String(
  37. localized:
  38. "High Temp Target Raises Sensitivity",
  39. comment: "High Temp Target Raises Sensitivity"
  40. ),
  41. miniHint: String(
  42. localized: "Increase sensitivity when glucose is above target if a manual Temp Target > \(state.units == .mgdL ? "100" : 100.formattedAsMmolL) \(state.units.rawValue) is set."
  43. ),
  44. verboseHint:
  45. VStack(alignment: .leading, spacing: 10) {
  46. Text("Default: OFF").bold()
  47. Text(
  48. "When this feature is enabled, manually setting a temporary target above \(state.units == .mgdL ? "100" : 100.formattedAsMmolL) \(state.units.rawValue) will decrease the Autosens Ratio used for ISF and basal adjustments, resulting in less insulin delivered overall. This scales with the temporary target set; the higher the temp target, the lower the Autosens Ratio used."
  49. )
  50. Text(
  51. "If Half Basal Exercise Target is set to \(state.units == .mgdL ? "160" : 160.formattedAsMmolL) \(state.units.rawValue), a temp target of \(state.units == .mgdL ? "120" : 120.formattedAsMmolL) \(state.units.rawValue) uses an Autosens Ratio of 0.75. A temp target of \(state.units == .mgdL ? "140" : 140.formattedAsMmolL) \(state.units.rawValue) uses an Autosens Ratio of 0.6."
  52. )
  53. Text("Note: The effect of this can be adjusted with the Half Basal Exercise Target")
  54. },
  55. headerText: String(localized: "Algorithmic Target Settings")
  56. )
  57. SettingInputSection(
  58. decimalValue: $decimalPlaceholder,
  59. booleanValue: effectiveLowTTLowersSensBinding,
  60. shouldDisplayHint: $shouldDisplayHint,
  61. selectedVerboseHint: Binding(
  62. get: { selectedVerboseHint },
  63. set: {
  64. selectedVerboseHint = $0.map { AnyView($0) }
  65. hintLabel = String(
  66. localized:
  67. "Low Temp Target Lowers Sensitivity",
  68. comment: "Low Temp Target Lowers Sensitivity"
  69. )
  70. }
  71. ),
  72. units: state.units,
  73. type: .boolean,
  74. label: String(
  75. localized:
  76. "Low Temp Target Lowers Sensitivity",
  77. comment: "Low Temp Target Lowers Sensitivity"
  78. ),
  79. miniHint: String(
  80. localized: "Decrease sensitivity when glucose is below target if a manual Temp Target < \(state.units == .mgdL ? "100" : 100.formattedAsMmolL) \(state.units.rawValue) is set."
  81. ),
  82. verboseHint:
  83. VStack(alignment: .leading, spacing: 10) {
  84. Text("Default: OFF").bold()
  85. Text(
  86. "When this feature is enabled, setting a temporary target below \(state.units == .mgdL ? "100" : 100.formattedAsMmolL) \(state.units.rawValue) will increase the Autosens Ratio used for ISF and basal adjustments, resulting in more insulin delivered overall. This scales with the temporary target set; the lower the Temp Target, the higher the Autosens Ratio used. It requires Algorithm Settings > Autosens > Autosens Max to be set to > 100% to work."
  87. )
  88. Text(
  89. "If Half Basal Exercise Target is \(state.units == .mgdL ? "160" : 160.formattedAsMmolL) \(state.units.rawValue), a Temp Target of \(state.units == .mgdL ? "95" : 95.formattedAsMmolL) \(state.units.rawValue) uses an Autosens Ratio of 1.09. A Temp Target of \(state.units == .mgdL ? "85" : 85.formattedAsMmolL) \(state.units.rawValue) uses an Autosens Ratio of 1.33."
  90. )
  91. Text("Note: The effect of this can be adjusted with the Half Basal Exercise Target")
  92. }
  93. )
  94. SettingInputSection(
  95. decimalValue: $decimalPlaceholder,
  96. booleanValue: $state.sensitivityRaisesTarget,
  97. shouldDisplayHint: $shouldDisplayHint,
  98. selectedVerboseHint: Binding(
  99. get: { selectedVerboseHint },
  100. set: {
  101. selectedVerboseHint = $0.map { AnyView($0) }
  102. hintLabel = String(localized: "Sensitivity Raises Target", comment: "Sensitivity Raises Target")
  103. }
  104. ),
  105. units: state.units,
  106. type: .boolean,
  107. label: String(localized: "Sensitivity Raises Target", comment: "Sensitivity Raises Target"),
  108. miniHint: String(localized: "Raise target glucose when Autosens Ratio is <1."),
  109. verboseHint: VStack(alignment: .leading, spacing: 10) {
  110. Text("Default: OFF").bold()
  111. Text(
  112. "Enabling this feature causes Trio to automatically raise the targeted glucose if it detects an increase in insulin sensitivity from your baseline."
  113. )
  114. }
  115. )
  116. SettingInputSection(
  117. decimalValue: $decimalPlaceholder,
  118. booleanValue: $state.resistanceLowersTarget,
  119. shouldDisplayHint: $shouldDisplayHint,
  120. selectedVerboseHint: Binding(
  121. get: { selectedVerboseHint },
  122. set: {
  123. selectedVerboseHint = $0.map { AnyView($0) }
  124. hintLabel = String(localized: "Resistance Lowers Target", comment: "Resistance Lowers Target")
  125. }
  126. ),
  127. units: state.units,
  128. type: .boolean,
  129. label: String(localized: "Resistance Lowers Target", comment: "Resistance Lowers Target"),
  130. miniHint: String(localized: "Lower target glucose when Autosens Ratio is >1."),
  131. verboseHint: VStack(alignment: .leading, spacing: 10) {
  132. Text("Default: OFF").bold()
  133. Text(
  134. "Enabling this feature causes Trio to automatically reduce the targeted glucose if it detects a decrease in sensitivity (resistance) from your baseline."
  135. )
  136. }
  137. )
  138. SettingInputSection(
  139. decimalValue: $state.halfBasalExerciseTarget,
  140. booleanValue: $booleanPlaceholder,
  141. shouldDisplayHint: $shouldDisplayHint,
  142. selectedVerboseHint: Binding(
  143. get: { selectedVerboseHint },
  144. set: {
  145. selectedVerboseHint = $0.map { AnyView($0) }
  146. hintLabel = String(localized: "Half Basal Exercise Target", comment: "Half Basal Exercise Target")
  147. }
  148. ),
  149. units: state.units,
  150. type: .decimal("halfBasalExerciseTarget"),
  151. label: String(localized: "Half Basal Exercise Target", comment: "Half Basal Exercise Target"),
  152. miniHint: String(localized: "Scales down your basal rate to 50% at this value."),
  153. verboseHint:
  154. VStack(alignment: .leading, spacing: 10) {
  155. Text(
  156. "Default: \(state.units == .mgdL ? "160" : 160.formattedAsMmolL) \(state.units.rawValue)"
  157. )
  158. .bold()
  159. Text(
  160. "The Half Basal Exercise Target allows you to scale down your basal insulin during exercise or scale up your basal insulin when eating soon when a temporary glucose target is set."
  161. )
  162. Text(
  163. "For example, at a temp target of \(state.units == .mgdL ? "160" : 160.formattedAsMmolL) \(state.units.rawValue), your basal is reduced to 50%, but this scales depending on the target (e.g., 75% at \(state.units == .mgdL ? "120" : 120.formattedAsMmolL) \(state.units.rawValue), 60% at \(state.units == .mgdL ? "140" : 140.formattedAsMmolL) \(state.units.rawValue))."
  164. )
  165. Text(
  166. "Note: This setting is only utilized if the settings \"Low Temp Target Lowers Sensitivity\" OR \"High Temp Target Raises Sensitivity\" are enabled."
  167. )
  168. }
  169. )
  170. }
  171. .listSectionSpacing(sectionSpacing)
  172. .sheet(isPresented: $shouldDisplayHint) {
  173. SettingInputHintView(
  174. hintDetent: $hintDetent,
  175. shouldDisplayHint: $shouldDisplayHint,
  176. hintLabel: hintLabel ?? "",
  177. hintText: selectedVerboseHint ?? AnyView(EmptyView()),
  178. sheetTitle: String(localized: "Help", comment: "Help sheet title")
  179. )
  180. }
  181. .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
  182. .onAppear(perform: configureView)
  183. .alert(
  184. "Cannot Enable This Setting",
  185. isPresented: $showAutosensMaxAlert
  186. ) {
  187. // Alert button(s). For a single button:
  188. Button("Got it!", role: .cancel) {}
  189. } message: {
  190. Text(
  191. "This feature cannot be enabled unless Algorithm Settings > Autosens > Autosens Max is set higher than 100%."
  192. )
  193. }
  194. .navigationTitle("Target Behavior")
  195. .navigationBarTitleDisplayMode(.automatic)
  196. }
  197. private var effectiveLowTTLowersSensBinding: Binding<Bool> {
  198. Binding(
  199. get: { state.autosensMax > 1 && state.lowTemptargetLowersSensitivity },
  200. set: { newValue in
  201. if newValue, state.autosensMax <= 1 {
  202. showAutosensMaxAlert = true
  203. } else {
  204. state.lowTemptargetLowersSensitivity = newValue
  205. }
  206. }
  207. )
  208. }
  209. }
  210. }