PumpView.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. }
  75. }
  76. if let date = expiresAtDate {
  77. HStack {
  78. Image(systemName: "stopwatch.fill")
  79. .resizable()
  80. .aspectRatio(contentMode: .fit)
  81. .frame(maxHeight: 15)
  82. .foregroundColor(timerColor)
  83. Text(remainingTimeString(time: date.timeIntervalSince(timerDate))).font(.callout)
  84. .fontWeight(.bold)
  85. }
  86. }
  87. }
  88. }
  89. private func remainingTimeString(time: TimeInterval) -> String {
  90. guard time > 0 else {
  91. return NSLocalizedString("Replace pod", comment: "View/Header when pod expired")
  92. }
  93. var time = time
  94. let days = Int(time / 1.days.timeInterval)
  95. time -= days.days.timeInterval
  96. let hours = Int(time / 1.hours.timeInterval)
  97. time -= hours.hours.timeInterval
  98. let minutes = Int(time / 1.minutes.timeInterval)
  99. if days >= 1 {
  100. return "\(days)" + NSLocalizedString("d", comment: "abbreviation for days") + " \(hours)" +
  101. NSLocalizedString("h", comment: "abbreviation for hours")
  102. }
  103. if hours >= 1 {
  104. return "\(hours)" + NSLocalizedString("h", comment: "abbreviation for hours")
  105. }
  106. return "\(minutes)" + NSLocalizedString("m", comment: "abbreviation for minutes")
  107. }
  108. private var batteryColor: Color {
  109. guard let battery = battery, let percent = battery.percent else {
  110. return .gray
  111. }
  112. switch percent {
  113. case ...10:
  114. return .red
  115. case ...20:
  116. return .yellow
  117. default:
  118. return .green
  119. }
  120. }
  121. private var reservoirColor: Color {
  122. guard let reservoir = reservoir else {
  123. return .gray
  124. }
  125. switch reservoir {
  126. case ...10:
  127. return .red
  128. case ...30:
  129. return .yellow
  130. default:
  131. return .blue
  132. }
  133. }
  134. private var timerColor: Color {
  135. guard let expisesAt = expiresAtDate else {
  136. return .gray
  137. }
  138. let time = expisesAt.timeIntervalSince(timerDate)
  139. switch time {
  140. case ...8.hours.timeInterval:
  141. return .red
  142. case ...1.days.timeInterval:
  143. return .yellow
  144. default:
  145. return .green
  146. }
  147. }
  148. }
  149. struct Hairline: View {
  150. let color: Color
  151. var body: some View {
  152. Rectangle()
  153. .fill(color)
  154. .frame(width: UIScreen.main.bounds.width / 1.3, height: 1)
  155. .opacity(0.5)
  156. }
  157. }