DataTableStateModel.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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().map {
  24. Treatment(units: units, type: .carbs, date: $0.createdAt, amount: $0.carbs)
  25. }
  26. let boluses = self.provider.pumpHistory()
  27. .filter { $0.type == .bolus }
  28. .map {
  29. Treatment(units: units, type: .bolus, date: $0.timestamp, amount: $0.amount)
  30. }
  31. let tempBasals = self.provider.pumpHistory()
  32. .filter { $0.type == .tempBasal || $0.type == .tempBasalDuration }
  33. .chunks(ofCount: 2)
  34. .compactMap { chunk -> Treatment? in
  35. let chunk = Array(chunk)
  36. guard chunk.count == 2, chunk[0].type == .tempBasal,
  37. chunk[1].type == .tempBasalDuration else { return nil }
  38. return Treatment(
  39. units: units,
  40. type: .tempBasal,
  41. date: chunk[0].timestamp,
  42. amount: chunk[0].rate ?? 0,
  43. secondAmount: nil,
  44. duration: Decimal(chunk[1].durationMin ?? 0)
  45. )
  46. }
  47. let tempTargets = self.provider.tempTargets()
  48. .map {
  49. Treatment(
  50. units: units,
  51. type: .tempTarget,
  52. date: $0.createdAt,
  53. amount: $0.targetBottom ?? 0,
  54. secondAmount: $0.targetTop,
  55. duration: $0.duration
  56. )
  57. }
  58. let suspend = self.provider.pumpHistory()
  59. .filter { $0.type == .pumpSuspend }
  60. .map {
  61. Treatment(units: units, type: .suspend, date: $0.timestamp)
  62. }
  63. let resume = self.provider.pumpHistory()
  64. .filter { $0.type == .pumpResume }
  65. .map {
  66. Treatment(units: units, type: .resume, date: $0.timestamp)
  67. }
  68. DispatchQueue.main.async {
  69. self.treatments = [carbs, boluses, tempBasals, tempTargets, suspend, resume]
  70. .flatMap { $0 }
  71. .sorted { $0.date > $1.date }
  72. }
  73. }
  74. }
  75. func setupGlucose() {
  76. DispatchQueue.main.async {
  77. self.glucose = self.provider.glucose().map(Glucose.init)
  78. }
  79. }
  80. func deleteCarbs(at date: Date) {
  81. provider.deleteCarbs(at: date)
  82. }
  83. func deleteInsulin(at date: Date) {
  84. unlockmanager.unlock()
  85. .sink { _ in } receiveValue: { [weak self] _ in
  86. guard let self = self else { return }
  87. self.provider.deleteInsulin(at: date)
  88. }
  89. .store(in: &lifetime)
  90. }
  91. func deleteGlucose(at index: Int) {
  92. let id = glucose[index].id
  93. provider.deleteGlucose(id: id)
  94. }
  95. }
  96. }
  97. extension DataTable.StateModel:
  98. SettingsObserver,
  99. PumpHistoryObserver,
  100. TempTargetsObserver,
  101. CarbsObserver,
  102. GlucoseObserver
  103. {
  104. func settingsDidChange(_: FreeAPSSettings) {
  105. setupTreatments()
  106. }
  107. func pumpHistoryDidUpdate(_: [PumpHistoryEvent]) {
  108. setupTreatments()
  109. }
  110. func tempTargetsDidUpdate(_: [TempTarget]) {
  111. setupTreatments()
  112. }
  113. func carbsDidUpdate(_: [CarbsEntry]) {
  114. setupTreatments()
  115. }
  116. func glucoseDidUpdate(_: [BloodGlucose]) {
  117. setupGlucose()
  118. }
  119. }