polscm32 пре 1 година
родитељ
комит
860068c8f5

+ 2 - 2
FreeAPS/Sources/APS/APSManager.swift

@@ -670,7 +670,7 @@ final class BaseAPSManager: APSManager, Injectable {
 
     private func enactDetermination() async throws {
         guard let determinationID = await determinationStorage
-            .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination).first
+            .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination, fetchLimit: 1).first
         else {
             throw APSError.apsError(message: "Determination not found")
         }
@@ -725,7 +725,7 @@ final class BaseAPSManager: APSManager, Injectable {
 
     private func reportEnacted(wasEnacted: Bool) async {
         guard let determinationID = await determinationStorage
-            .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination).first
+            .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination, fetchLimit: 1).first
         else {
             return
         }

+ 4 - 3
FreeAPS/Sources/APS/Storage/DeterminationStorage.swift

@@ -3,7 +3,7 @@ import Foundation
 import Swinject
 
 protocol DeterminationStorage {
-    func fetchLastDeterminationObjectID(predicate: NSPredicate) async -> [NSManagedObjectID]
+    func fetchLastDeterminationObjectID(predicate: NSPredicate, fetchLimit: Int) async -> [NSManagedObjectID]
     func getForecasts(for determinationID: NSManagedObjectID, in context: NSManagedObjectContext) -> [Forecast]
     func getForecastValues(for forecastID: NSManagedObjectID, in context: NSManagedObjectContext) -> [ForecastValue]
 }
@@ -16,14 +16,15 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
         injectServices(resolver)
     }
 
-    func fetchLastDeterminationObjectID(predicate: NSPredicate) async -> [NSManagedObjectID] {
+    func fetchLastDeterminationObjectID(predicate: NSPredicate, fetchLimit: Int) async -> [NSManagedObjectID] {
         let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: OrefDetermination.self,
             onContext: backgroundContext,
             predicate: predicate,
             key: "deliverAt",
             ascending: false,
-            fetchLimit: 1
+            fetchLimit: fetchLimit,
+            batchSize: 50
         )
         return await backgroundContext.perform {
             results.map(\.objectID)

+ 4 - 1
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -620,7 +620,10 @@ extension Bolus.StateModel {
     // Determinations
     private func setupDeterminationsArray() {
         Task {
-            let ids = await determinationStorage.fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
+            let ids = await determinationStorage.fetchLastDeterminationObjectID(
+                predicate: NSPredicate.enactedDetermination,
+                fetchLimit: 1
+            )
             await updateDeterminationsArray(with: ids)
         }
     }

+ 2 - 2
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -691,10 +691,10 @@ extension Home.StateModel {
     private func setupDeterminationsArray() {
         Task {
             async let enactedObjectIDs = determinationStorage
-                .fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
+                .fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination, fetchLimit: 1)
             async let enactedAndNonEnactedObjectIDs = determinationStorage.fetchLastDeterminationObjectID(
                 predicate: NSPredicate
-                    .predicateFor30MinAgoForDetermination
+                    .determinationsForCobIobCharts, fetchLimit: 288
             )
 
             let enactedIDs = await enactedObjectIDs

+ 65 - 11
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -115,9 +115,10 @@ struct MainChartView: View {
     var body: some View {
         VStack {
             ZStack {
-                VStack {
+                VStack(spacing: 0) {
                     staticYAxisChart
                     dummyBasalChart
+                    dummyCobChart.offset(y: 20)
                 }
 
                 ScrollViewReader { scroller in
@@ -125,6 +126,7 @@ struct MainChartView: View {
                         VStack(spacing: 0) {
                             mainChart
                             basalChart
+                            cobChart.offset(y: 20)
                         }.onChange(of: screenHours) { _ in
                             updateStartEndMarkers()
                             yAxisChartData()
@@ -153,7 +155,7 @@ struct MainChartView: View {
                     }
                 }
             }
-            legendPanel.padding(.top, 8)
+//            legendPanel.padding(.top, 8)
         }
     }
 }
@@ -200,14 +202,34 @@ extension MainChartView {
     }
 
     private var dummyBasalChart: some View {
-        Chart {}
-            .id("DummyBasalChart")
-            .frame(height: UIScreen.main.bounds.height * 0.08)
-            .frame(width: screenSize.width - 10)
-            .chartYAxis(.hidden)
-            .chartXAxis(.hidden)
-            .chartYScale(domain: minValue ... maxValue)
-            .chartLegend(.hidden)
+        Chart {
+            drawTempBasals().foregroundStyle(.clear)
+        }
+        .id("DummyBasalChart")
+        .frame(height: UIScreen.main.bounds.height * 0.05)
+        .frame(width: screenSize.width - 10)
+        .chartYAxis(.hidden)
+        .chartXAxis(.hidden)
+        .chartYScale(domain: minValue ... maxValue)
+        .chartLegend(.hidden)
+    }
+
+    private var dummyCobChart: some View {
+        Chart {
+            ForEach(state.enactedAndNonEnactedDeterminations) { cob in
+                let amount = Int(cob.cob)
+                let date: Date = cob.deliverAt ?? Date()
+
+                LineMark(x: .value("Time", date), y: .value("Value", amount)).foregroundStyle(.clear)
+                AreaMark(x: .value("Time", date), y: .value("Value", amount)).foregroundStyle(.clear)
+            }
+        }
+        .id("DummyCobChart")
+        .frame(height: UIScreen.main.bounds.height * 0.1)
+        .frame(width: screenSize.width - 10)
+        .chartXAxis(.hidden)
+        .chartYAxis { cobChartYAxis }
+        .chartLegend(.hidden)
     }
 
     private var mainChart: some View {
@@ -311,14 +333,34 @@ extension MainChartView {
             }.onChange(of: basalProfile) { _ in
                 calculateBasals()
             }
-            .frame(height: UIScreen.main.bounds.height * 0.08)
+            .frame(height: UIScreen.main.bounds.height * 0.05)
             .frame(width: fullWidth(viewWidth: screenSize.width))
             .chartXScale(domain: startMarker ... endMarker)
             .chartXAxis { basalChartXAxis }
+            .chartXAxis(.hidden)
             .chartYAxis(.hidden)
         }
     }
 
+    private var cobChart: some View {
+        Chart {
+            drawCurrentTimeMarker()
+            ForEach(state.enactedAndNonEnactedDeterminations) { cob in
+                let amount = Int(cob.cob)
+                let date: Date = cob.deliverAt ?? Date()
+
+                LineMark(x: .value("Time", date), y: .value("Value", amount)).foregroundStyle(Color.orange.gradient)
+                AreaMark(x: .value("Time", date), y: .value("Value", amount)).foregroundStyle(Color.orange.gradient.opacity(0.3))
+            }
+        }
+        .frame(height: UIScreen.main.bounds.height * 0.1)
+        .frame(width: fullWidth(viewWidth: screenSize.width))
+        .chartXScale(domain: startMarker ... endMarker)
+        .chartXAxis { basalChartXAxis }
+//        .chartYAxis { cobChartYAxis }
+        .chartYAxis(.hidden)
+    }
+
     var legendPanel: some View {
         HStack(spacing: 10) {
             Spacer()
@@ -903,6 +945,18 @@ extension MainChartView {
             }
         }
     }
+
+    private var cobChartYAxis: some AxisContent {
+        AxisMarks(position: .trailing) { _ in
+            if displayXgridLines {
+                AxisGridLine(stroke: .init(lineWidth: 0.5, dash: [2, 3]))
+            } else {
+                AxisGridLine(stroke: .init(lineWidth: 0, dash: [2, 3]))
+            }
+
+            AxisValueLabel().font(.system(.footnote))
+        }
+    }
 }
 
 struct LegendItem: View {

+ 4 - 1
FreeAPS/Sources/Modules/ISFEditor/ISFEditorStateModel.swift

@@ -100,7 +100,10 @@ extension ISFEditor {
 
         private func setupDeterminationsArray() {
             Task {
-                let ids = await determinationStorage.fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
+                let ids = await determinationStorage.fetchLastDeterminationObjectID(
+                    predicate: NSPredicate.enactedDetermination,
+                    fetchLimit: 1
+                )
                 await updateDeterminationsArray(with: ids)
             }
         }

+ 5 - 0
Model/Helper/Determination+helper.swift

@@ -26,4 +26,9 @@ extension NSPredicate {
         let date = Date.halfHourAgo
         return NSPredicate(format: "enacted == %@ AND deliverAt >= %@", true as NSNumber, date as NSDate)
     }
+
+    static var determinationsForCobIobCharts: NSPredicate {
+        let date = Date.oneDayAgo
+        return NSPredicate(format: "deliverAt >= %@", date as NSDate)
+    }
 }