PreferencesEditorViewModel.swift 12 KB

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