PreferencesEditorViewModel.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import Foundation
  2. import SwiftUI
  3. extension PreferencesEditor {
  4. class ViewModel<Provider>: BaseViewModel<Provider>, ObservableObject,
  5. PreferencesSettable where Provider: PreferencesEditorProvider
  6. {
  7. @Injected() var settingsManager: SettingsManager!
  8. private(set) var preferences = Preferences()
  9. @Published var unitsIndex = 1
  10. @Published var allowAnnouncements = false
  11. @Published var insulinReqFraction: Decimal = 0.7
  12. @Published var skipBolusScreenAfterCarbs = false
  13. @Published var decimalFields: [Field<Decimal>] = []
  14. @Published var boolFields: [Field<Bool>] = []
  15. @Published var insulinCurveField = Field<InsulinCurve>(
  16. displayName: "Insulin curve",
  17. keypath: \.curve,
  18. value: .rapidActing
  19. )
  20. override func subscribe() {
  21. preferences = provider.preferences
  22. unitsIndex = settingsManager.settings.units == .mgdL ? 0 : 1
  23. allowAnnouncements = settingsManager.settings.allowAnnouncements
  24. insulinCurveField.value = preferences.curve
  25. insulinCurveField.settable = self
  26. insulinReqFraction = settingsManager.settings.insulinReqFraction ?? 0.7
  27. skipBolusScreenAfterCarbs = settingsManager.settings.skipBolusScreenAfterCarbs ?? false
  28. $unitsIndex
  29. .removeDuplicates()
  30. .sink { [weak self] index in
  31. self?.settingsManager.settings.units = index == 0 ? .mgdL : .mmolL
  32. }
  33. .store(in: &lifetime)
  34. $allowAnnouncements
  35. .removeDuplicates()
  36. .sink { [weak self] allow in
  37. self?.settingsManager.settings.allowAnnouncements = allow
  38. }
  39. .store(in: &lifetime)
  40. $insulinReqFraction
  41. .removeDuplicates()
  42. .sink { [weak self] fraction in
  43. self?.settingsManager.settings.insulinReqFraction = fraction
  44. }
  45. .store(in: &lifetime)
  46. $skipBolusScreenAfterCarbs
  47. .removeDuplicates()
  48. .sink { [weak self] skip in
  49. self?.settingsManager.settings.skipBolusScreenAfterCarbs = skip
  50. }
  51. .store(in: &lifetime)
  52. boolFields = [
  53. Field(
  54. displayName: "Rewind Resets Autosens",
  55. keypath: \.rewindResetsAutosens,
  56. value: preferences.rewindResetsAutosens,
  57. settable: self
  58. ),
  59. Field(
  60. displayName: "High Temptarget Raises Sensitivity",
  61. keypath: \.highTemptargetRaisesSensitivity,
  62. value: preferences.highTemptargetRaisesSensitivity,
  63. settable: self
  64. ),
  65. Field(
  66. displayName: "Low Temptarget Lowers Sensitivity",
  67. keypath: \.lowTemptargetLowersSensitivity,
  68. value: preferences.lowTemptargetLowersSensitivity,
  69. settable: self
  70. ),
  71. Field(
  72. displayName: "Sensitivity Raises Target",
  73. keypath: \.sensitivityRaisesTarget,
  74. value: preferences.sensitivityRaisesTarget,
  75. settable: self
  76. ),
  77. Field(
  78. displayName: "Resistance Lowers Target",
  79. keypath: \.resistanceLowersTarget,
  80. value: preferences.resistanceLowersTarget,
  81. settable: self
  82. ),
  83. Field(
  84. displayName: "Advanced Target Adjustments",
  85. keypath: \.advTargetAdjustments,
  86. value: preferences.advTargetAdjustments,
  87. settable: self
  88. ),
  89. Field(
  90. displayName: "Exercise Mode",
  91. keypath: \.exerciseMode,
  92. value: preferences.exerciseMode,
  93. settable: self
  94. ),
  95. Field(
  96. displayName: "Wide BG Target Range",
  97. keypath: \.wideBGTargetRange,
  98. value: preferences.wideBGTargetRange,
  99. settable: self
  100. ),
  101. Field(
  102. displayName: "Skip Neutral Temps",
  103. keypath: \.skipNeutralTemps,
  104. value: preferences.skipNeutralTemps,
  105. settable: self
  106. ),
  107. Field(
  108. displayName: "Unsuspend If No Temp",
  109. keypath: \.unsuspendIfNoTemp,
  110. value: preferences.unsuspendIfNoTemp,
  111. settable: self
  112. ),
  113. Field(
  114. displayName: "Enable UAM",
  115. keypath: \.enableUAM,
  116. value: preferences.enableUAM,
  117. settable: self
  118. ),
  119. // Field(
  120. // displayName: "A52 Risk Enable",
  121. // keypath: \.a52RiskEnable,
  122. // value: preferences.a52RiskEnable,
  123. // settable: self
  124. // ),
  125. Field(
  126. displayName: "Enable SMB With COB",
  127. keypath: \.enableSMBWithCOB,
  128. value: preferences.enableSMBWithCOB,
  129. settable: self
  130. ),
  131. Field(
  132. displayName: "Enable SMB With Temptarget",
  133. keypath: \.enableSMBWithTemptarget,
  134. value: preferences.enableSMBWithTemptarget,
  135. settable: self
  136. ),
  137. Field(
  138. displayName: "Enable SMB Always",
  139. keypath: \.enableSMBAlways,
  140. value: preferences.enableSMBAlways,
  141. settable: self
  142. ),
  143. Field(
  144. displayName: "Enable SMB After Carbs",
  145. keypath: \.enableSMBAfterCarbs,
  146. value: preferences.enableSMBAfterCarbs,
  147. settable: self
  148. ),
  149. Field(
  150. displayName: "Allow SMB With High Temptarget",
  151. keypath: \.allowSMBWithHighTemptarget,
  152. value: preferences.allowSMBWithHighTemptarget,
  153. settable: self
  154. ),
  155. Field(
  156. displayName: "Use Custom Peak Time",
  157. keypath: \.useCustomPeakTime,
  158. value: preferences.useCustomPeakTime,
  159. settable: self
  160. ),
  161. Field(
  162. displayName: "Suspend Zeros IOB",
  163. keypath: \.suspendZerosIOB,
  164. value: preferences.suspendZerosIOB,
  165. settable: self
  166. )
  167. ]
  168. decimalFields = [
  169. Field(
  170. displayName: "Max IOB",
  171. keypath: \.maxIOB,
  172. value: preferences.maxIOB,
  173. settable: self
  174. ),
  175. Field(
  176. displayName: "Max Daily Safety Multiplier",
  177. keypath: \.maxDailySafetyMultiplier,
  178. value: preferences.maxDailySafetyMultiplier,
  179. settable: self
  180. ),
  181. Field(
  182. displayName: "Current Basal Safety Multiplier",
  183. keypath: \.currentBasalSafetyMultiplier,
  184. value: preferences.currentBasalSafetyMultiplier,
  185. settable: self
  186. ),
  187. Field(
  188. displayName: "Autosens Max",
  189. keypath: \.autosensMax,
  190. value: preferences.autosensMax,
  191. settable: self
  192. ),
  193. Field(
  194. displayName: "Autosens Min",
  195. keypath: \.autosensMin,
  196. value: preferences.autosensMin,
  197. settable: self
  198. ),
  199. Field(
  200. displayName: "Half Basal Exercise Target",
  201. keypath: \.halfBasalExerciseTarget,
  202. value: preferences.halfBasalExerciseTarget,
  203. settable: self
  204. ),
  205. Field(
  206. displayName: "Max COB",
  207. keypath: \.maxCOB,
  208. value: preferences.maxCOB,
  209. settable: self
  210. ),
  211. Field(
  212. displayName: "Bolus Snooze DIA Divisor",
  213. keypath: \.bolusSnoozeDIADivisor,
  214. value: preferences.bolusSnoozeDIADivisor,
  215. settable: self
  216. ),
  217. Field(
  218. displayName: "Min 5m Carbimpact",
  219. keypath: \.min5mCarbimpact,
  220. value: preferences.min5mCarbimpact,
  221. settable: self
  222. ),
  223. Field(
  224. displayName: "Autotune ISF Adjustment Fraction",
  225. keypath: \.autotuneISFAdjustmentFraction,
  226. value: preferences.autotuneISFAdjustmentFraction,
  227. settable: self
  228. ),
  229. Field(
  230. displayName: "Remaining Carbs Fraction",
  231. keypath: \.remainingCarbsFraction,
  232. value: preferences.remainingCarbsFraction,
  233. settable: self
  234. ),
  235. Field(
  236. displayName: "Remaining Carbs Cap",
  237. keypath: \.remainingCarbsCap,
  238. value: preferences.remainingCarbsCap,
  239. settable: self
  240. ),
  241. Field(
  242. displayName: "Max SMB Basal Minutes",
  243. keypath: \.maxSMBBasalMinutes,
  244. value: preferences.maxSMBBasalMinutes,
  245. settable: self
  246. ),
  247. Field(
  248. displayName: "Max UAM SMB Basal Minutes",
  249. keypath: \.maxUAMSMBBasalMinutes,
  250. value: preferences.maxUAMSMBBasalMinutes,
  251. settable: self
  252. ),
  253. Field(
  254. displayName: "SMB Interval",
  255. keypath: \.smbInterval,
  256. value: preferences.smbInterval,
  257. settable: self
  258. ),
  259. Field(
  260. displayName: "Bolus Increment",
  261. keypath: \.bolusIncrement,
  262. value: preferences.bolusIncrement,
  263. settable: self
  264. ),
  265. Field(
  266. displayName: "Insulin Peak Time",
  267. keypath: \.insulinPeakTime,
  268. value: preferences.insulinPeakTime,
  269. settable: self
  270. ),
  271. Field(
  272. displayName: "Carbs Req Threshold",
  273. keypath: \.carbsReqThreshold,
  274. value: preferences.carbsReqThreshold,
  275. settable: self
  276. ),
  277. Field(
  278. displayName: "Noisy CGM Target Multiplier",
  279. keypath: \.noisyCGMTargetMultiplier,
  280. value: preferences.noisyCGMTargetMultiplier,
  281. settable: self
  282. )
  283. ]
  284. }
  285. func onSet<T>(_ keypath: WritableKeyPath<Preferences, T>, value: T) {
  286. preferences[keyPath: keypath] = value
  287. save()
  288. }
  289. func save() {
  290. provider.savePreferences(preferences)
  291. }
  292. }
  293. }