|
@@ -51,54 +51,59 @@ struct CurrentGlucoseView: View {
|
|
|
let triangleColor = Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902)
|
|
let triangleColor = Color(red: 0.262745098, green: 0.7333333333, blue: 0.9137254902)
|
|
|
|
|
|
|
|
if cgmAvailable {
|
|
if cgmAvailable {
|
|
|
- VStack(spacing: 0) {
|
|
|
|
|
- ZStack {
|
|
|
|
|
- if let progress = cgmProgress {
|
|
|
|
|
- SensorLifecycleArcView(
|
|
|
|
|
- progress: progress.percentComplete,
|
|
|
|
|
- progressState: progress.progressState
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ZStack {
|
|
|
|
|
+ if let progress = cgmProgress {
|
|
|
|
|
+ SensorLifecycleArcView(
|
|
|
|
|
+ progress: progress.percentComplete,
|
|
|
|
|
+ progressState: progress.progressState
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- TrendShape(gradient: angularGradient, color: triangleColor, showArrow: true)
|
|
|
|
|
- .rotationEffect(.degrees(rotationDegrees))
|
|
|
|
|
|
|
+ TrendShape(gradient: angularGradient, color: triangleColor, showArrow: true)
|
|
|
|
|
+ .rotationEffect(.degrees(rotationDegrees))
|
|
|
|
|
|
|
|
- VStack(alignment: .center) {
|
|
|
|
|
- bobbleContent()
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- .onChange(of: glucose.last?.directionEnum) {
|
|
|
|
|
- withAnimation {
|
|
|
|
|
- switch glucose.last?.directionEnum {
|
|
|
|
|
- case .doubleUp,
|
|
|
|
|
- .singleUp,
|
|
|
|
|
- .tripleUp:
|
|
|
|
|
- rotationDegrees = -90
|
|
|
|
|
- case .fortyFiveUp:
|
|
|
|
|
- rotationDegrees = -45
|
|
|
|
|
- case .flat:
|
|
|
|
|
- rotationDegrees = 0
|
|
|
|
|
- case .fortyFiveDown:
|
|
|
|
|
- rotationDegrees = 45
|
|
|
|
|
- case .doubleDown,
|
|
|
|
|
- .singleDown,
|
|
|
|
|
- .tripleDown:
|
|
|
|
|
- rotationDegrees = 90
|
|
|
|
|
- case nil,
|
|
|
|
|
- .notComputable,
|
|
|
|
|
- .rateOutOfRange:
|
|
|
|
|
- rotationDegrees = 0
|
|
|
|
|
- default:
|
|
|
|
|
- rotationDegrees = 0
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ VStack(alignment: .center) {
|
|
|
|
|
+ bobbleContent()
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if let tag = tagLabel {
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ .overlay(alignment: .bottom) {
|
|
|
|
|
+ // Tag floats outside the bobble's frame so it doesn't push
|
|
|
|
|
+ // chart / stats / tab bar down. When the trend triangle
|
|
|
|
|
+ // rotates into the lower half (`rotationDegrees >= 45`) it
|
|
|
|
|
+ // ends up around 6 o'clock and collides with the tag —
|
|
|
|
|
+ // hide the SensorStatusTagView to avoid collision
|
|
|
|
|
+ if let tag = tagLabel, !trendIsDownward {
|
|
|
SensorStatusTagView(text: tag.text, theme: tag.theme)
|
|
SensorStatusTagView(text: tag.text, theme: tag.theme)
|
|
|
|
|
+ .offset(y: 14)
|
|
|
.zIndex(1)
|
|
.zIndex(1)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ .onChange(of: glucose.last?.directionEnum) {
|
|
|
|
|
+ withAnimation {
|
|
|
|
|
+ switch glucose.last?.directionEnum {
|
|
|
|
|
+ case .doubleUp,
|
|
|
|
|
+ .singleUp,
|
|
|
|
|
+ .tripleUp:
|
|
|
|
|
+ rotationDegrees = -90
|
|
|
|
|
+ case .fortyFiveUp:
|
|
|
|
|
+ rotationDegrees = -45
|
|
|
|
|
+ case .flat:
|
|
|
|
|
+ rotationDegrees = 0
|
|
|
|
|
+ case .fortyFiveDown:
|
|
|
|
|
+ rotationDegrees = 45
|
|
|
|
|
+ case .doubleDown,
|
|
|
|
|
+ .singleDown,
|
|
|
|
|
+ .tripleDown:
|
|
|
|
|
+ rotationDegrees = 90
|
|
|
|
|
+ case nil,
|
|
|
|
|
+ .notComputable,
|
|
|
|
|
+ .rateOutOfRange:
|
|
|
|
|
+ rotationDegrees = 0
|
|
|
|
|
+ default:
|
|
|
|
|
+ rotationDegrees = 0
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
VStack(alignment: .center, spacing: 12) {
|
|
VStack(alignment: .center, spacing: 12) {
|
|
|
HStack
|
|
HStack
|
|
@@ -166,6 +171,11 @@ struct CurrentGlucoseView: View {
|
|
|
return Date().timeIntervalSince(date) < 12 * 60
|
|
return Date().timeIntervalSince(date) < 12 * 60
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /// True when the trend arrow is rotated into the lower half of the
|
|
|
|
|
+ /// circle — used to decide whether the bottom tag needs to dodge the
|
|
|
|
|
+ /// triangle by sliding up onto the bobble's rim.
|
|
|
|
|
+ private var trendIsDownward: Bool { rotationDegrees >= 45 }
|
|
|
|
|
+
|
|
|
/// Status highlight wins; otherwise fall back to remaining-time.
|
|
/// Status highlight wins; otherwise fall back to remaining-time.
|
|
|
private var tagLabel: (text: String, theme: SensorStatusTagTheme)? {
|
|
private var tagLabel: (text: String, theme: SensorStatusTagTheme)? {
|
|
|
if let status = cgmStatus {
|
|
if let status = cgmStatus {
|