PumpView.swift 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import SwiftUI
  2. struct PumpView: View {
  3. @Binding var reservoir: Decimal?
  4. @Binding var battery: Battery?
  5. @Binding var name: String
  6. @Binding var expiresAtDate: Date?
  7. @Binding var timerDate: Date
  8. @Binding var boluses: [PumpHistoryEvent]
  9. @State var state: Home.StateModel
  10. @State var totalBolus: Decimal = 0
  11. private var reservoirFormatter: NumberFormatter {
  12. let formatter = NumberFormatter()
  13. formatter.numberStyle = .decimal
  14. formatter.maximumFractionDigits = 0
  15. return formatter
  16. }
  17. private var batteryFormatter: NumberFormatter {
  18. let formatter = NumberFormatter()
  19. formatter.numberStyle = .percent
  20. return formatter
  21. }
  22. private var numberFormatter: NumberFormatter {
  23. let formatter = NumberFormatter()
  24. formatter.numberStyle = .decimal
  25. formatter.maximumFractionDigits = 2
  26. return formatter
  27. }
  28. var body: some View {
  29. HStack {
  30. Text("IOB").font(.callout).foregroundColor(.secondary)
  31. Text(
  32. (numberFormatter.string(from: (state.suggestion?.iob ?? 0) as NSNumber) ?? "0") +
  33. NSLocalizedString(" U", comment: "Insulin unit")
  34. )
  35. .font(.callout).fontWeight(.bold)
  36. Spacer()
  37. Text("COB").font(.callout).foregroundColor(.secondary)
  38. Text(
  39. (numberFormatter.string(from: (state.suggestion?.cob ?? 0) as NSNumber) ?? "0") +
  40. NSLocalizedString(" g", comment: "gram of carbs")
  41. )
  42. .font(.callout).fontWeight(.bold)
  43. Spacer()
  44. if let reservoir = reservoir {
  45. HStack {
  46. Image(systemName: "drop.fill")
  47. .resizable()
  48. .aspectRatio(contentMode: .fit)
  49. .frame(maxHeight: 15)
  50. .foregroundColor(reservoirColor)
  51. if reservoir == 0xDEAD_BEEF {
  52. Text("50+ " + NSLocalizedString("U", comment: "Insulin unit")).font(.callout)
  53. .fontWeight(.bold)
  54. } else {
  55. Text(
  56. reservoirFormatter
  57. .string(from: reservoir as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
  58. )
  59. .font(.callout).fontWeight(.bold)
  60. }
  61. }
  62. }
  63. Spacer()
  64. if let battery = battery, battery.display ?? false, expiresAtDate == nil {
  65. HStack {
  66. Image(systemName: "battery.100")
  67. .resizable()
  68. .aspectRatio(contentMode: .fit)
  69. .frame(maxHeight: 15)
  70. .foregroundColor(batteryColor)
  71. Text("\(Int(battery.percent ?? 100)) %").font(.callout)
  72. .fontWeight(.bold)
  73. Text(calculateTINS())
  74. .font(.callout).fontWeight(.bold)
  75. }
  76. }
  77. if let date = expiresAtDate {
  78. HStack {
  79. Image(systemName: "stopwatch.fill")
  80. .resizable()
  81. .aspectRatio(contentMode: .fit)
  82. .frame(maxHeight: 15)
  83. .foregroundColor(timerColor)
  84. Text(remainingTimeString(time: date.timeIntervalSince(timerDate))).font(.callout)
  85. .fontWeight(.bold)
  86. }
  87. }
  88. }
  89. }
  90. //MARK: WORKS....BUT MAYBE TIMEZONE PROBLEMS COULD OCCUR
  91. //DEFINETELY SOMETHING FOR OUR TIMEZONE EXPERT.....
  92. func calculateTINS() -> String {
  93. let date = Date()
  94. let calendar = Calendar.current
  95. let offset = state.scale
  96. var offsetComponents = DateComponents()
  97. offsetComponents.hour = -offset.rawValue
  98. let startTime = calendar.date(byAdding: offsetComponents, to: date)!
  99. print("******************")
  100. print("die voll krasse start time ist: \(startTime)")
  101. let bolusesForCurrentDay = boluses.filter { $0.timestamp >= startTime && $0.type == .bolus }
  102. let totalBolus = bolusesForCurrentDay.map { $0.amount ?? 0 }.reduce(0, +)
  103. let roundedTotalBolus = Decimal(round(100 * Double(totalBolus)) / 100)
  104. return "\(roundedTotalBolus) U"
  105. }
  106. // MARK: THIS CRAP DOES NOT WORK
  107. // func calculateTINS() -> String {
  108. // let date = Date()
  109. // let calendar = Calendar.current
  110. // let offset = state.scale
  111. //
  112. // // let hour = calendar.component(.hour, from: date)
  113. // //
  114. // // let minutes = calendar.component(.minute, from: date)
  115. //
  116. // let startTime = calendar.startOfDay(for: date).addingTimeInterval(-Double(offset.rawValue))
  117. // print("******************")
  118. // print(startTime)
  119. //
  120. // let bolusesForCurrentDay = boluses.filter { $0.timestamp >= startTime && $0.type == .bolus }
  121. //
  122. // let totalBolus = bolusesForCurrentDay.map { $0.amount ?? 0 }.reduce(0, +)
  123. // let roundedTotalBolus = Decimal(round(100 * Double(totalBolus)) / 100)
  124. //
  125. // return "\(roundedTotalBolus) U"
  126. // }
  127. private func remainingTimeString(time: TimeInterval) -> String {
  128. guard time > 0 else {
  129. return NSLocalizedString("Replace pod", comment: "View/Header when pod expired")
  130. }
  131. var time = time
  132. let days = Int(time / 1.days.timeInterval)
  133. time -= days.days.timeInterval
  134. let hours = Int(time / 1.hours.timeInterval)
  135. time -= hours.hours.timeInterval
  136. let minutes = Int(time / 1.minutes.timeInterval)
  137. if days >= 1 {
  138. return "\(days)" + NSLocalizedString("d", comment: "abbreviation for days") + " \(hours)" +
  139. NSLocalizedString("h", comment: "abbreviation for hours")
  140. }
  141. if hours >= 1 {
  142. return "\(hours)" + NSLocalizedString("h", comment: "abbreviation for hours")
  143. }
  144. return "\(minutes)" + NSLocalizedString("m", comment: "abbreviation for minutes")
  145. }
  146. private var batteryColor: Color {
  147. guard let battery = battery, let percent = battery.percent else {
  148. return .gray
  149. }
  150. switch percent {
  151. case ...10:
  152. return .red
  153. case ...20:
  154. return .yellow
  155. default:
  156. return .green
  157. }
  158. }
  159. private var reservoirColor: Color {
  160. guard let reservoir = reservoir else {
  161. return .gray
  162. }
  163. switch reservoir {
  164. case ...10:
  165. return .red
  166. case ...30:
  167. return .yellow
  168. default:
  169. return .blue
  170. }
  171. }
  172. private var timerColor: Color {
  173. guard let expisesAt = expiresAtDate else {
  174. return .gray
  175. }
  176. let time = expisesAt.timeIntervalSince(timerDate)
  177. switch time {
  178. case ...8.hours.timeInterval:
  179. return .red
  180. case ...1.days.timeInterval:
  181. return .yellow
  182. default:
  183. return .green
  184. }
  185. }
  186. }
  187. struct Hairline: View {
  188. let color: Color
  189. var body: some View {
  190. Rectangle()
  191. .fill(color)
  192. .frame(width: UIScreen.main.bounds.width / 1.3, height: 1)
  193. .opacity(0.5)
  194. }
  195. }