Преглед изворни кода

Various updates

- Run calculation of total insulin on scope only on change of picker panel, on appearance of the app and on change of boluses
	* to do: fix tins not updating on Pump History change

- Dynamic Island updates
	* add cob to lockscreen widget
	* add iob to lockscreen widget and adjust padding/spacing
	* to do: fix delay of updating cob and iob

- Change gradient of custom background color
polscm32 пре 2 година
родитељ
комит
98fcad4f41

+ 17 - 0
FreeAPS/Sources/Modules/OverrideProfilesConfig/View/OverrideProfilesRootView.swift

@@ -40,6 +40,23 @@ extension OverrideProfilesConfig {
             formatter.roundingMode = .halfUp
             return formatter
         }
+        
+        private var color: LinearGradient {
+            colorScheme == .dark ?  LinearGradient(
+                gradient: Gradient(colors: [
+                    // RGB(10, 34, 55)
+                    Color(red: 0.03921568627, green: 0.1333333333, blue: 0.2156862745),
+                    // RGB(3, 15, 28)
+                    Color(red: 0.011, green: 0.058, blue: 0.109),
+                    // RGB(10, 34, 55)
+                    Color(red: 0.03921568627, green: 0.1333333333, blue: 0.2156862745)
+                ]),
+                startPoint: .top,
+                endPoint: .bottom
+            )
+                :
+                LinearGradient(gradient: Gradient(colors: [Color.gray.opacity(0.1)]), startPoint: .top, endPoint: .bottom)
+        }
 
         var presetPopover: some View {
             Form {

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

@@ -12,6 +12,8 @@ struct LiveActivityAttributes: ActivityAttributes {
         let rotationDegrees: Double
         let highGlucose: Double
         let lowGlucose: Double
+        let cob: Decimal
+        let iob: Decimal
     }
 
     let startDate: Date

+ 36 - 13
FreeAPS/Sources/Services/LiveActivity/LiveActivityBridge.swift

@@ -21,7 +21,14 @@ extension LiveActivityAttributes.ContentState {
             .string(from: mmol ? value.asMmolL as NSNumber : NSNumber(value: value))!
     }
 
-    init?(new bg: BloodGlucose, prev: BloodGlucose?, mmol: Bool, chart: [Readings], settings: FreeAPSSettings) {
+    init?(
+        new bg: BloodGlucose,
+        prev: BloodGlucose?,
+        mmol: Bool,
+        chart: [Readings],
+        settings: FreeAPSSettings,
+        suggestion: Suggestion
+    ) {
         guard let glucose = bg.glucose,
               bg.dateString.timeIntervalSinceNow > -TimeInterval(minutes: 6)
         else {
@@ -80,6 +87,9 @@ extension LiveActivityAttributes.ContentState {
         let highGlucose = settings.highGlucose
         let lowGlucose = settings.lowGlucose
 
+        let cob = suggestion.cob ?? 0
+        let iob = suggestion.iob ?? 0
+
         self.init(
             bg: formattedBG,
             trendSystemImage: trendString,
@@ -89,7 +99,9 @@ extension LiveActivityAttributes.ContentState {
             chartDate: chartDate,
             rotationDegrees: rotationDegrees,
             highGlucose: Double(highGlucose),
-            lowGlucose: Double(lowGlucose)
+            lowGlucose: Double(lowGlucose),
+            cob: cob,
+            iob: iob
         )
     }
 }
@@ -118,11 +130,16 @@ extension LiveActivityAttributes.ContentState {
     @Injected() private var settingsManager: SettingsManager!
     @Injected() private var glucoseStorage: GlucoseStorage!
     @Injected() private var broadcaster: Broadcaster!
+    @Injected() private var storage: FileStorage!
 
     private var settings: FreeAPSSettings {
         settingsManager.settings
     }
 
+    var suggestion: Suggestion? {
+        storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
+    }
+
     private var currentActivity: ActiveActivity?
     private var latestGlucose: BloodGlucose?
 
@@ -221,25 +238,31 @@ extension LiveActivityBridge: GlucoseObserver {
         defer {
             self.latestGlucose = glucose.last
         }
+        
         // fetch glucose for chart from Core Data
         let coreDataStorage = CoreDataStorage()
         let sixHoursAgo = Calendar.current.date(byAdding: .hour, value: -6, to: Date()) ?? Date()
         let fetchGlucose = coreDataStorage.fetchGlucose(interval: sixHoursAgo as NSDate)
 
-        guard let bg = glucose.last, let content = LiveActivityAttributes.ContentState(
-            new: bg,
-            prev: latestGlucose,
-            mmol: settings.units == .mmolL,
-
-            chart: fetchGlucose, settings: settings
-
-        ) 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
+        guard let bg = glucose.last else {
             return
         }
 
-        Task {
-            await self.pushUpdate(content)
+        if let suggestion = suggestion {
+            let content = LiveActivityAttributes.ContentState(
+                new: bg,
+                prev: latestGlucose,
+                mmol: settings.units == .mmolL,
+                chart: fetchGlucose,
+                settings: settings,
+                suggestion: suggestion
+            )
+
+            if let content = content {
+                Task {
+                    await self.pushUpdate(content)
+                }
+            }
         }
     }
 }

+ 42 - 7
LiveActivity/LiveActivity.swift

@@ -11,6 +11,21 @@ struct LiveActivity: Widget {
         return f
     }()
 
+    private var bolusFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 2
+        formatter.decimalSeparator = "."
+        return formatter
+    }
+
+    private var carbsFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        return formatter
+    }
+
     func changeLabel(context: ActivityViewContext<LiveActivityAttributes>) -> Text {
         if !context.isStale && !context.state.change.isEmpty {
             Text(context.state.change)
@@ -20,7 +35,7 @@ struct LiveActivity: Widget {
     }
 
     func updatedLabel(context: ActivityViewContext<LiveActivityAttributes>) -> Text {
-        Text("Updated: \(dateFormatter.string(from: context.state.date))")
+        Text("Updated: \(dateFormatter.string(from: context.state.date))").italic()
     }
 
     func bgLabel(context: ActivityViewContext<LiveActivityAttributes>) -> Text {
@@ -31,6 +46,25 @@ struct LiveActivity: Widget {
         }
     }
 
+    @ViewBuilder func mealLabel(context: ActivityViewContext<LiveActivityAttributes>) -> some View {
+        VStack(alignment: .leading, spacing: 1, content: {
+            HStack {
+                Text("COB: ").font(.caption)
+                Text(
+                    (carbsFormatter.string(from: context.state.cob as NSNumber) ?? "--") +
+                        NSLocalizedString(" g", comment: "grams of carbs")
+                ).font(.caption).fontWeight(.bold)
+            }
+            HStack {
+                Text("IOB: ").font(.caption)
+                Text(
+                    (bolusFormatter.string(from: context.state.iob as NSNumber) ?? "--") +
+                        NSLocalizedString(" U", comment: "Unit in number of units delivered (keep the space character!)")
+                ).font(.caption).fontWeight(.bold)
+            }
+        })
+    }
+
     @ViewBuilder func trend(context: ActivityViewContext<LiveActivityAttributes>) -> some View {
         if context.isStale {
             Text("--")
@@ -118,25 +152,26 @@ struct LiveActivity: Widget {
             HStack(spacing: 2) {
                 VStack {
                     chart(context: context).frame(width: UIScreen.main.bounds.width / 1.8)
-                }.padding(.vertical, 5).padding(.horizontal, 15)
+                }.padding(.all, 15)
                 Divider().foregroundStyle(Color.white)
-                VStack {
+                VStack(alignment: .center) {
+                    Spacer()
                     ZStack {
                         bobble(context: context)
                             .scaleEffect(0.6)
                             .clipped()
                         VStack {
-//                            bgAndTrend(context: context).imageScale(.small).font(.title2)
                             bgLabel(context: context).font(.title2).imageScale(.small)
                             changeLabel(context: context).font(.callout)
                         }
-                    }.padding(.trailing, 10).padding(.top, 5)
-                    updatedLabel(context: context).font(.caption).padding(.bottom).padding(.trailing, 5)
+                    }.scaleEffect(0.85).offset(y: 15)
+                    mealLabel(context: context).padding(.bottom, 8)
+                    updatedLabel(context: context).font(.caption).padding(.bottom, 50)
                 }
             }
             .privacySensitive()
             .imageScale(.small)
-            .padding(.all, 15)
+//            .padding(.all, 15)
             .background(Color.white.opacity(0.2))
             .foregroundColor(Color.white)
             .activityBackgroundTint(Color.black.opacity(0.7))