MainView.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import SwiftDate
  2. import SwiftUI
  3. struct MainView: View {
  4. private enum Config {
  5. static let lag: TimeInterval = 30
  6. }
  7. @EnvironmentObject var state: WatchStateModel
  8. @State var isCarbsActive = false
  9. @State var isTargetsActive = false
  10. @State var isBolusActive = false
  11. var body: some View {
  12. VStack {
  13. header
  14. Spacer()
  15. buttons
  16. }
  17. .frame(maxHeight: .infinity)
  18. .padding()
  19. }
  20. var header: some View {
  21. VStack {
  22. HStack(alignment: .top) {
  23. VStack(alignment: .leading) {
  24. HStack {
  25. Text(state.glucose).font(.largeTitle)
  26. Text(state.trend)
  27. }
  28. Text(state.delta).font(.caption2)
  29. }
  30. Spacer()
  31. VStack(spacing: 0) {
  32. HStack {
  33. Circle().stroke(color, lineWidth: 6).frame(width: 30, height: 30).padding(10)
  34. }
  35. if state.lastLoopDate != nil {
  36. Text(timeString).font(.caption2)
  37. } else {
  38. Text("--").font(.caption2)
  39. }
  40. }
  41. }
  42. Spacer()
  43. HStack {
  44. Text("IOB: " + iobFormatter.string(from: (state.iob ?? 0) as NSNumber)! + " U").font(.caption2)
  45. Spacer()
  46. Text("COB: " + iobFormatter.string(from: (state.cob ?? 0) as NSNumber)! + " g").font(.caption2)
  47. }
  48. Spacer()
  49. }.padding()
  50. }
  51. var buttons: some View {
  52. HStack {
  53. NavigationLink {
  54. CarbsView()
  55. .environmentObject(state)
  56. } label: {
  57. HStack {
  58. Image("carbs", bundle: nil)
  59. .renderingMode(.template)
  60. .resizable()
  61. .frame(width: 24, height: 24)
  62. .foregroundColor(.loopGreen)
  63. }
  64. }
  65. NavigationLink {
  66. EmptyView()
  67. } label: {
  68. HStack {
  69. Image("target", bundle: nil)
  70. .renderingMode(.template)
  71. .resizable()
  72. .frame(width: 24, height: 24)
  73. .foregroundColor(.loopYellow)
  74. }
  75. }
  76. NavigationLink {
  77. EmptyView()
  78. } label: {
  79. HStack {
  80. Image("bolus", bundle: nil)
  81. .renderingMode(.template)
  82. .resizable()
  83. .frame(width: 24, height: 24)
  84. .foregroundColor(.insulin)
  85. }
  86. }
  87. }
  88. }
  89. private var iobFormatter: NumberFormatter {
  90. let formatter = NumberFormatter()
  91. formatter.maximumFractionDigits = 2
  92. formatter.numberStyle = .decimal
  93. return formatter
  94. }
  95. private var timeString: String {
  96. let minAgo = Int((Date().timeIntervalSince(state.lastLoopDate ?? .distantPast) - Config.lag) / 60) + 1
  97. if minAgo > 1440 {
  98. return "--"
  99. }
  100. return "\(minAgo) " + NSLocalizedString("min ago", comment: "Minutes ago since last loop")
  101. }
  102. private var color: Color {
  103. guard let lastLoopDate = state.lastLoopDate else {
  104. return .loopGray
  105. }
  106. let delta = Date().timeIntervalSince(lastLoopDate) - Config.lag
  107. if delta <= 5.minutes.timeInterval {
  108. return .loopGreen
  109. } else if delta <= 10.minutes.timeInterval {
  110. return .loopYellow
  111. } else {
  112. return .loopRed
  113. }
  114. }
  115. }
  116. struct ContentView_Previews: PreviewProvider {
  117. static var previews: some View {
  118. Group {
  119. MainView().environmentObject(WatchStateModel())
  120. MainView().previewDevice("Apple Watch Series 5 - 40mm").environmentObject(WatchStateModel())
  121. }
  122. }
  123. }