DataTableViewModel.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import SwiftUI
  2. extension DataTable {
  3. class ViewModel<Provider>: BaseViewModel<Provider>, ObservableObject where Provider: DataTableProvider {
  4. @Injected() var broadcaster: Broadcaster!
  5. @Injected() var settingsManager: SettingsManager!
  6. @Published var items: [Item] = []
  7. override func subscribe() {
  8. setupItems()
  9. broadcaster.register(SettingsObserver.self, observer: self)
  10. broadcaster.register(PumpHistoryObserver.self, observer: self)
  11. broadcaster.register(TempTargetsObserver.self, observer: self)
  12. broadcaster.register(CarbsObserver.self, observer: self)
  13. }
  14. private func setupItems() {
  15. DispatchQueue.global().async {
  16. let units = self.settingsManager.settings.units
  17. let carbs = self.provider.carbs().map {
  18. Item(units: units, type: .carbs, date: $0.createdAt, amount: $0.carbs)
  19. }
  20. let boluses = self.provider.pumpHistory()
  21. .filter { $0.type == .bolus }
  22. .map {
  23. Item(units: units, type: .bolus, date: $0.timestamp, amount: $0.amount)
  24. }
  25. let tempBasals = self.provider.pumpHistory()
  26. .filter { $0.type == .tempBasal || $0.type == .tempBasalDuration }
  27. .chunks(ofCount: 2)
  28. .compactMap { chunk -> Item? in
  29. let chunk = Array(chunk)
  30. guard chunk.count == 2, chunk[0].type == .tempBasal,
  31. chunk[1].type == .tempBasalDuration else { return nil }
  32. return Item(
  33. units: units,
  34. type: .tempBasal,
  35. date: chunk[0].timestamp,
  36. amount: chunk[0].rate ?? 0,
  37. secondAmount: nil,
  38. duration: Decimal(chunk[1].durationMin ?? 0)
  39. )
  40. }
  41. let tempTargets = self.provider.tempTargets()
  42. .map {
  43. Item(
  44. units: units,
  45. type: .tempTarget,
  46. date: $0.createdAt,
  47. amount: $0.targetBottom ?? 0,
  48. secondAmount: $0.targetTop,
  49. duration: $0.duration
  50. )
  51. }
  52. let suspend = self.provider.pumpHistory()
  53. .filter { $0.type == .pumpSuspend }
  54. .map {
  55. Item(units: units, type: .suspend, date: $0.timestamp)
  56. }
  57. let resume = self.provider.pumpHistory()
  58. .filter { $0.type == .pumpResume }
  59. .map {
  60. Item(units: units, type: .resume, date: $0.timestamp)
  61. }
  62. DispatchQueue.main.async {
  63. self.items = [carbs, boluses, tempBasals, tempTargets, suspend, resume]
  64. .flatMap { $0 }
  65. .sorted { $0.date > $1.date }
  66. }
  67. }
  68. }
  69. func deleteCarbs(at date: Date) {
  70. provider.deleteCarbs(at: date)
  71. }
  72. }
  73. }
  74. extension DataTable.ViewModel:
  75. SettingsObserver,
  76. PumpHistoryObserver,
  77. TempTargetsObserver,
  78. CarbsObserver
  79. {
  80. func settingsDidChange(_: FreeAPSSettings) {
  81. setupItems()
  82. }
  83. func pumpHistoryDidUpdate(_: [PumpHistoryEvent]) {
  84. setupItems()
  85. }
  86. func tempTargetsDidUpdate(_: [TempTarget]) {
  87. setupItems()
  88. }
  89. func carbsDidUpdate(_: [CarbsEntry]) {
  90. setupItems()
  91. }
  92. }