DynamicSettingsRootView.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import SwiftUI
  2. import Swinject
  3. extension DynamicSettings {
  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: String?
  10. @State var hintLabel: String?
  11. @State private var decimalPlaceholder: Decimal = 0.0
  12. @State private var booleanPlaceholder: Bool = false
  13. private var conversionFormatter: NumberFormatter {
  14. let formatter = NumberFormatter()
  15. formatter.numberStyle = .decimal
  16. formatter.maximumFractionDigits = 1
  17. return formatter
  18. }
  19. @Environment(\.colorScheme) var colorScheme
  20. var color: LinearGradient {
  21. colorScheme == .dark ? LinearGradient(
  22. gradient: Gradient(colors: [
  23. Color.bgDarkBlue,
  24. Color.bgDarkerDarkBlue
  25. ]),
  26. startPoint: .top,
  27. endPoint: .bottom
  28. )
  29. :
  30. LinearGradient(
  31. gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
  32. startPoint: .top,
  33. endPoint: .bottom
  34. )
  35. }
  36. private var formatter: NumberFormatter {
  37. let formatter = NumberFormatter()
  38. formatter.numberStyle = .decimal
  39. return formatter
  40. }
  41. private var glucoseFormatter: NumberFormatter {
  42. let formatter = NumberFormatter()
  43. formatter.numberStyle = .decimal
  44. if state.units == .mmolL {
  45. formatter.maximumFractionDigits = 1
  46. } else { formatter.maximumFractionDigits = 0 }
  47. formatter.roundingMode = .halfUp
  48. return formatter
  49. }
  50. var body: some View {
  51. List {
  52. SettingInputSection(
  53. decimalValue: $decimalPlaceholder,
  54. booleanValue: $state.useNewFormula,
  55. shouldDisplayHint: $shouldDisplayHint,
  56. selectedVerboseHint: Binding(
  57. get: { selectedVerboseHint },
  58. set: {
  59. selectedVerboseHint = $0
  60. hintLabel = "Activate Dynamic Sensitivity (ISF)"
  61. }
  62. ),
  63. units: state.units,
  64. type: .boolean,
  65. label: "Activate Dynamic Sensitivity (ISF)",
  66. miniHint: "Trio calculates insulin sensitivity (ISF) each loop cycle based on current blood sugar, daily insulin use, and an adjustment factor, within set limits.",
  67. verboseHint: "DynamicISF",
  68. headerText: "Dynamic Insulin Sensitivity"
  69. )
  70. if state.useNewFormula {
  71. SettingInputSection(
  72. decimalValue: $decimalPlaceholder,
  73. booleanValue: $state.enableDynamicCR,
  74. shouldDisplayHint: $shouldDisplayHint,
  75. selectedVerboseHint: Binding(
  76. get: { selectedVerboseHint },
  77. set: {
  78. selectedVerboseHint = $0
  79. hintLabel = "Activate Dynamic Carb Ratio (CR)"
  80. }
  81. ),
  82. units: state.units,
  83. type: .boolean,
  84. label: "Activate Dynamic Carb Ratio (CR)",
  85. miniHint: "Similar to Dynamic Sensitivity, Trio calculates a dynamic carb ratio every loop cycle.",
  86. verboseHint: "Logarithmic Dynamic Insulin Sensitivity"
  87. )
  88. SettingInputSection(
  89. decimalValue: $decimalPlaceholder,
  90. booleanValue: $state.sigmoid,
  91. shouldDisplayHint: $shouldDisplayHint,
  92. selectedVerboseHint: Binding(
  93. get: { selectedVerboseHint },
  94. set: {
  95. selectedVerboseHint = $0
  96. hintLabel = "Use Sigmoid Formula"
  97. }
  98. ),
  99. units: state.units,
  100. type: .boolean,
  101. label: "Use Sigmoid Formula",
  102. miniHint: "Alternative formula for dynamic ISF, that alters ISF based on distance from target BG",
  103. verboseHint: "Sigmoid Dynamic Insulin Sensitivity"
  104. )
  105. if !state.sigmoid {
  106. SettingInputSection(
  107. decimalValue: $state.adjustmentFactor,
  108. booleanValue: $booleanPlaceholder,
  109. shouldDisplayHint: $shouldDisplayHint,
  110. selectedVerboseHint: Binding(
  111. get: { selectedVerboseHint },
  112. set: {
  113. selectedVerboseHint = $0
  114. hintLabel = "Adjustment Factor"
  115. }
  116. ),
  117. units: state.units,
  118. type: .decimal("adjustmentFactor"),
  119. label: "Adjustment Factor",
  120. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  121. verboseHint: "Adjustment Factor for logarithmic dynamic sensitvity... bla bla bla"
  122. )
  123. } else {
  124. SettingInputSection(
  125. decimalValue: $state.adjustmentFactorSigmoid,
  126. booleanValue: $booleanPlaceholder,
  127. shouldDisplayHint: $shouldDisplayHint,
  128. selectedVerboseHint: Binding(
  129. get: { selectedVerboseHint },
  130. set: {
  131. selectedVerboseHint = $0
  132. hintLabel = "Sigmoid Adjustment Factor"
  133. }
  134. ),
  135. units: state.units,
  136. type: .decimal("adjustmentFactorSigmoid"),
  137. label: "Sigmoid Adjustment Factor",
  138. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  139. verboseHint: "Sigmoid Adjustment Factor… should be 0.5… bla bla ba"
  140. )
  141. }
  142. SettingInputSection(
  143. decimalValue: $state.weightPercentage,
  144. booleanValue: $booleanPlaceholder,
  145. shouldDisplayHint: $shouldDisplayHint,
  146. selectedVerboseHint: Binding(
  147. get: { selectedVerboseHint },
  148. set: {
  149. selectedVerboseHint = $0
  150. hintLabel = "Weighted Average of TDD"
  151. }
  152. ),
  153. units: state.units,
  154. type: .decimal("weightPercentage"),
  155. label: "Weighted Average of TDD",
  156. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  157. verboseHint: "Weight of past 24 hours"
  158. )
  159. SettingInputSection(
  160. decimalValue: $decimalPlaceholder,
  161. booleanValue: $state.tddAdjBasal,
  162. shouldDisplayHint: $shouldDisplayHint,
  163. selectedVerboseHint: Binding(
  164. get: { selectedVerboseHint },
  165. set: {
  166. selectedVerboseHint = $0
  167. hintLabel = "Adjust Basal"
  168. }
  169. ),
  170. units: state.units,
  171. type: .boolean,
  172. label: "Adjust Basal",
  173. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  174. verboseHint: "Adjust basal dynamically… bla bla"
  175. )
  176. SettingInputSection(
  177. decimalValue: $state.threshold_setting,
  178. booleanValue: $booleanPlaceholder,
  179. shouldDisplayHint: $shouldDisplayHint,
  180. selectedVerboseHint: Binding(
  181. get: { selectedVerboseHint },
  182. set: {
  183. selectedVerboseHint = $0
  184. hintLabel = "Threshold Setting"
  185. }
  186. ),
  187. units: state.units,
  188. type: .decimal("threshold_setting"),
  189. label: "Threshold Setting",
  190. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  191. verboseHint: "BG threshold"
  192. )
  193. }
  194. }
  195. .sheet(isPresented: $shouldDisplayHint) {
  196. SettingInputHintView(
  197. hintDetent: $hintDetent,
  198. shouldDisplayHint: $shouldDisplayHint,
  199. hintLabel: hintLabel ?? "",
  200. hintText: selectedVerboseHint ?? "",
  201. sheetTitle: "Help"
  202. )
  203. }
  204. .scrollContentBackground(.hidden).background(color)
  205. .onAppear(perform: configureView)
  206. .navigationBarTitle("Dynamic Settings")
  207. .navigationBarTitleDisplayMode(.automatic)
  208. .onDisappear {
  209. state.saveIfChanged()
  210. }
  211. }
  212. }
  213. }