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

cap fat and protein entries to limits

- Adds two new settings: `maxFat` & `maxProtein`
  - default to 250g, same as `maxCarbs`
- Change label of `Carbohydrate limit` to `Limit Per Entry` for Meal Settings
- For meal entry module, shorten `grams` to `g`
- If bolus, carbs, fat, or protein exceed their limit:
  - Change `U` or `g` to `⚠️`
  - Disable submit button, change text to red, and replace with warning
Mike Plante пре 1 година
родитељ
комит
b93963e29b

+ 2 - 0
FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json

@@ -40,6 +40,8 @@
   "oneDimensionalGraph" : false,
   "rulerMarks" : true,
   "maxCarbs": 250,
+  "maxFat": 250,
+  "maxProtein": 250,
   "displayFatAndProteinOnWatch": false,
   "lockScreenView": "simple"
 }

+ 10 - 0
FreeAPS/Sources/Models/FreeAPSSettings.swift

@@ -41,6 +41,8 @@ struct FreeAPSSettings: JSON, Equatable {
     var oneDimensionalGraph: Bool = false
     var rulerMarks: Bool = true
     var maxCarbs: Decimal = 250
+    var maxFat: Decimal = 250
+    var maxProtein: Decimal = 250
     var displayFatAndProteinOnWatch: Bool = false
     var onlyAutotuneBasals: Bool = false
     var useLiveActivity: Bool = false
@@ -218,6 +220,14 @@ extension FreeAPSSettings: Decodable {
             settings.maxCarbs = maxCarbs
         }
 
+        if let maxFat = try? container.decode(Decimal.self, forKey: .maxFat) {
+            settings.maxFat = maxFat
+        }
+
+        if let maxProtein = try? container.decode(Decimal.self, forKey: .maxProtein) {
+            settings.maxProtein = maxProtein
+        }
+
         if let displayFatAndProteinOnWatch = try? container.decode(Bool.self, forKey: .displayFatAndProteinOnWatch) {
             settings.displayFatAndProteinOnWatch = displayFatAndProteinOnWatch
         }

+ 17 - 1
FreeAPS/Sources/Modules/AddCarbs/AddCarbsStateModel.swift

@@ -16,7 +16,9 @@ extension AddCarbs {
         @Published var dish: String = ""
         @Published var selection: Presets?
         @Published var summation: [String] = []
-        @Published var maxCarbs: Decimal = 0
+        @Published var maxCarbs: Decimal = 250
+        @Published var maxFat: Decimal = 250
+        @Published var maxProtein: Decimal = 250
         @Published var note: String = ""
 
         let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
@@ -25,6 +27,8 @@ extension AddCarbs {
             subscribeSetting(\.useFPUconversion, on: $useFPUconversion) { useFPUconversion = $0 }
             carbsRequired = provider.suggestion?.carbsReq
             maxCarbs = settings.settings.maxCarbs
+            maxFat = settings.settings.maxFat
+            maxProtein = settings.settings.maxProtein
         }
 
         func add() {
@@ -160,5 +164,17 @@ extension AddCarbs {
             }
             return waitersNotepadString
         }
+
+        func saveButtonText() -> String {
+            if carbs > maxCarbs {
+                return "\(NSLocalizedString("Max Carbs of", comment: "")) \(maxCarbs) \(NSLocalizedString("g", comment: "")) \(NSLocalizedString("exceeded", comment: ""))"
+            } else if fat > maxFat {
+                return "\(NSLocalizedString("Max Fat of", comment: "")) \(maxFat) \(NSLocalizedString("g", comment: "")) \(NSLocalizedString("exceeded", comment: ""))"
+            } else if protein > maxProtein {
+                return "\(NSLocalizedString("Max Protein of", comment: "")) \(maxProtein) \(NSLocalizedString("g", comment: "")) \(NSLocalizedString("exceeded", comment: ""))"
+            } else {
+                return NSLocalizedString("Save and continue", comment: "")
+            }
+        }
     }
 }

+ 9 - 16
FreeAPS/Sources/Modules/AddCarbs/View/AddCarbsRootView.swift

@@ -48,7 +48,7 @@ extension AddCarbs {
                             autofocus: true,
                             cleanInput: true
                         )
-                        Text("grams").foregroundColor(.secondary)
+                        Text(state.carbs > state.maxCarbs ? "⚠️" : "g").foregroundColor(.secondary)
                     }.padding(.vertical)
 
                     if state.useFPUconversion {
@@ -118,23 +118,17 @@ extension AddCarbs {
 
                 Section {
                     Button { state.add() }
-                    label: {
-                        Text(
-                            state.carbs <= state.maxCarbs ? NSLocalizedString("Save and continue", comment: "") :
-                                NSLocalizedString("Max Carbs of", comment: "")
-                                + " "
-                                + formatter.string(from: state.maxCarbs as NSNumber)!
-                                + NSLocalizedString("g", comment: "The short unit display string for grams")
-                                + " "
-                                + NSLocalizedString("exceeded", comment: "")
-                        ).font(.title3) }
+                    label: { Text(state.saveButtonText()).font(.title3) }
                         .disabled(
                             state.carbs > state.maxCarbs
+                                || state.fat > state.maxFat
+                                || state.protein > state.maxProtein
                                 || (state.carbs <= 0 && state.fat <= 0 && state.protein <= 0)
                         )
                         .foregroundStyle(
                             (state.carbs <= 0 && state.fat <= 0 && state.protein <= 0) ? .gray :
-                                state.carbs > state.maxCarbs ? .red : .blue
+                                state.carbs > state.maxCarbs || state.fat > state.maxFat || state.protein > state
+                                .maxProtein ? .red : .blue
                         )
                         .frame(maxWidth: .infinity, alignment: .center)
                 } footer: { Text(state.waitersNotepad().description) }
@@ -276,7 +270,7 @@ extension AddCarbs {
                     autofocus: false,
                     cleanInput: true
                 )
-                Text("grams").foregroundColor(.secondary)
+                Text(state.fat > state.maxFat ? "⚠️" : "g").foregroundColor(.secondary)
             }
             HStack {
                 Text("Protein").foregroundColor(.red) // .fontWeight(.thin)
@@ -287,9 +281,8 @@ extension AddCarbs {
                     formatter: formatter,
                     autofocus: false,
                     cleanInput: true
-                ).foregroundColor(.loopRed)
-
-                Text("grams").foregroundColor(.secondary)
+                )
+                Text(state.protein > state.maxProtein ? "⚠️" : "g").foregroundColor(.secondary)
             }
         }
     }

+ 1 - 1
FreeAPS/Sources/Modules/Bolus/View/BolusRootView.swift

@@ -72,7 +72,7 @@ extension Bolus {
                                 autofocus: true,
                                 cleanInput: true
                             )
-                            Text("U").foregroundColor(.secondary)
+                            Text(state.amount > state.maxBolus ? "⚠️" : "U").foregroundColor(.secondary)
                         }
                     }
                     header: { Text("Bolus") }

+ 4 - 0
FreeAPS/Sources/Modules/FPUConfig/FPUConfigStateModel.swift

@@ -3,6 +3,8 @@ import SwiftUI
 extension FPUConfig {
     final class StateModel: BaseStateModel<Provider> {
         @Published var maxCarbs: Decimal = 250
+        @Published var maxFat: Decimal = 250
+        @Published var maxProtein: Decimal = 250
         @Published var individualAdjustmentFactor: Decimal = 0
         @Published var timeCap: Decimal = 0
         @Published var minuteInterval: Decimal = 0
@@ -10,6 +12,8 @@ extension FPUConfig {
 
         override func subscribe() {
             subscribeSetting(\.maxCarbs, on: $maxCarbs) { maxCarbs = $0 }
+            subscribeSetting(\.maxFat, on: $maxFat) { maxFat = $0 }
+            subscribeSetting(\.maxProtein, on: $maxProtein) { maxProtein = $0 }
             subscribeSetting(\.timeCap, on: $timeCap.map(Int.init), initial: {
                 let value = max(min($0, 12), 5)
                 timeCap = Decimal(value)

+ 9 - 1
FreeAPS/Sources/Modules/FPUConfig/View/FPUConfigRootView.swift

@@ -28,11 +28,19 @@ extension FPUConfig {
 
         var body: some View {
             Form {
-                Section(header: Text("Carbohydrate limit")) {
+                Section(header: Text("Limit Per Entry")) {
                     HStack {
                         Text("Max Carbs")
                         DecimalTextField("g", value: $state.maxCarbs, formatter: formatter)
                     }
+                    HStack {
+                        Text("Max Fat")
+                        DecimalTextField("g", value: $state.maxFat, formatter: formatter)
+                    }
+                    HStack {
+                        Text("Max Protein")
+                        DecimalTextField("g", value: $state.maxProtein, formatter: formatter)
+                    }
                 }
 
                 Section(header: Text("Fat and Protein Conversion Settings")) {