DataTableStateModel.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import SwiftUI
  2. extension DataTable {
  3. final class StateModel: BaseStateModel<Provider> {
  4. @Injected() var broadcaster: Broadcaster!
  5. @Injected() var unlockmanager: UnlockManager!
  6. @Published var mode: Mode = .treatments
  7. @Published var treatments: [Treatment] = []
  8. @Published var glucose: [Glucose] = []
  9. var units: GlucoseUnits = .mmolL
  10. override func subscribe() {
  11. units = settingsManager.settings.units
  12. setupTreatments()
  13. setupGlucose()
  14. broadcaster.register(SettingsObserver.self, observer: self)
  15. broadcaster.register(PumpHistoryObserver.self, observer: self)
  16. broadcaster.register(TempTargetsObserver.self, observer: self)
  17. broadcaster.register(CarbsObserver.self, observer: self)
  18. broadcaster.register(GlucoseObserver.self, observer: self)
  19. }
  20. private func setupTreatments() {
  21. DispatchQueue.global().async {
  22. let units = self.settingsManager.settings.units
  23. let carbs = self.provider.carbs()
  24. .filter { !($0.isFPU ?? false) }
  25. .map {
  26. if let id = $0.id {
  27. return Treatment(
  28. units: units,
  29. type: .carbs,
  30. date: $0.createdAt,
  31. amount: $0.carbs,
  32. id: id
  33. )
  34. } else {
  35. return Treatment(units: units, type: .carbs, date: $0.createdAt, amount: $0.carbs)
  36. }
  37. }
  38. let fpus = self.provider.fpus()
  39. .filter { $0.isFPU ?? false }
  40. .map {
  41. Treatment(
  42. units: units,
  43. type: .fpus,
  44. date: $0.createdAt,
  45. amount: $0.carbs,
  46. id: $0.id,
  47. isFPU: $0.isFPU,
  48. fpuID: $0.fpuID
  49. )
  50. }
  51. let boluses = self.provider.pumpHistory()
  52. .filter { $0.type == .bolus }
  53. .map {
  54. Treatment(units: units, type: .bolus, date: $0.timestamp, amount: $0.amount, idPumpEvent: $0.id)
  55. }
  56. let tempBasals = self.provider.pumpHistory()
  57. .filter { $0.type == .tempBasal || $0.type == .tempBasalDuration }
  58. .chunks(ofCount: 2)
  59. .compactMap { chunk -> Treatment? in
  60. let chunk = Array(chunk)
  61. guard chunk.count == 2, chunk[0].type == .tempBasal,
  62. chunk[1].type == .tempBasalDuration else { return nil }
  63. return Treatment(
  64. units: units,
  65. type: .tempBasal,
  66. date: chunk[0].timestamp,
  67. amount: chunk[0].rate ?? 0,
  68. secondAmount: nil,
  69. duration: Decimal(chunk[1].durationMin ?? 0)
  70. )
  71. }
  72. let tempTargets = self.provider.tempTargets()
  73. .map {
  74. Treatment(
  75. units: units,
  76. type: .tempTarget,
  77. date: $0.createdAt,
  78. amount: $0.targetBottom ?? 0,
  79. secondAmount: $0.targetTop,
  80. duration: $0.duration
  81. )
  82. }
  83. let suspend = self.provider.pumpHistory()
  84. .filter { $0.type == .pumpSuspend }
  85. .map {
  86. Treatment(units: units, type: .suspend, date: $0.timestamp)
  87. }
  88. let resume = self.provider.pumpHistory()
  89. .filter { $0.type == .pumpResume }
  90. .map {
  91. Treatment(units: units, type: .resume, date: $0.timestamp)
  92. }
  93. DispatchQueue.main.async {
  94. self.treatments = [carbs, boluses, tempBasals, tempTargets, suspend, resume, fpus]
  95. .flatMap { $0 }
  96. .sorted { $0.date > $1.date }
  97. }
  98. }
  99. }
  100. func setupGlucose() {
  101. DispatchQueue.main.async {
  102. self.glucose = self.provider.glucose().map(Glucose.init)
  103. }
  104. }
  105. func deleteCarbs(_ treatment: Treatment) {
  106. provider.deleteCarbs(treatment)
  107. }
  108. func deleteInsulin(_ treatment: Treatment) {
  109. unlockmanager.unlock()
  110. .sink { _ in } receiveValue: { [weak self] _ in
  111. guard let self = self else { return }
  112. self.provider.deleteInsulin(treatment)
  113. }
  114. .store(in: &lifetime)
  115. }
  116. func deleteGlucose(at index: Int) {
  117. let id = glucose[index].id
  118. provider.deleteGlucose(id: id)
  119. }
  120. }
  121. }
  122. extension DataTable.StateModel:
  123. SettingsObserver,
  124. PumpHistoryObserver,
  125. TempTargetsObserver,
  126. CarbsObserver,
  127. GlucoseObserver
  128. {
  129. func settingsDidChange(_: FreeAPSSettings) {
  130. setupTreatments()
  131. }
  132. func pumpHistoryDidUpdate(_: [PumpHistoryEvent]) {
  133. setupTreatments()
  134. }
  135. func tempTargetsDidUpdate(_: [TempTarget]) {
  136. setupTreatments()
  137. }
  138. func carbsDidUpdate(_: [CarbsEntry]) {
  139. setupTreatments()
  140. }
  141. func glucoseDidUpdate(_: [BloodGlucose]) {
  142. setupGlucose()
  143. }
  144. }