GlucoseTrendView.swift 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import SwiftUI
  2. struct GlucoseTrendView: View {
  3. let state: WatchState
  4. let rotationDegrees: Double
  5. private var is40mm: Bool {
  6. let size = WKInterfaceDevice.current().screenBounds.size
  7. return size.height < 225 && size.width < 185
  8. }
  9. /// Determines the status color based on the time elapsed since the last loop
  10. /// - Parameter timeString: The time string representing minutes since last loop (format: "X min")
  11. /// - Returns: A color indicating the status:
  12. /// - Green: <= 5 minutes
  13. /// - Yellow: 5-10 minutes
  14. /// - Red: > 10 minutes or invalid time
  15. private func statusColor(for timeString: String?) -> Color {
  16. guard let timeString = timeString,
  17. timeString != "--",
  18. let minutes = timeString.split(separator: " ").first.flatMap({ Int($0) })
  19. else {
  20. return .secondary
  21. }
  22. switch minutes {
  23. case ...5:
  24. return .loopGreen
  25. case 5 ... 10:
  26. return .loopYellow
  27. case 11...:
  28. return .loopRed
  29. default:
  30. return .loopYellow
  31. }
  32. }
  33. var body: some View {
  34. VStack {
  35. ZStack {
  36. Circle()
  37. .stroke(statusColor(for: state.lastLoopTime), lineWidth: is40mm ? 1 : 1.5)
  38. .frame(width: is40mm ? 86 : 105, height: is40mm ? 86 : 105)
  39. .background(Circle().fill(Color.bgDarkBlue))
  40. .shadow(color: statusColor(for: state.lastLoopTime), radius: is40mm ? 8 : 12)
  41. TrendShape(rotationDegrees: rotationDegrees, isSmallDevice: is40mm)
  42. .animation(.spring(response: 0.5, dampingFraction: 0.6), value: rotationDegrees)
  43. .shadow(color: Color.black.opacity(0.5), radius: 5)
  44. VStack(alignment: .center) {
  45. Text(state.currentGlucose)
  46. .fontWeight(.semibold)
  47. .font(.system(is40mm ? .title2 : .title, design: .rounded))
  48. .foregroundStyle(state.currentGlucoseColorString.toColor())
  49. if let delta = state.delta {
  50. Text(delta)
  51. .fontWeight(.semibold)
  52. .font(.system(.caption, design: .rounded))
  53. .foregroundStyle(.secondary)
  54. }
  55. }
  56. }
  57. Text(state.lastLoopTime ?? "--").font(.system(size: is40mm ? 9 : 10))
  58. Spacer()
  59. }.frame(maxWidth: .infinity, maxHeight: .infinity)
  60. }
  61. }