CurrentGlucoseView.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import SwiftUI
  2. struct CurrentGlucoseView: View {
  3. @Binding var recentGlucose: BloodGlucose?
  4. @Binding var delta: Int?
  5. let 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.map { glucoseFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! })"
  31. let glucoseStringWithoutSuffix = String(glucoseString.dropFirst(11)) // Drop first 11 characters
  32. let glucoseStringTrimmed = String(glucoseStringWithoutSuffix.dropLast(3)) // Drop last 3 characters
  33. switch glucoseStringTrimmed {
  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 body: some View {
  47. VStack(alignment: .center, spacing: 6) {
  48. HStack(spacing: 8) {
  49. Text(
  50. recentGlucose?.glucose
  51. .map {
  52. glucoseFormatter
  53. .string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)! }
  54. ?? "--"
  55. )
  56. .font(.system(size: 24, weight: .bold))
  57. .fixedSize()
  58. .foregroundColor(colorOfGlucose)
  59. image.padding(.bottom, 2)
  60. }.padding(.leading, 4)
  61. HStack(spacing: 2) {
  62. Text(
  63. recentGlucose.map { dateFormatter.string(from: $0.dateString) } ?? "--"
  64. ).font(.caption2).foregroundColor(.secondary)
  65. Text(
  66. delta
  67. .map { deltaFormatter.string(from: Double(units == .mmolL ? $0.asMmolL : Decimal($0)) as NSNumber)!
  68. } ??
  69. "--"
  70. ).font(.system(size: 12, weight: .bold))
  71. }
  72. }
  73. }
  74. var image: Image {
  75. guard let direction = recentGlucose?.direction else {
  76. return Image(systemName: "arrow.left.and.right")
  77. }
  78. switch direction {
  79. case .doubleUp,
  80. .singleUp,
  81. .tripleUp:
  82. return Image(systemName: "arrow.up")
  83. case .fortyFiveUp:
  84. return Image(systemName: "arrow.up.right")
  85. case .flat:
  86. return Image(systemName: "arrow.forward")
  87. case .fortyFiveDown:
  88. return Image(systemName: "arrow.down.forward")
  89. case .doubleDown,
  90. .singleDown,
  91. .tripleDown:
  92. return Image(systemName: "arrow.down")
  93. case .none,
  94. .notComputable,
  95. .rateOutOfRange:
  96. return Image(systemName: "arrow.left.and.right")
  97. }
  98. }
  99. }