Kaynağa Gözat

add glucose graph in dynamic island....WiP

polscm32 2 yıl önce
ebeveyn
işleme
8b762cf37d

+ 1 - 0
FreeAPS/Sources/Services/LiveActivity/LiveActitiyShared.swift

@@ -7,6 +7,7 @@ struct LiveActivityAttributes: ActivityAttributes {
         let trendSystemImage: String?
         let trendSystemImage: String?
         let change: String
         let change: String
         let date: Date
         let date: Date
+        let chart: [Int?]
     }
     }
 
 
     let startDate: Date
     let startDate: Date

+ 7 - 3
FreeAPS/Sources/Services/LiveActivity/LiveActivityBridge.swift

@@ -21,7 +21,7 @@ extension LiveActivityAttributes.ContentState {
             .string(from: mmol ? value.asMmolL as NSNumber : NSNumber(value: value))!
             .string(from: mmol ? value.asMmolL as NSNumber : NSNumber(value: value))!
     }
     }
 
 
-    init?(new bg: BloodGlucose, prev: BloodGlucose?, mmol: Bool) {
+    init?(new bg: BloodGlucose, prev: BloodGlucose?, mmol: Bool, chart: [BloodGlucose]) {
         guard let glucose = bg.glucose,
         guard let glucose = bg.glucose,
               bg.dateString.timeIntervalSinceNow > -TimeInterval(minutes: 6)
               bg.dateString.timeIntervalSinceNow > -TimeInterval(minutes: 6)
         else {
         else {
@@ -62,7 +62,9 @@ extension LiveActivityAttributes.ContentState {
             Self.formatGlucose(glucose - $0, mmol: mmol, forceSign: true)
             Self.formatGlucose(glucose - $0, mmol: mmol, forceSign: true)
         }) ?? ""
         }) ?? ""
 
 
-        self.init(bg: formattedBG, trendSystemImage: trendString, change: change, date: bg.dateString)
+        let chartBG = chart.map(\.glucose)
+
+        self.init(bg: formattedBG, trendSystemImage: trendString, change: change, date: bg.dateString, chart: chartBG)
     }
     }
 }
 }
 
 
@@ -194,10 +196,12 @@ extension LiveActivityBridge: GlucoseObserver {
             self.latestGlucose = glucose.last
             self.latestGlucose = glucose.last
         }
         }
 
 
+        let last200Glucose = Array(glucose.suffix(200))
+
         guard let bg = glucose.last, let content = LiveActivityAttributes.ContentState(
         guard let bg = glucose.last, let content = LiveActivityAttributes.ContentState(
             new: bg,
             new: bg,
             prev: latestGlucose,
             prev: latestGlucose,
-            mmol: settings.units == .mmolL
+            mmol: settings.units == .mmolL, chart: last200Glucose
         ) else {
         ) else {
             // no bg or value stale. Don't update the activity if there already is one, just let it turn stale so that it can still be used once current bg is available again
             // no bg or value stale. Don't update the activity if there already is one, just let it turn stale so that it can still be used once current bg is available again
             return
             return

+ 49 - 17
LiveActivity/LiveActivity.swift

@@ -1,4 +1,5 @@
 import ActivityKit
 import ActivityKit
+import Charts
 import SwiftUI
 import SwiftUI
 import WidgetKit
 import WidgetKit
 
 
@@ -41,6 +42,35 @@ struct LiveActivity: Widget {
         }
         }
     }
     }
 
 
+//
+//    @ViewBuilder func chart(context: ActivityViewContext<LiveActivityAttributes>) -> some View {
+//        if context.isStale {
+//            Text("--")
+//        } else {
+//            Chart {
+//                PointMark(
+//                    x: .value("Time", context.state.chart.count),
+//                    y: .value("Value", context.state.chart.count)
+//                )
+//            }
+//        }
+//    }
+
+    @ViewBuilder func chart(context: ActivityViewContext<LiveActivityAttributes>) -> some View {
+        if context.isStale {
+            Text("--")
+        } else {
+            Chart {
+                ForEach(context.state.chart.indices, id: \.self) { index in
+                    PointMark(
+                        x: .value("Time", index),
+                        y: .value("Value", context.state.chart[index] ?? 0)
+                    )
+                }
+            }
+        }
+    }
+
     var body: some WidgetConfiguration {
     var body: some WidgetConfiguration {
         ActivityConfiguration(for: LiveActivityAttributes.self) { context in
         ActivityConfiguration(for: LiveActivityAttributes.self) { context in
             // Lock screen/banner UI goes here
             // Lock screen/banner UI goes here
@@ -51,6 +81,7 @@ struct LiveActivity: Widget {
                 VStack(alignment: .trailing, spacing: 5) {
                 VStack(alignment: .trailing, spacing: 5) {
                     changeLabel(context: context).font(.title3)
                     changeLabel(context: context).font(.title3)
                     updatedLabel(context: context).font(.caption).foregroundStyle(.black.opacity(0.7))
                     updatedLabel(context: context).font(.caption).foregroundStyle(.black.opacity(0.7))
+                    chart(context: context)
                 }
                 }
             }
             }
             .privacySensitive()
             .privacySensitive()
@@ -76,6 +107,7 @@ struct LiveActivity: Widget {
                 DynamicIslandExpandedRegion(.bottom) {
                 DynamicIslandExpandedRegion(.bottom) {
                     updatedLabel(context: context).font(.caption).foregroundStyle(Color.secondary)
                     updatedLabel(context: context).font(.caption).foregroundStyle(Color.secondary)
                         .padding(.bottom, 5)
                         .padding(.bottom, 5)
+                    chart(context: context)
                 }
                 }
             } compactLeading: {
             } compactLeading: {
                 HStack(spacing: 1) {
                 HStack(spacing: 1) {
@@ -92,20 +124,20 @@ struct LiveActivity: Widget {
     }
     }
 }
 }
 
 
-private extension LiveActivityAttributes {
-    static var preview: LiveActivityAttributes {
-        LiveActivityAttributes(startDate: Date())
-    }
-}
-
-private extension LiveActivityAttributes.ContentState {
-    static var test: LiveActivityAttributes.ContentState {
-        LiveActivityAttributes.ContentState(bg: "100", trendSystemImage: "arrow.right", change: "+2", date: Date())
-    }
-}
-
-#Preview("Notification", as: .content, using: LiveActivityAttributes.preview) {
-    LiveActivity()
-} contentStates: {
-    LiveActivityAttributes.ContentState.test
-}
+// private extension LiveActivityAttributes {
+//    static var preview: LiveActivityAttributes {
+//        LiveActivityAttributes(startDate: Date())
+//    }
+// }
+//
+// private extension LiveActivityAttributes.ContentState {
+//    static var test: LiveActivityAttributes.ContentState {
+//        LiveActivityAttributes.ContentState(bg: "100", trendSystemImage: "arrow.right", change: "+2", date: Date())
+//    }
+// }
+//
+// #Preview("Notification", as: .content, using: LiveActivityAttributes.preview) {
+//    LiveActivity()
+// } contentStates: {
+//    LiveActivityAttributes.ContentState.test
+// }