Selaa lähdekoodia

Use unique label for Fat / Protein
Use unique colour in chart and in data table

Jon Mårtensson 3 vuotta sitten
vanhempi
commit
e08caa3eb0

+ 8 - 0
FreeAPS/Sources/Modules/DataTable/DataTableDataFlow.swift

@@ -24,6 +24,7 @@ enum DataTable {
 
     enum DataType: String, Equatable {
         case carbs
+        case fpus
         case bolus
         case tempBasal
         case tempTarget
@@ -35,6 +36,8 @@ enum DataTable {
             switch self {
             case .carbs:
                 name = "Carbs"
+            case .fpus:
+                name = "Protein/Fat"
             case .bolus:
                 name = "Bolus"
             case .tempBasal:
@@ -108,6 +111,9 @@ enum DataTable {
             switch type {
             case .carbs:
                 return numberFormater.string(from: amount as NSNumber)! + NSLocalizedString(" g", comment: "gram of carbs")
+            case .fpus:
+                return numberFormater
+                    .string(from: amount as NSNumber)! + NSLocalizedString(" g", comment: "gram of carb equilvalents")
             case .bolus:
                 return numberFormater.string(from: amount as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
             case .tempBasal:
@@ -138,6 +144,8 @@ enum DataTable {
             switch type {
             case .carbs:
                 return .loopYellow
+            case .fpus:
+                return .red
             case .bolus:
                 return .insulin
             case .tempBasal:

+ 4 - 0
FreeAPS/Sources/Modules/DataTable/DataTableProvider.swift

@@ -21,6 +21,10 @@ extension DataTable {
             carbsStorage.recent()
         }
 
+        func fpus() -> [CarbsEntry] {
+            carbsStorage.recent()
+        }
+
         func deleteCarbs(_ treatement: Treatment) {
             nightscoutManager.deleteCarbs(at: treatement.date)
             healthkitManager.deleteCarbs(syncID: treatement.id)

+ 23 - 9
FreeAPS/Sources/Modules/DataTable/DataTableStateModel.swift

@@ -25,19 +25,33 @@ extension DataTable {
             DispatchQueue.global().async {
                 let units = self.settingsManager.settings.units
 
-                let carbs = self.provider.carbs().map {
-                    if let id = $0.id {
-                        return Treatment(
+                let carbs = self.provider.carbs()
+                    .filter { !($0.isFPU ?? false) }
+                    .map {
+                        if let id = $0.id {
+                            return Treatment(
+                                units: units,
+                                type: .carbs,
+                                date: $0.createdAt,
+                                amount: $0.carbs,
+                                id: id
+                            )
+                        } else {
+                            return Treatment(units: units, type: .carbs, date: $0.createdAt, amount: $0.carbs)
+                        }
+                    }
+
+                let fpus = self.provider.fpus()
+                    .filter { $0.isFPU ?? false }
+                    .map {
+                        Treatment(
                             units: units,
-                            type: .carbs,
+                            type: .fpus,
                             date: $0.createdAt,
                             amount: $0.carbs,
-                            id: id
+                            id: $0.id
                         )
-                    } else {
-                        return Treatment(units: units, type: .carbs, date: $0.createdAt, amount: $0.carbs)
                     }
-                }
 
                 let boluses = self.provider.pumpHistory()
                     .filter { $0.type == .bolus }
@@ -87,7 +101,7 @@ extension DataTable {
                     }
 
                 DispatchQueue.main.async {
-                    self.treatments = [carbs, boluses, tempBasals, tempTargets, suspend, resume]
+                    self.treatments = [carbs, boluses, tempBasals, tempTargets, suspend, resume, fpus]
                         .flatMap { $0 }
                         .sorted { $0.date > $1.date }
                 }

+ 22 - 0
FreeAPS/Sources/Modules/DataTable/View/DataTableRootView.swift

@@ -105,6 +105,28 @@ extension DataTable {
                         }
                 }
 
+                if item.type == .fpus {
+                    Spacer()
+                    Image(systemName: "xmark.circle").foregroundColor(.secondary)
+                        .contentShape(Rectangle())
+                        .padding(.vertical)
+                        .onTapGesture {
+                            removeCarbsAlert = Alert(
+                                title: Text("Delete carb equivalents?"),
+                                message: Text(item.amountText),
+                                primaryButton: .destructive(
+                                    Text("Delete"),
+                                    action: { state.deleteCarbs(item) }
+                                ),
+                                secondaryButton: .cancel()
+                            )
+                            isRemoveCarbsAlertPresented = true
+                        }
+                        .alert(isPresented: $isRemoveCarbsAlertPresented) {
+                            removeCarbsAlert!
+                        }
+                }
+
                 if item.type == .bolus {
                     Spacer()
                     Image(systemName: "xmark.circle").foregroundColor(.secondary)

+ 62 - 1
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -62,6 +62,10 @@ struct MainChartView: View {
     @State private var suspensionsPath = Path()
     @State private var carbsDots: [DotInfo] = []
     @State private var carbsPath = Path()
+
+    @State private var fpuDots: [DotInfo] = []
+    @State private var fpuPath = Path()
+
     @State private var glucoseYGange: GlucoseYRange = (0, 0, 0, 0)
     @State private var offset: CGFloat = 0
     @State private var cachedMaxBasalRate: Decimal?
@@ -93,7 +97,16 @@ struct MainChartView: View {
     private var carbsFormatter: NumberFormatter {
         let formatter = NumberFormatter()
         formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        return formatter
+    }
+
+    private var fpuFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
         formatter.maximumFractionDigits = 1
+        formatter.decimalSeparator = "."
+        formatter.minimumIntegerDigits = 0
         return formatter
     }
 
@@ -236,6 +249,7 @@ struct MainChartView: View {
                 ZStack {
                     xGridView(fullSize: fullSize)
                     carbsView(fullSize: fullSize)
+                    fpuView(fullSize: fullSize)
                     bolusView(fullSize: fullSize)
                     glucoseView(fullSize: fullSize)
                     predictionsView(fullSize: fullSize)
@@ -352,6 +366,28 @@ struct MainChartView: View {
         }
     }
 
+    private func fpuView(fullSize: CGSize) -> some View {
+        ZStack {
+            fpuPath
+                .fill(Color.red)
+            fpuPath
+                .stroke(Color.primary, lineWidth: 0.5)
+
+            ForEach(fpuDots, id: \.rect.minX) { info -> AnyView in
+                let position = CGPoint(x: info.rect.midX, y: info.rect.minY - 8)
+                return Text(fpuFormatter.string(from: info.value as NSNumber)!).font(.caption2)
+                    .position(position)
+                    .asAny()
+            }
+        }
+        .onChange(of: carbs) { _ in
+            calculateFPUsDots(fullSize: fullSize)
+        }
+        .onChange(of: didAppearTrigger) { _ in
+            calculateFPUsDots(fullSize: fullSize)
+        }
+    }
+
     private func tempTargetsView(fullSize: CGSize) -> some View {
         ZStack {
             tempTargetsPath
@@ -413,6 +449,7 @@ extension MainChartView {
         calculateGlucoseDots(fullSize: fullSize)
         calculateBolusDots(fullSize: fullSize)
         calculateCarbsDots(fullSize: fullSize)
+        calculateFPUsDots(fullSize: fullSize)
         calculateTempTargetsRects(fullSize: fullSize)
         calculateBasalPoints(fullSize: fullSize)
         calculateSuspensions(fullSize: fullSize)
@@ -458,7 +495,8 @@ extension MainChartView {
 
     private func calculateCarbsDots(fullSize: CGSize) {
         calculationQueue.async {
-            let dots = carbs.map { value -> DotInfo in
+            let realCarbs = carbs.filter { !($0.isFPU ?? false) }
+            let dots = realCarbs.map { value -> DotInfo in
                 let center = timeToInterpolatedPoint(value.createdAt.timeIntervalSince1970, fullSize: fullSize)
                 let size = Config.carbsSize + CGFloat(value.carbs) * Config.carbsScale
                 let rect = CGRect(x: center.x - size / 2, y: center.y - size / 2, width: size, height: size)
@@ -478,6 +516,29 @@ extension MainChartView {
         }
     }
 
+    private func calculateFPUsDots(fullSize: CGSize) {
+        calculationQueue.async {
+            let fpus = carbs.filter { $0.isFPU ?? false }
+            let dots = fpus.map { value -> DotInfo in
+                let center = timeToInterpolatedPoint(value.createdAt.timeIntervalSince1970, fullSize: fullSize)
+                let size = Config.carbsSize + CGFloat(value.carbs) * Config.carbsScale
+                let rect = CGRect(x: center.x - size / 2, y: center.y - size / 2, width: size, height: size)
+                return DotInfo(rect: rect, value: value.carbs)
+            }
+
+            let path = Path { path in
+                for dot in dots {
+                    path.addEllipse(in: dot.rect)
+                }
+            }
+
+            DispatchQueue.main.async {
+                fpuDots = dots
+                fpuPath = path
+            }
+        }
+    }
+
     private func calculatePredictionDots(fullSize: CGSize, type: PredictionType) {
         calculationQueue.async {
             let values: [Int] = { () -> [Int] in