DataTableDataFlow.swift 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import Foundation
  2. import SwiftUI
  3. enum DataTable {
  4. enum Config {}
  5. enum Mode: String, Hashable, Identifiable, CaseIterable {
  6. case treatments
  7. case meals
  8. case glucose
  9. var id: String { rawValue }
  10. var name: String {
  11. var name: String = ""
  12. switch self {
  13. case .treatments:
  14. name = "Treatments"
  15. case .meals:
  16. name = "Meals"
  17. case .glucose:
  18. name = "Glucose"
  19. }
  20. return NSLocalizedString(name, comment: "History Mode")
  21. }
  22. }
  23. enum DataType: String, Equatable {
  24. case carbs
  25. case fpus
  26. case bolus
  27. case tempBasal
  28. case tempTarget
  29. case suspend
  30. case resume
  31. var name: String {
  32. var name: String = ""
  33. switch self {
  34. case .carbs:
  35. name = "Carbs"
  36. case .fpus:
  37. name = "Protein / Fat"
  38. case .bolus:
  39. name = "Bolus"
  40. case .tempBasal:
  41. name = "Temp Basal"
  42. case .tempTarget:
  43. name = "Temp Target"
  44. case .suspend:
  45. name = "Suspend"
  46. case .resume:
  47. name = "Resume"
  48. }
  49. return NSLocalizedString(name, comment: "Treatment type")
  50. }
  51. }
  52. class Treatment: Identifiable, Hashable, Equatable {
  53. let id: String
  54. let idPumpEvent: String?
  55. let units: GlucoseUnits
  56. let type: DataType
  57. let date: Date
  58. let amount: Decimal?
  59. let secondAmount: Decimal?
  60. let duration: Decimal?
  61. let isFPU: Bool?
  62. let fpuID: String?
  63. let note: String?
  64. let isSMB: Bool?
  65. let isExternal: Bool?
  66. private var numberFormatter: NumberFormatter {
  67. let formatter = NumberFormatter()
  68. formatter.numberStyle = .decimal
  69. formatter.maximumFractionDigits = 2
  70. return formatter
  71. }
  72. private var tempTargetFormater: NumberFormatter {
  73. let formatter = NumberFormatter()
  74. formatter.numberStyle = .decimal
  75. formatter.maximumFractionDigits = 1
  76. return formatter
  77. }
  78. init(
  79. units: GlucoseUnits,
  80. type: DataType,
  81. date: Date,
  82. amount: Decimal? = nil,
  83. secondAmount: Decimal? = nil,
  84. duration: Decimal? = nil,
  85. id: String? = nil,
  86. idPumpEvent: String? = nil,
  87. isFPU: Bool? = nil,
  88. fpuID: String? = nil,
  89. note: String? = nil,
  90. isSMB: Bool? = nil,
  91. isExternal: Bool? = nil
  92. ) {
  93. self.units = units
  94. self.type = type
  95. self.date = date
  96. self.amount = amount
  97. self.secondAmount = secondAmount
  98. self.duration = duration
  99. self.id = id ?? UUID().uuidString
  100. self.idPumpEvent = idPumpEvent
  101. self.isFPU = isFPU
  102. self.fpuID = fpuID
  103. self.note = note
  104. self.isSMB = isSMB
  105. self.isExternal = isExternal
  106. }
  107. static func == (lhs: Treatment, rhs: Treatment) -> Bool {
  108. lhs.id == rhs.id
  109. }
  110. func hash(into hasher: inout Hasher) {
  111. hasher.combine(id)
  112. }
  113. var amountText: String {
  114. guard let amount = amount else {
  115. return ""
  116. }
  117. if amount == 0, duration == 0 {
  118. return "Cancel temp"
  119. }
  120. switch type {
  121. case .carbs:
  122. return numberFormatter
  123. .string(from: amount as NSNumber)! + NSLocalizedString(" g", comment: "gram of carbs")
  124. case .fpus:
  125. return numberFormatter
  126. .string(from: amount as NSNumber)! + NSLocalizedString(" g", comment: "gram of carb equilvalents")
  127. case .bolus:
  128. var bolusText = " "
  129. if isSMB ?? false {}
  130. else if isExternal ?? false {
  131. bolusText += NSLocalizedString("External", comment: "External Insulin")
  132. } else {
  133. bolusText += NSLocalizedString("Manual", comment: "Manual Bolus")
  134. }
  135. return numberFormatter
  136. .string(from: amount as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit") + bolusText
  137. case .tempBasal:
  138. return numberFormatter
  139. .string(from: amount as NSNumber)! + NSLocalizedString(" U/hr", comment: "Unit insulin per hour")
  140. case .tempTarget:
  141. var converted = amount
  142. if units == .mmolL {
  143. converted = converted.asMmolL
  144. }
  145. guard var secondAmount = secondAmount else {
  146. return numberFormatter.string(from: converted as NSNumber)! + " \(units.rawValue)"
  147. }
  148. if units == .mmolL {
  149. secondAmount = secondAmount.asMmolL
  150. }
  151. return tempTargetFormater.string(from: converted as NSNumber)! + " - " + tempTargetFormater
  152. .string(from: secondAmount as NSNumber)! + " \(units.rawValue)"
  153. case .resume,
  154. .suspend:
  155. return type.name
  156. }
  157. }
  158. var color: Color {
  159. switch type {
  160. case .carbs:
  161. return .loopYellow
  162. case .fpus:
  163. return .orange.opacity(0.5)
  164. case .bolus:
  165. return Color.insulin
  166. case .tempBasal:
  167. return Color.insulin.opacity(0.4)
  168. case .resume,
  169. .suspend,
  170. .tempTarget:
  171. return .loopGray
  172. }
  173. }
  174. var durationText: String? {
  175. guard let duration = duration, duration > 0 else {
  176. return nil
  177. }
  178. return numberFormatter.string(from: duration as NSNumber)! + " min"
  179. }
  180. }
  181. class Glucose: Identifiable, Hashable, Equatable {
  182. static func == (lhs: DataTable.Glucose, rhs: DataTable.Glucose) -> Bool {
  183. lhs.glucose == rhs.glucose
  184. }
  185. let glucose: BloodGlucose
  186. init(glucose: BloodGlucose) {
  187. self.glucose = glucose
  188. }
  189. var id: String { glucose.id }
  190. }
  191. }
  192. protocol DataTableProvider: Provider {
  193. func pumpHistory() -> [PumpHistoryEvent]
  194. func tempTargets() -> [TempTarget]
  195. func carbs() -> [CarbsEntry]
  196. func glucose() -> [BloodGlucose]
  197. func deleteCarbs(_ treatement: DataTable.Treatment)
  198. func deleteInsulin(_ treatement: DataTable.Treatment)
  199. func deleteGlucose(id: String)
  200. }