PumpView.swift 6.6 KB

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