TrioMainWatchView.swift 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import Charts
  2. import SwiftUI
  3. struct TrioMainWatchView: View {
  4. @State private var state = WatchState()
  5. @State private var showingCarbsSheet = false
  6. @State private var showingBolusSheet = false
  7. @State private var currentPage: Double = 0
  8. @State private var rotationDegrees: Double = 0.0
  9. var body: some View {
  10. TabView(selection: $currentPage) {
  11. // Page 1: Current glucose and action buttons
  12. ScrollView {
  13. VStack(spacing: 15) {
  14. // Main Glucose Display
  15. ZStack {
  16. TrendShape(rotationDegrees: rotationDegrees)
  17. .animation(.spring(response: 0.5, dampingFraction: 0.6), value: rotationDegrees)
  18. VStack(alignment: .center, spacing: 4) {
  19. Text(state.currentGlucose)
  20. .fontWeight(.semibold)
  21. .font(.system(size: 44, design: .rounded))
  22. if let delta = state.delta {
  23. Text(delta)
  24. .font(.system(.caption, design: .rounded))
  25. .foregroundStyle(.secondary)
  26. }
  27. }
  28. }
  29. .padding(.top, 5)
  30. // IOB and COB Display
  31. HStack(spacing: 20) {
  32. VStack(spacing: 4) {
  33. HStack(spacing: 4) {
  34. Image(systemName: "drop.fill")
  35. .foregroundStyle(.blue)
  36. Text(state.iob ?? "--")
  37. }
  38. }
  39. .padding(.horizontal, 12)
  40. .padding(.vertical, 8)
  41. .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 8))
  42. VStack(spacing: 4) {
  43. HStack(spacing: 4) {
  44. Image(systemName: "fork.knife")
  45. .foregroundStyle(.orange)
  46. Text(state.cob ?? "--")
  47. }
  48. }
  49. .padding(.horizontal, 12)
  50. .padding(.vertical, 8)
  51. .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 8))
  52. }
  53. }
  54. .scenePadding()
  55. }
  56. .tag(0.0)
  57. .onChange(of: state.trend) { _, newTrend in
  58. withAnimation {
  59. updateRotation(for: newTrend)
  60. }
  61. }
  62. .toolbar {
  63. ToolbarItem(placement: .bottomBar) {
  64. Button {
  65. showingCarbsSheet = true
  66. } label: {
  67. Image(systemName: "fork.knife")
  68. .foregroundStyle(.orange)
  69. }
  70. }
  71. ToolbarItem(placement: .bottomBar) {
  72. Button {
  73. showingBolusSheet = true
  74. } label: {
  75. Image(systemName: "drop.fill")
  76. .foregroundStyle(.blue)
  77. }
  78. }
  79. }
  80. // Page 2: Glucose chart
  81. GlucoseChartView(glucoseValues: state.glucoseValues)
  82. .tag(1.0)
  83. }
  84. .tabViewStyle(.verticalPage)
  85. .navigationBarHidden(true)
  86. .digitalCrownRotation($currentPage, from: 0, through: 1, by: 1)
  87. .sheet(isPresented: $showingCarbsSheet) {
  88. CarbsInputView(state: state)
  89. }
  90. .sheet(isPresented: $showingBolusSheet) {
  91. BolusInputView(state: state)
  92. }
  93. }
  94. private func updateRotation(for trend: String?) {
  95. switch trend {
  96. case "DoubleUp",
  97. "SingleUp":
  98. rotationDegrees = -90
  99. case "FortyFiveUp":
  100. rotationDegrees = -45
  101. case "Flat":
  102. rotationDegrees = 0
  103. case "FortyFiveDown":
  104. rotationDegrees = 45
  105. case "DoubleDown",
  106. "SingleDown":
  107. rotationDegrees = 90
  108. default:
  109. rotationDegrees = 0
  110. }
  111. }
  112. }
  113. #Preview {
  114. TrioMainWatchView()
  115. }