PreferencesEditorViewModel.swift 11 KB

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