Jon B Mårtensson 2 лет назад
Родитель
Сommit
36e6791b91

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

@@ -140,16 +140,16 @@ extension AddCarbs {
             var addedString = ""
 
             if extracarbs > 0, filteredArray.isNotEmpty {
-                addedString += "Additional carbs: \(extracarbs) "
+                addedString += "Additional carbs: \(extracarbs) ,"
             } else if extracarbs < 0 { addedString += "Removed carbs: \(extracarbs) " }
 
             if extraFat > 0, filteredArray.isNotEmpty {
-                addedString += "Additional fat: \(extraFat) "
-            } else if extraFat < 0 { addedString += "Removed fat: \(extraFat) " }
+                addedString += "Additional fat: \(extraFat) ,"
+            } else if extraFat < 0 { addedString += "Removed fat: \(extraFat) ," }
 
             if extraProtein > 0, filteredArray.isNotEmpty {
-                addedString += "Additional protein: \(extraProtein) "
-            } else if extraProtein < 0 { addedString += "Removed protein: \(extraProtein) " }
+                addedString += "Additional protein: \(extraProtein) ,"
+            } else if extraProtein < 0 { addedString += "Removed protein: \(extraProtein) ," }
 
             if addedString != "" {
                 waitersNotepad.append(addedString)
@@ -170,7 +170,7 @@ extension AddCarbs {
 
         func loadEntries(_ editMode: Bool) {
             if editMode {
-                coredataContext.perform {
+                coredataContext.performAndWait {
                     var mealToEdit = [Meals]()
                     let requestMeal = Meals.fetchRequest() as NSFetchRequest<Meals>
                     let sortMeal = NSSortDescriptor(key: "createdAt", ascending: false)
@@ -188,15 +188,17 @@ extension AddCarbs {
         }
 
         func saveToCoreData(_ stored: [CarbsEntry]) {
-            let save = Meals(context: coredataContext)
-            save.createdAt = Date.now
-            save.id = stored.first?.collectionID ?? ""
-            save.carbs = Double(stored.first?.carbs ?? 0)
-            save.fat = Double(stored.first?.fat ?? 0)
-            save.protein = Double(stored.first?.protein ?? 0)
-            save.note = stored.first?.note ?? ""
-            if coredataContext.hasChanges {
-                try? coredataContext.save()
+            coredataContext.performAndWait {
+                let save = Meals(context: coredataContext)
+                if let entry = stored.first {
+                    save.createdAt = Date.now
+                    save.id = entry.collectionID ?? ""
+                    save.carbs = Double(entry.carbs)
+                    save.fat = Double(entry.fat ?? 0)
+                    save.protein = Double(entry.protein ?? 0)
+                    save.note = entry.note
+                    try? coredataContext.save()
+                }
             }
         }
     }

+ 163 - 98
FreeAPS/Sources/Modules/AddCarbs/View/AddCarbsRootView.swift

@@ -10,6 +10,7 @@ extension AddCarbs {
         @State var dish: String = ""
         @State var isPromptPresented = false
         @State var saved = false
+        @State var pushed = false
         @State private var showAlert = false
         @FocusState private var isFocused: Bool
 
@@ -29,12 +30,12 @@ extension AddCarbs {
 
         var body: some View {
             Form {
-                if let carbsReq = state.carbsRequired {
+                if let carbsReq = state.carbsRequired, state.carbs < carbsReq {
                     Section {
                         HStack {
                             Text("Carbs required")
                             Spacer()
-                            Text(formatter.string(from: carbsReq as NSNumber)! + " g")
+                            Text((formatter.string(from: carbsReq as NSNumber) ?? "") + " g")
                         }
                     }
                 }
@@ -50,11 +51,55 @@ extension AddCarbs {
                             cleanInput: true
                         )
                         Text("grams").foregroundColor(.secondary)
-                    }.padding(.vertical)
+                    }
 
                     if state.useFPUconversion {
                         proteinAndFat()
                     }
+
+                    // Summary when combining presets
+                    if state.waitersNotepad() != "" {
+                        HStack {
+                            Text("Serving")
+                            let test = state.waitersNotepad().components(separatedBy: ", ").removeDublicates()
+                            HStack(spacing: 0) {
+                                ForEach(test, id: \.self) {
+                                    Text($0).foregroundStyle(Color.randomGreen()).font(.footnote)
+                                    Text($0 == test[test.count - 1] ? "" : ", ")
+                                }
+                            }.frame(maxWidth: .infinity, alignment: .trailing)
+                        }
+                    }
+
+                    // Time
+                    HStack {
+                        let now = Date.now
+                        Text("Time")
+                        Spacer()
+                        if !pushed {
+                            Button {
+                                pushed = true
+                            } label: { Text("Now") }.buttonStyle(.borderless).foregroundColor(.secondary).padding(.trailing, 5)
+                        } else {
+                            Button { state.date = state.date.addingTimeInterval(-10.minutes.timeInterval) }
+                            label: { Image(systemName: "minus.circle") }.tint(.blue).buttonStyle(.borderless)
+                            DatePicker(
+                                "Time",
+                                selection: $state.date,
+                                in: ...now,
+                                displayedComponents: [.hourAndMinute]
+                            ).controlSize(.mini)
+                                .labelsHidden()
+                            Button {
+                                if state.date.addingTimeInterval(5.minutes.timeInterval) < now {
+                                    state.date = state.date.addingTimeInterval(10.minutes.timeInterval)
+                                }
+                            }
+                            label: { Image(systemName: "plus.circle") }.tint(.blue).buttonStyle(.borderless)
+                        }
+                    }
+
+                    // Optional meal note
                     HStack {
                         Text("Note").foregroundColor(.secondary)
                         TextField("", text: $state.note).multilineTextAlignment(.trailing)
@@ -62,14 +107,11 @@ extension AddCarbs {
                             Button { isFocused = false } label: { Image(systemName: "keyboard.chevron.compact.down") }
                                 .controlSize(.mini)
                         }
-                    }.focused($isFocused)
-                        .popover(isPresented: $isPromptPresented) {
-                            presetPopover
-                        }
-                }
-
-                Section {
-                    mealPresets
+                    }
+                    .focused($isFocused)
+                    .popover(isPresented: $isPromptPresented) {
+                        presetPopover
+                    }
                 }
 
                 Section {
@@ -77,10 +119,11 @@ extension AddCarbs {
                     label: { Text(state.skipBolus ? "Save" : "Continue") }
                         .disabled(state.carbs <= 0 && state.fat <= 0 && state.protein <= 0)
                         .frame(maxWidth: .infinity, alignment: .center)
-                } footer: { Text(state.waitersNotepad().description) }
+                }.listRowBackground(!empty ? Color(.systemBlue) : Color(.systemGray4))
+                    .tint(.white)
 
                 Section {
-                    DatePicker("Date", selection: $state.date)
+                    mealPresets
                 }
             }
             .onAppear {
@@ -93,7 +136,7 @@ extension AddCarbs {
             .navigationBarItems(leading: Button("Close", action: state.hideModal))
         }
 
-        var presetPopover: some View {
+        private var presetPopover: some View {
             Form {
                 Section {
                     TextField("Name Of Dish", text: $dish)
@@ -121,114 +164,125 @@ extension AddCarbs {
             }
         }
 
-        var notEmpty: Bool {
-            state.carbs > 0 || state.protein > 0 || state.fat > 0
+        private var empty: Bool {
+            state.carbs <= 0 && state.fat <= 0 && state.protein <= 0
+        }
+
+        private var minusButton: some View {
+            Button {
+                if state.carbs != 0,
+                   (state.carbs - (((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal) as Decimal) >= 0
+                {
+                    state.carbs -= (((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal)
+                } else { state.carbs = 0 }
+
+                if state.fat != 0,
+                   (state.fat - (((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal) as Decimal) >= 0
+                {
+                    state.fat -= (((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal)
+                } else { state.fat = 0 }
+
+                if state.protein != 0,
+                   (state.protein - (((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal) as Decimal) >= 0
+                {
+                    state.protein -= (((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal)
+                } else { state.protein = 0 }
+
+                state.removePresetFromNewMeal()
+                if state.carbs == 0, state.fat == 0, state.protein == 0 { state.summation = [] }
+            }
+            label: { Image(systemName: "minus.circle") }
+                .disabled(
+                    state
+                        .selection == nil ||
+                        (
+                            !state.summation
+                                .contains(state.selection?.dish ?? "") && (state.selection?.dish ?? "") != ""
+                        )
+                )
+                .buttonStyle(.borderless)
+                .tint(.blue)
+        }
+
+        private var plusButton: some View {
+            Button {
+                state.carbs += ((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal
+                state.fat += ((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal
+                state.protein += ((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal
+
+                state.addPresetToNewMeal()
+            }
+            label: { Image(systemName: "plus.circle") }
+                .disabled(state.selection == nil)
+                .buttonStyle(.borderless)
+                .tint(.blue)
         }
 
-        var mealPresets: some View {
+        private var mealPresets: some View {
             Section {
                 HStack {
-                    Button {
-                        isPromptPresented = true
+                    if state.selection != nil {
+                        minusButton
                     }
-                    label: { Text("Save as Preset") }
-                        .buttonStyle(BorderlessButtonStyle())
-                        .disabled(
-                            !notEmpty ||
-                                (
-                                    (((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal) == state
-                                        .carbs && (((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal) == state
-                                        .fat && (((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal) == state
-                                        .protein
-                                )
-                        )
-
-                    Picker("Select a Preset", selection: $state.selection) {
-                        Text("Presets").tag(nil as Presets?)
+                    Picker("Preset", selection: $state.selection) {
+                        Text("Saved Food").tag(nil as Presets?)
                         ForEach(carbPresets, id: \.self) { (preset: Presets) in
                             Text(preset.dish ?? "").tag(preset as Presets?)
                         }
                     }
                     .labelsHidden()
-                    .frame(maxWidth: .infinity, alignment: .trailing)
+                    .frame(maxWidth: .infinity, alignment: .center)
                     ._onBindingChange($state.selection) { _ in
                         state.carbs += ((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal
                         state.fat += ((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal
                         state.protein += ((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal
                         state.addToSummation()
                     }
+                    if state.selection != nil {
+                        plusButton
+                    }
                 }
 
-                if state.selection != nil {
-                    HStack {
-                        Button("Delete Preset") {
-                            showAlert.toggle()
-                        }
-                        .disabled(state.selection == nil)
-                        .tint(.orange)
-                        .buttonStyle(BorderlessButtonStyle())
-                        .alert(
-                            "Delete preset '\(state.selection?.dish ?? "")'?",
-                            isPresented: $showAlert,
-                            actions: {
-                                Button("No", role: .cancel) {}
-                                Button("Yes", role: .destructive) {
-                                    state.deletePreset()
+                HStack {
+                    Button("Delete Preset") {
+                        showAlert.toggle()
+                    }
+                    .disabled(state.selection == nil)
+                    .tint(.orange)
+                    .buttonStyle(.borderless)
+                    .alert(
+                        "Delete preset '\(state.selection?.dish ?? "")'?",
+                        isPresented: $showAlert,
+                        actions: {
+                            Button("No", role: .cancel) {}
+                            Button("Yes", role: .destructive) {
+                                state.deletePreset()
 
-                                    state.carbs += ((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal
-                                    state.fat += ((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal
-                                    state.protein += ((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal
+                                state.carbs += ((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal
+                                state.fat += ((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal
+                                state.protein += ((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal
 
-                                    state.addPresetToNewMeal()
-                                }
+                                state.addPresetToNewMeal()
                             }
-                        )
-                        Button {
-                            if state.carbs != 0,
-                               (state.carbs - (((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal) as Decimal) >= 0
-                            {
-                                state.carbs -= (((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal)
-                            } else { state.carbs = 0 }
-
-                            if state.fat != 0,
-                               (state.fat - (((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal) as Decimal) >= 0
-                            {
-                                state.fat -= (((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal)
-                            } else { state.fat = 0 }
-
-                            if state.protein != 0,
-                               (state.protein - (((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal) as Decimal) >= 0
-                            {
-                                state.protein -= (((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal)
-                            } else { state.protein = 0 }
-
-                            state.removePresetFromNewMeal()
-                            if state.carbs == 0, state.fat == 0, state.protein == 0 { state.summation = [] }
                         }
-                        label: { Text("[ -1 ]") }
-                            .disabled(
-                                state
-                                    .selection == nil ||
-                                    (
-                                        !state.summation
-                                            .contains(state.selection?.dish ?? "") && (state.selection?.dish ?? "") != ""
-                                    )
-                            )
-                            .buttonStyle(BorderlessButtonStyle())
-                            .frame(maxWidth: .infinity, alignment: .trailing)
-                            .tint(.minus)
-                        Button {
-                            state.carbs += ((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal
-                            state.fat += ((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal
-                            state.protein += ((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal
+                    )
 
-                            state.addPresetToNewMeal()
-                        }
-                        label: { Text("[ +1 ]") }
-                            .disabled(state.selection == nil)
-                            .buttonStyle(BorderlessButtonStyle())
-                            .tint(.blue)
+                    Spacer()
+
+                    Button {
+                        isPromptPresented = true
                     }
+                    label: { Text("Save as Preset") }
+                        .buttonStyle(.borderless)
+                        .disabled(
+                            empty ||
+                                (
+                                    (((state.selection?.carbs ?? 0) as NSDecimalNumber) as Decimal) == state
+                                        .carbs && (((state.selection?.fat ?? 0) as NSDecimalNumber) as Decimal) == state
+                                        .fat && (((state.selection?.protein ?? 0) as NSDecimalNumber) as Decimal) == state
+                                        .protein
+                                )
+                        )
                 }
             }
         }
@@ -262,3 +316,14 @@ extension AddCarbs {
         }
     }
 }
+
+public extension Color {
+    static func randomGreen(randomOpacity: Bool = false) -> Color {
+        Color(
+            red: .random(in: 0 ... 1),
+            green: .random(in: 0.4 ... 0.7),
+            blue: .random(in: 0.2 ... 1),
+            opacity: randomOpacity ? .random(in: 0.8 ... 1) : 1
+        )
+    }
+}

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

@@ -1,5 +1,3 @@
-
-import CoreData
 import LoopKit
 import SwiftUI
 import Swinject
@@ -14,8 +12,6 @@ extension Bolus {
         @Injected() var settings: SettingsManager!
         @Injected() var nsManager: NightscoutManager!
 
-        let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
-
         @Published var suggestion: Suggestion?
         @Published var amount: Decimal = 0
         @Published var insulinRecommended: Decimal = 0

+ 1 - 0
FreeAPS/Sources/Modules/Bolus/View/DefaultBolusCalcRootView.swift

@@ -1,3 +1,4 @@
+import CoreData
 import SwiftUI
 import Swinject