Просмотр исходного кода

Refactor presets; add addMealPreset view

Deniz Cengiz 1 год назад
Родитель
Сommit
c62c3ee04a

+ 4 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -434,6 +434,7 @@
 		DDD1631A2C4C695E00CD525A /* EditOverrideForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD163192C4C695E00CD525A /* EditOverrideForm.swift */; };
 		DDD1631C2C4C697400CD525A /* AddOverrideForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD1631B2C4C697400CD525A /* AddOverrideForm.swift */; };
 		DDD1631F2C4C6F6900CD525A /* TrioCoreDataPersistentContainer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DDD1631D2C4C6F6900CD525A /* TrioCoreDataPersistentContainer.xcdatamodeld */; };
+		DDF847E62C5D66490049BB3B /* AddMealPresetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF847E52C5D66490049BB3B /* AddMealPresetView.swift */; };
 		E00EEC0327368630002FF094 /* ServiceAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = E00EEBFD27368630002FF094 /* ServiceAssembly.swift */; };
 		E00EEC0427368630002FF094 /* SecurityAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = E00EEBFE27368630002FF094 /* SecurityAssembly.swift */; };
 		E00EEC0527368630002FF094 /* StorageAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = E00EEBFF27368630002FF094 /* StorageAssembly.swift */; };
@@ -1039,6 +1040,7 @@
 		DDD163192C4C695E00CD525A /* EditOverrideForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditOverrideForm.swift; sourceTree = "<group>"; };
 		DDD1631B2C4C697400CD525A /* AddOverrideForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOverrideForm.swift; sourceTree = "<group>"; };
 		DDD1631E2C4C6F6900CD525A /* TrioCoreDataPersistentContainer.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TrioCoreDataPersistentContainer.xcdatamodel; sourceTree = "<group>"; };
+		DDF847E52C5D66490049BB3B /* AddMealPresetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMealPresetView.swift; sourceTree = "<group>"; };
 		E00EEBFD27368630002FF094 /* ServiceAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceAssembly.swift; sourceTree = "<group>"; };
 		E00EEBFE27368630002FF094 /* SecurityAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecurityAssembly.swift; sourceTree = "<group>"; };
 		E00EEBFF27368630002FF094 /* StorageAssembly.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageAssembly.swift; sourceTree = "<group>"; };
@@ -2240,6 +2242,7 @@
 				58237D9D2BCF0A6B00A47A79 /* PopupView.swift */,
 				BDB899872C564509006F3298 /* ForeCastChart.swift */,
 				BD0B2EF22C5998E600B3298F /* MealPresetView.swift */,
+				DDF847E52C5D66490049BB3B /* AddMealPresetView.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -3038,6 +3041,7 @@
 				DD57C4D12C4C7103001A5B28 /* ImportError+CoreDataProperties.swift in Sources */,
 				DD57C4D22C4C7103001A5B28 /* StatsData+CoreDataClass.swift in Sources */,
 				DD57C4D32C4C7103001A5B28 /* StatsData+CoreDataProperties.swift in Sources */,
+				DDF847E62C5D66490049BB3B /* AddMealPresetView.swift in Sources */,
 				3811DEAE25C9D88300A708ED /* Cache.swift in Sources */,
 				383420D625FFE38C002D46C1 /* LoopView.swift in Sources */,
 				3811DEAD25C9D88300A708ED /* UserDefaults+Cache.swift in Sources */,

+ 119 - 0
FreeAPS/Sources/Modules/Bolus/View/AddMealPresetView.swift

@@ -0,0 +1,119 @@
+import CoreData
+import Foundation
+import SwiftUI
+
+struct AddMealPresetView: View {
+    @Binding var dish: String
+    @Binding var presetCarbs: Decimal
+    @Binding var presetFat: Decimal
+    @Binding var presetProtein: Decimal
+    var onSave: () -> Void
+    var onCancel: () -> Void
+
+    @Environment(\.colorScheme) private var colorScheme
+    private var color: LinearGradient {
+        colorScheme == .dark ? LinearGradient(
+            gradient: Gradient(colors: [
+                Color.bgDarkBlue,
+                Color.bgDarkerDarkBlue
+            ]),
+            startPoint: .top,
+            endPoint: .bottom
+        )
+            :
+            LinearGradient(
+                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
+                startPoint: .top,
+                endPoint: .bottom
+            )
+    }
+
+    private var mealFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 1
+        return formatter
+    }
+
+    var body: some View {
+        NavigationStack {
+            Form {
+                Section {
+                    TextField("Name Of Dish", text: $dish)
+                } header: {
+                    Text("New Preset")
+                }
+                .listRowBackground(Color.chart)
+
+                Section {
+                    carbsTextField()
+                    proteinAndFat()
+                }
+                .listRowBackground(Color.chart)
+
+                savePresetButton
+            }
+            .scrollContentBackground(.hidden).background(color)
+            .navigationTitle("Add Meal Preset")
+            .navigationBarTitleDisplayMode(.inline)
+            .toolbar(content: {
+                ToolbarItem(placement: .topBarLeading) {
+                    Button {
+                        onCancel()
+                    } label: {
+                        Text("Cancel")
+                    }
+                }
+            })
+        }
+    }
+
+    @ViewBuilder private func carbsTextField() -> some View {
+        HStack {
+            Text("Carbs").fontWeight(.semibold)
+            Spacer()
+            TextFieldWithToolBar(
+                text: $presetCarbs,
+                placeholder: "0",
+                keyboardType: .numberPad,
+                numberFormatter: mealFormatter
+            )
+            Text("g").foregroundColor(.secondary)
+        }
+    }
+
+    @ViewBuilder private func proteinAndFat() -> some View {
+        HStack {
+            Text("Fat").foregroundColor(.orange)
+            Spacer()
+            TextFieldWithToolBar(text: $presetFat, placeholder: "0", keyboardType: .numberPad, numberFormatter: mealFormatter)
+            Text("g").foregroundColor(.secondary)
+        }
+        HStack {
+            Text("Protein").foregroundColor(.red)
+            Spacer()
+            TextFieldWithToolBar(
+                text: $presetProtein,
+                placeholder: "0",
+                keyboardType: .numberPad,
+                numberFormatter: mealFormatter
+            )
+            Text("g").foregroundColor(.secondary)
+        }
+    }
+
+    private var savePresetButton: some View {
+        Button {
+            onSave()
+        }
+        label: {
+            Text("Save")
+                .font(.headline)
+                .foregroundStyle(Color.white)
+                .frame(maxWidth: .infinity, alignment: .center)
+        }
+        .listRowBackground(Color(.systemBlue))
+        .shadow(radius: 3)
+        .clipShape(RoundedRectangle(cornerRadius: 8))
+    }
+}

+ 53 - 117
FreeAPS/Sources/Modules/Bolus/View/MealPresetView.swift

@@ -10,8 +10,7 @@ struct MealPresetView: View {
 
     @State private var showAlert = false
     @State private var dish: String = ""
-
-    @State private var addNewPreset: Bool = false
+    @State private var showAddNewPresetSheet = false
 
     @State private var presetCarbs: Decimal = 0
     @State private var presetFat: Decimal = 0
@@ -53,98 +52,53 @@ struct MealPresetView: View {
     var body: some View {
         NavigationStack {
             Form {
-                if addNewPreset {
-                    showNewPresetForm()
-                } else {
-                    addNewPresetButton
-                    mealPresets
-                    dishInfos()
-                    addPresetToTreatmentsButton
-                }
+                mealPresets
+                dishInfos()
+                addPresetToTreatmentsButton
             }
             .scrollContentBackground(.hidden).background(color)
             .navigationTitle("Meal Presets")
-            .navigationBarTitleDisplayMode(.inline)
+            .navigationBarTitleDisplayMode(.automatic)
             .toolbar(content: {
                 ToolbarItem(placement: .topBarLeading) {
                     Button {
-                        addNewPreset ? (addNewPreset = false) : dismiss()
+                        dismiss()
+                        resetValues()
                     } label: {
-                        Text(addNewPreset ? "Cancel" : "Close")
+                        Text("Close")
                     }
                 }
+                ToolbarItem(placement: .topBarTrailing) {
+                    Button(action: {
+                        showAddNewPresetSheet.toggle()
+                        resetValues()
+                    }, label: {
+                        HStack {
+                            Text("New Preset")
+                            Image(systemName: "plus")
+                        }
+                    })
+                }
             })
+            .sheet(isPresented: $showAddNewPresetSheet) {
+                AddMealPresetView(
+                    dish: $dish,
+                    presetCarbs: $presetCarbs,
+                    presetFat: $presetFat,
+                    presetProtein: $presetProtein,
+                    onSave: savePreset,
+                    onCancel: {
+                        showAddNewPresetSheet.toggle()
+                        resetValues()
+                    }
+                )
+            }
             .onDisappear {
                 resetValues()
             }
         }
     }
 
-    private var addNewPresetButton: some View {
-        Button(action: {
-            addNewPreset = true
-            resetValues()
-        }, label: {
-            HStack {
-                Spacer()
-                Text("Add new meal Preset")
-                Spacer()
-            }
-        })
-    }
-
-    @ViewBuilder private func showNewPresetForm() -> some View {
-        Section {
-            TextField("Name Of Dish", text: $dish)
-        } header: {
-            Text("New Preset")
-        }
-
-        Section {
-            carbsTextField()
-
-            if state.useFPUconversion {
-                proteinAndFat()
-            }
-        }
-
-        savePresetButton
-    }
-
-    @ViewBuilder private func carbsTextField() -> some View {
-        HStack {
-            Text("Carbs").fontWeight(.semibold)
-            Spacer()
-            TextFieldWithToolBar(
-                text: $presetCarbs,
-                placeholder: "0",
-                keyboardType: .numberPad,
-                numberFormatter: mealFormatter
-            )
-            Text("g").foregroundColor(.secondary)
-        }
-    }
-
-    @ViewBuilder private func proteinAndFat() -> some View {
-        HStack {
-            Text("Fat").foregroundColor(.orange)
-            Spacer()
-            TextFieldWithToolBar(text: $presetFat, placeholder: "0", keyboardType: .numberPad, numberFormatter: mealFormatter)
-            Text("g").foregroundColor(.secondary)
-        }
-        HStack {
-            Text("Protein").foregroundColor(.red)
-            Spacer()
-            TextFieldWithToolBar(
-                text: $presetProtein,
-                placeholder: "0",
-                keyboardType: .numberPad,
-                numberFormatter: mealFormatter
-            )
-            Text("g").foregroundColor(.secondary)
-        }
-    }
-
     private var mealPresets: some View {
         Section {
             HStack {
@@ -202,38 +156,7 @@ struct MealPresetView: View {
 
                 Spacer()
             }
-        }
-    }
-
-    private var savePresetButton: some View {
-        Button {
-            if dish != "" {
-                let preset = MealPresetStored(context: moc)
-                preset.dish = dish
-                preset.fat = presetFat as NSDecimalNumber
-                preset.protein = presetProtein as NSDecimalNumber
-                preset.carbs = presetCarbs as NSDecimalNumber
-
-                do {
-                    guard self.moc.hasChanges else { return }
-                    try moc.save()
-                    resetValues()
-                    addNewPreset = false
-                } catch let error as NSError {
-                    debugPrint("\(DebuggingIdentifiers.failed) Failed to save Meal Preset with error: \(error.userInfo)")
-                }
-            }
-        }
-        label: {
-            Text("Save")
-                .font(.headline)
-                .foregroundStyle(Color.white)
-                .frame(maxWidth: .infinity, alignment: .center)
-        }
-        .disabled(notEnoughPresetInfosGiven)
-        .listRowBackground(notEnoughPresetInfosGiven ? Color(.systemGray3) : Color(.systemBlue))
-        .shadow(radius: 3)
-        .clipShape(RoundedRectangle(cornerRadius: 8))
+        }.listRowBackground(Color.chart)
     }
 
     private var addPresetToTreatmentsButton: some View {
@@ -260,12 +183,6 @@ struct MealPresetView: View {
         state.selection == nil || carbs == 0 || fat == 0 || protein == 0
     }
 
-    private var notEnoughPresetInfosGiven: Bool {
-        state
-            .useFPUconversion ? (presetCarbs <= 0 && presetFat <= 0 && presetProtein <= 0 || dish == "") :
-            (presetCarbs <= 0 || dish == "")
-    }
-
     @ViewBuilder private func dishInfos() -> some View {
         if !state.summation.isEmpty {
             let presetSummary = generatePresetSummary()
@@ -317,7 +234,7 @@ struct MealPresetView: View {
                         }
                     }
                 }
-            }
+            }.listRowBackground(Color.chart)
         }
     }
 
@@ -401,4 +318,23 @@ struct MealPresetView: View {
         .buttonStyle(.borderless)
         .tint(.blue)
     }
+
+    private func savePreset() {
+        if dish != "" {
+            let preset = MealPresetStored(context: moc)
+            preset.dish = dish
+            preset.fat = presetFat as NSDecimalNumber
+            preset.protein = presetProtein as NSDecimalNumber
+            preset.carbs = presetCarbs as NSDecimalNumber
+
+            do {
+                guard moc.hasChanges else { return }
+                try moc.save()
+                showAddNewPresetSheet.toggle()
+                resetValues()
+            } catch let error as NSError {
+                debugPrint("\(DebuggingIdentifiers.failed) Failed to save Meal Preset with error: \(error.userInfo)")
+            }
+        }
+    }
 }