CurrentGlucoseView.swift 4.0 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. var glucoseString =
  30. " \(recentGlucose?.glucose.map { glucoseFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! })"
  31. var glucoseStringWithoutSuffix = String(glucoseString.dropFirst(11)) // Drop first 11 characters
  32. var glucoseStringTrimmed = String(glucoseStringWithoutSuffix.dropLast(3)) // Drop last 3 characters
  33. switch glucoseStringTrimmed {
  34. case "10",
  35. "11",
  36. "12",
  37. "13",
  38. "14",
  39. "15",
  40. "16",
  41. "17",
  42. "18",
  43. "19",
  44. "20",
  45. "21",
  46. "22",
  47. "23",
  48. "24",
  49. "25":
  50. return .loopRed
  51. case "1,",
  52. "2,",
  53. "3,":
  54. return .loopRed
  55. case "4,",
  56. "5,",
  57. "6,",
  58. "7,":
  59. return .loopGreen
  60. case "8,",
  61. "9,":
  62. return .loopYellow
  63. default:
  64. return .white
  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. recentGlucose.map { dateFormatter.string(from: $0.dateString) } ?? "--"
  85. ).font(.caption2).foregroundColor(.secondary)
  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. }