CurrentGlucoseView.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import SwiftUI
  2. struct CurrentGlucoseView: View {
  3. @Binding var recentGlucose: BloodGlucose?
  4. @Binding var delta: Int?
  5. @Binding var units: GlucoseUnits
  6. private var glucoseFormatter: NumberFormatter {
  7. let formatter = NumberFormatter()
  8. formatter.numberStyle = .decimal
  9. formatter.maximumFractionDigits = 0
  10. if units == .mmolL {
  11. formatter.minimumFractionDigits = 1
  12. formatter.maximumFractionDigits = 1
  13. }
  14. return formatter
  15. }
  16. private var deltaFormatter: NumberFormatter {
  17. let formatter = NumberFormatter()
  18. formatter.numberStyle = .decimal
  19. formatter.maximumFractionDigits = 2
  20. formatter.positivePrefix = "+"
  21. return formatter
  22. }
  23. private var dateFormatter: DateFormatter {
  24. let formatter = DateFormatter()
  25. formatter.timeStyle = .short
  26. return formatter
  27. }
  28. var colorOfGlucose: Color {
  29. let glucoseString =
  30. recentGlucose?.glucose
  31. .map { glucoseFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! } ?? "--"
  32. let glucoseStringFirstTwoCharacters = String(glucoseString.dropLast(1))
  33. switch glucoseStringFirstTwoCharacters {
  34. case "4,",
  35. "5,",
  36. "6,",
  37. "7,":
  38. return .loopGreen
  39. case "8,",
  40. "9,":
  41. return .loopYellow
  42. default:
  43. return .loopRed
  44. }
  45. }
  46. var minutesAgo: Int {
  47. let lastGlucoseDate = recentGlucose.map { dateFormatter.string(from: $0.dateString) } ?? "--"
  48. let glucoseDate = Date(lastGlucoseDate) ?? Date()
  49. let now = Date()
  50. let diff = Int(glucoseDate.timeIntervalSince1970 - now.timeIntervalSince1970)
  51. let hoursDiff = diff / 3600
  52. var minutesDiff = (diff - hoursDiff * 3600) / 60
  53. minutesDiff.negate() // Remove "-" sign
  54. return minutesDiff
  55. }
  56. func colorOfMinutesAgo(_ minutes: Int) -> Color {
  57. print("number of minutes ago: \(minutesAgo)")
  58. switch minutes {
  59. case 0 ... 5:
  60. return .loopGray
  61. case 6 ... 9:
  62. return .loopYellow
  63. default:
  64. return .loopRed
  65. }
  66. }
  67. var body: some View {
  68. VStack(alignment: .center, spacing: 6) {
  69. HStack(spacing: 8) {
  70. Text(
  71. recentGlucose?.glucose
  72. .map {
  73. glucoseFormatter
  74. .string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! }
  75. ?? "--"
  76. )
  77. .font(.system(size: 24, weight: .bold))
  78. .fixedSize()
  79. .foregroundColor(colorOfGlucose)
  80. image.padding(.bottom, 2)
  81. }.padding(.leading, 4)
  82. HStack(alignment: .lastTextBaseline, spacing: 2) {
  83. Text(
  84. "\(minutesAgo)min "
  85. ).font(.caption2).foregroundColor(colorOfMinutesAgo(minutesAgo))
  86. Text(
  87. delta
  88. .map { deltaFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)!
  89. } ??
  90. "--"
  91. ).font(.caption2).foregroundColor(.secondary)
  92. }
  93. }
  94. }
  95. var image: Image {
  96. guard let direction = recentGlucose?.direction else {
  97. return Image(systemName: "arrow.left.and.right")
  98. }
  99. switch direction {
  100. case .doubleUp,
  101. .singleUp,
  102. .tripleUp:
  103. return Image(systemName: "arrow.up")
  104. case .fortyFiveUp:
  105. return Image(systemName: "arrow.up.right")
  106. case .flat:
  107. return Image(systemName: "arrow.forward")
  108. case .fortyFiveDown:
  109. return Image(systemName: "arrow.down.forward")
  110. case .doubleDown,
  111. .singleDown,
  112. .tripleDown:
  113. return Image(systemName: "arrow.down")
  114. case .none,
  115. .notComputable,
  116. .rateOutOfRange:
  117. return Image(systemName: "arrow.left.and.right")
  118. }
  119. }
  120. }