polscm32 2 лет назад
Родитель
Сommit
23e1879538

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

@@ -59,7 +59,7 @@ extension AddCarbs {
                 showModal(for: nil)
             } else if carbs > 0 {
                 saveToCoreData(carbsToStore)
-                showModal(for: .bolus(waitForSuggestion: true, fetch: true))
+//                showModal(for: .bolus(waitForSuggestion: true, fetch: true))
             } else {
                 hideModal()
             }

+ 202 - 2
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -1,3 +1,5 @@
+import CoreData
+import Foundation
 import LoopKit
 import SwiftUI
 import Swinject
@@ -11,6 +13,7 @@ extension Bolus {
         // added for bolus calculator
         @Injected() var settings: SettingsManager!
         @Injected() var nsManager: NightscoutManager!
+        @Injected() var carbsStorage: CarbsStorage!
 
         @Published var suggestion: Suggestion?
         @Published var predictions: Predictions?
@@ -70,6 +73,25 @@ extension Bolus {
         @Published var protein: Decimal = 0
         @Published var note: String = ""
 
+        // @Published var carbs: Decimal = 0
+        @Published var date = Date()
+        // @Published var protein: Decimal = 0
+        // @Published var fat: Decimal = 0
+        @Published var carbsRequired: Decimal?
+        @Published var useFPUconversion: Bool = false
+        @Published var dish: String = ""
+        @Published var selection: Presets?
+        @Published var summation: [String] = []
+        @Published var maxCarbs: Decimal = 0
+        // @Published var note: String = ""
+        @Published var id_: String = ""
+        @Published var summary: String = ""
+        @Published var skipBolus: Bool = false
+
+        let now = Date.now
+
+        let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
+
         override func subscribe() {
             setupInsulinRequired()
             broadcaster.register(SuggestionObserver.self, observer: self)
@@ -86,6 +108,11 @@ extension Bolus {
             sweetMealFactor = settings.settings.sweetMealFactor
             displayPredictions = settings.settings.displayPredictions
 
+            carbsRequired = provider.suggestion?.carbsReq
+            maxCarbs = settings.settings.maxCarbs
+            skipBolus = settingsManager.settings.skipBolusScreenAfterCarbs
+            useFPUconversion = settingsManager.settings.useFPUconversion
+
             if waitForSuggestionInitial {
                 apsManager.determineBasal()
                     .receive(on: DispatchQueue.main)
@@ -265,9 +292,9 @@ extension Bolus {
             }
         }
 
-        func backToCarbsView(complexEntry: Bool, _ meal: FetchedResults<Meals>, override: Bool) {
+        func backToCarbsView(complexEntry: Bool, _ meal: FetchedResults<Meals>, override _: Bool) {
             delete(deleteTwice: complexEntry, meal: meal)
-            showModal(for: .addCarbs(editMode: complexEntry, override: override))
+            // showModal(for: .addCarbs(editMode: complexEntry, override: override))
         }
 
         func delete(deleteTwice: Bool, meal: FetchedResults<Meals>) {
@@ -303,6 +330,179 @@ extension Bolus {
                 nsManager.deleteCarbs(mealArray, complexMeal: false)
             }
         }
+
+        func addCarbs(_ continue_: Bool, fetch: Bool) {
+            guard carbs > 0 || fat > 0 || protein > 0 else { return }
+            carbs = min(carbs, maxCarbs)
+            id_ = UUID().uuidString
+
+            let carbsToStore = [CarbsEntry(
+                id: id_,
+                createdAt: now,
+                actualDate: date,
+                carbs: carbs,
+                fat: fat,
+                protein: protein,
+                note: note,
+                enteredBy: CarbsEntry.manual,
+                isFPU: false, fpuID: UUID().uuidString
+            )]
+            carbsStorage.storeCarbs(carbsToStore)
+
+            if skipBolus, !continue_, !fetch {
+                apsManager.determineBasalSync()
+                showModal(for: nil)
+            } else if carbs > 0 {
+                saveToCoreData(carbsToStore)
+                apsManager.determineBasalSync()
+                // showModal(for: .bolus(waitForSuggestion: true, fetch: true, editMode: false, override: false))
+            } else {
+                hideModal()
+            }
+        }
+
+        func deletePreset() {
+            if selection != nil {
+                try? coredataContext.delete(selection!)
+                try? coredataContext.save()
+                carbs = 0
+                fat = 0
+                protein = 0
+            }
+            selection = nil
+        }
+
+        func removePresetFromNewMeal() {
+            let a = summation.firstIndex(where: { $0 == selection?.dish! })
+            if a != nil, summation[a ?? 0] != "" {
+                summation.remove(at: a!)
+            }
+        }
+
+        func addPresetToNewMeal() {
+            let test: String = selection?.dish ?? "dontAdd"
+            if test != "dontAdd" {
+                summation.append(test)
+            }
+        }
+
+        func addNewPresetToWaitersNotepad(_ dish: String) {
+            summation.append(dish)
+        }
+
+        func addToSummation() {
+            summation.append(selection?.dish ?? "")
+        }
+
+        func waitersNotepad() -> String {
+            var filteredArray = summation.filter { !$0.isEmpty }
+
+            if carbs == 0, protein == 0, fat == 0 {
+                filteredArray = []
+            }
+
+            guard filteredArray != [] else {
+                return ""
+            }
+            var carbs_: Decimal = 0.0
+            var fat_: Decimal = 0.0
+            var protein_: Decimal = 0.0
+            var presetArray = [Presets]()
+
+            coredataContext.performAndWait {
+                let requestPresets = Presets.fetchRequest() as NSFetchRequest<Presets>
+                try? presetArray = coredataContext.fetch(requestPresets)
+            }
+            var waitersNotepad = [String]()
+            var stringValue = ""
+
+            for each in filteredArray {
+                let countedSet = NSCountedSet(array: filteredArray)
+                let count = countedSet.count(for: each)
+                if each != stringValue {
+                    waitersNotepad.append("\(count) \(each)")
+                }
+                stringValue = each
+
+                for sel in presetArray {
+                    if sel.dish == each {
+                        carbs_ += (sel.carbs)! as Decimal
+                        fat_ += (sel.fat)! as Decimal
+                        protein_ += (sel.protein)! as Decimal
+                        break
+                    }
+                }
+            }
+            let extracarbs = carbs - carbs_
+            let extraFat = fat - fat_
+            let extraProtein = protein - protein_
+            var addedString = ""
+
+            if extracarbs > 0, filteredArray.isNotEmpty {
+                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) ," }
+
+            if extraProtein > 0, filteredArray.isNotEmpty {
+                addedString += "Additional protein: \(extraProtein) ,"
+            } else if extraProtein < 0 { addedString += "Removed protein: \(extraProtein) ," }
+
+            if addedString != "" {
+                waitersNotepad.append(addedString)
+            }
+            var waitersNotepadString = ""
+
+            if waitersNotepad.count == 1 {
+                waitersNotepadString = waitersNotepad[0]
+            } else if waitersNotepad.count > 1 {
+                for each in waitersNotepad {
+                    if each != waitersNotepad.last {
+                        waitersNotepadString += " " + each + ","
+                    } else { waitersNotepadString += " " + each }
+                }
+            }
+            return waitersNotepadString
+        }
+
+        func loadEntries(_ editMode: Bool) {
+            if editMode {
+                coredataContext.performAndWait {
+                    var mealToEdit = [Meals]()
+                    let requestMeal = Meals.fetchRequest() as NSFetchRequest<Meals>
+                    let sortMeal = NSSortDescriptor(key: "createdAt", ascending: false)
+                    requestMeal.sortDescriptors = [sortMeal]
+                    requestMeal.fetchLimit = 1
+                    try? mealToEdit = self.coredataContext.fetch(requestMeal)
+
+                    self.carbs = Decimal(mealToEdit.first?.carbs ?? 0)
+                    self.fat = Decimal(mealToEdit.first?.fat ?? 0)
+                    self.protein = Decimal(mealToEdit.first?.protein ?? 0)
+                    self.note = mealToEdit.first?.note ?? ""
+                    self.id_ = mealToEdit.first?.id ?? ""
+                }
+            }
+        }
+
+        func saveToCoreData(_ stored: [CarbsEntry]) {
+            coredataContext.performAndWait {
+                let save = Meals(context: coredataContext)
+                if let entry = stored.first {
+                    save.createdAt = now
+                    save.actualDate = entry.actualDate ?? Date.now
+                    save.id = entry.id ?? ""
+                    save.fpuID = entry.fpuID ?? ""
+                    save.carbs = Double(entry.carbs)
+                    save.fat = Double(entry.fat ?? 0)
+                    save.protein = Double(entry.protein ?? 0)
+                    save.note = entry.note
+                    try? coredataContext.save()
+                }
+                print("meals 1: ID: " + (save.id ?? "").description + " FPU ID: " + (save.fpuID ?? "").description)
+            }
+        }
     }
 }
 

+ 215 - 53
FreeAPS/Sources/Modules/Bolus/View/AlternativeBolusCalcRootView.swift

@@ -8,19 +8,35 @@ extension Bolus {
         let resolver: Resolver
         let waitForSuggestion: Bool
         let fetch: Bool
+        let editMode: Bool
+        let override: Bool
         @StateObject var state: StateModel
         @State private var showInfo = false
         @State private var exceededMaxBolus = false
         @State private var keepForNextWiew: Bool = false
         @State private var calculatorDetent = PresentationDetent.medium
+        @State var pushed = false
+        @State var isPromptPresented = false
+        @State var dish: String = ""
+        @State var saved = false
+        @State private var treatmentsViewMode: TreatmentsViewMode = .calcMode
+
+        @FocusState private var isFocused: Bool
 
         @ObservedObject var appState: AppState
 
+        @Environment(\.managedObjectContext) var moc
+
         private enum Config {
             static let dividerHeight: CGFloat = 2
             static let spacing: CGFloat = 3
         }
 
+        private enum TreatmentsViewMode {
+            case editMode
+            case calcMode
+        }
+
         @Environment(\.colorScheme) var colorScheme
 
         @FetchRequest(
@@ -74,15 +90,169 @@ extension Bolus {
                 )
         }
 
+        private var empty: Bool {
+            state.carbs <= 0 && state.fat <= 0 && state.protein <= 0
+        }
+
+        private var presetPopover: some View {
+            Form {
+                Section {
+                    TextField("Name Of Dish", text: $dish)
+                    Button {
+                        saved = true
+                        if dish != "", saved {
+                            let preset = Presets(context: moc)
+                            preset.dish = dish
+                            preset.fat = state.fat as NSDecimalNumber
+                            preset.protein = state.protein as NSDecimalNumber
+                            preset.carbs = state.carbs as NSDecimalNumber
+                            try? moc.save()
+                            state.addNewPresetToWaitersNotepad(dish)
+                            saved = false
+                            isPromptPresented = false
+                        }
+                    }
+                    label: { Text("Save") }
+                    Button {
+                        dish = ""
+                        saved = false
+                        isPromptPresented = false }
+                    label: { Text("Cancel") }
+                } header: { Text("Enter Meal Preset Name") }
+            }
+        }
+
+        @ViewBuilder private func proteinAndFat() -> some View {
+            HStack {
+                Text("Fat").foregroundColor(.orange)
+                Spacer()
+                DecimalTextField(
+                    "0",
+                    value: $state.fat,
+                    formatter: formatter,
+                    autofocus: false,
+                    cleanInput: true
+                )
+                Text("g").foregroundColor(.secondary)
+            }
+            HStack {
+                Text("Protein").foregroundColor(.red)
+                Spacer()
+                DecimalTextField(
+                    "0",
+                    value: $state.protein,
+                    formatter: formatter,
+                    autofocus: false,
+                    cleanInput: true
+                ).foregroundColor(.loopRed)
+
+                Text("g").foregroundColor(.secondary)
+            }
+        }
+
         var body: some View {
             Form {
+                // MARK: ADDED
+
                 Section {
-                    if state.waitForSuggestion {
-                        Text("Please wait")
-                    } else {
-                        predictionChart
+                    HStack {
+                        Text("Carbs").fontWeight(.semibold)
+                        Spacer()
+                        DecimalTextField(
+                            "0",
+                            value: $state.carbs,
+                            formatter: formatter,
+                            autofocus: true,
+                            cleanInput: true
+                        )
+                        Text("g").foregroundColor(.secondary)
+                    }
+
+                    if state.useFPUconversion {
+                        proteinAndFat()
                     }
-                } header: { Text("Predictions") }.listRowBackground(Color.chart)
+
+                    // Summary when combining presets
+                    if state.waitersNotepad() != "" {
+                        HStack {
+                            Text("Total")
+                            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 {
+                        Text("Time").foregroundStyle(Color.secondary)
+                        Spacer()
+                        if !pushed {
+                            Button {
+                                pushed = true
+                            } label: { Text("Now") }.buttonStyle(.borderless).foregroundColor(.secondary).padding(.trailing, 5)
+                        } else {
+                            Button { state.date = state.date.addingTimeInterval(-15.minutes.timeInterval) }
+                            label: { Image(systemName: "minus.circle") }.tint(.blue).buttonStyle(.borderless)
+                            DatePicker(
+                                "Time",
+                                selection: $state.date,
+                                displayedComponents: [.hourAndMinute]
+                            ).controlSize(.mini)
+                                .labelsHidden()
+                            Button {
+                                state.date = state.date.addingTimeInterval(15.minutes.timeInterval)
+                            }
+                            label: { Image(systemName: "plus.circle") }.tint(.blue).buttonStyle(.borderless)
+                        }
+                    }
+
+                    // Optional meal note
+                    //                    HStack {
+                    //                        Image(systemName: "note.text.badge.plus").foregroundColor(.secondary)
+                    //                        TextField("", text: $state.note).multilineTextAlignment(.trailing)
+                    //                        if state.note != "", isFocused {
+                    //                            Button { isFocused = false } label: { Image(systemName: "keyboard.chevron.compact.down") }
+                    //                                .controlSize(.mini)
+                    //                        }
+                    //                    }
+                    //                    .focused($isFocused)
+                    //                    .popover(isPresented: $isPromptPresented) {
+                    //                        presetPopover
+                    //                    }
+
+                    HStack {
+                        Spacer()
+                        Button {
+                            if treatmentsViewMode == .calcMode {
+                                state.addCarbs(override, fetch: editMode)
+                                treatmentsViewMode = .editMode
+                            } else {
+                                state.backToCarbsView(complexEntry: true, meal, override: false)
+                                treatmentsViewMode = .calcMode
+                            }
+                        }
+                        label: {
+                            // Text((state.skipBolus && !override && !editMode) ? "Save" : "Calculate Bolus")
+                            // if carbs > 0 and it is the first entry then go into edit mode
+                            // conditionally change text to 'edit meal'
+                            // Text(!editMode ? "Calculate" : "Edit Meal")
+                            if treatmentsViewMode == .calcMode {
+                                Text("Calculate")
+                            } else {
+                                Text("Edit meal")
+                            }
+                        }
+                        .disabled(empty)
+
+                        Spacer()
+                    }
+                } header: { Text("Carbs") }.listRowBackground(Color.chart)
+
+                // MARK: ADDING END
 
                 if fetch {
                     Section {
@@ -102,31 +272,36 @@ extension Bolus {
                             .font(.footnote)
                             .buttonStyle(PlainButtonStyle())
                             .frame(maxWidth: .infinity, alignment: .leading)
-                        if state.fattyMeals {
-                            Spacer()
-                            Toggle(isOn: $state.useFattyMealCorrectionFactor) {
-                                Text("Fatty Meal")
-                            }
-                            .toggleStyle(CheckboxToggleStyle())
-                            .font(.footnote)
-                            .onChange(of: state.useFattyMealCorrectionFactor) { _ in
-                                state.insulinCalculated = state.calculateInsulin()
-                                if state.useFattyMealCorrectionFactor {
-                                    state.useSuperBolus = false
+                    }
+
+                    if state.sweetMeals || state.fattyMeals {
+                        HStack {
+                            if state.fattyMeals {
+                                Spacer()
+                                Toggle(isOn: $state.useFattyMealCorrectionFactor) {
+                                    Text("Fatty Meal")
+                                }
+                                .toggleStyle(CheckboxToggleStyle())
+                                .font(.footnote)
+                                .onChange(of: state.useFattyMealCorrectionFactor) { _ in
+                                    state.insulinCalculated = state.calculateInsulin()
+                                    if state.useFattyMealCorrectionFactor {
+                                        state.useSuperBolus = false
+                                    }
                                 }
                             }
-                        }
-                        if state.sweetMeals {
-                            Spacer()
-                            Toggle(isOn: $state.useSuperBolus) {
-                                Text("Super Bolus")
-                            }
-                            .toggleStyle(CheckboxToggleStyle())
-                            .font(.footnote)
-                            .onChange(of: state.useSuperBolus) { _ in
-                                state.insulinCalculated = state.calculateInsulin()
-                                if state.useSuperBolus {
-                                    state.useFattyMealCorrectionFactor = false
+                            if state.sweetMeals {
+                                Spacer()
+                                Toggle(isOn: $state.useSuperBolus) {
+                                    Text("Super Bolus")
+                                }
+                                .toggleStyle(CheckboxToggleStyle())
+                                .font(.footnote)
+                                .onChange(of: state.useSuperBolus) { _ in
+                                    state.insulinCalculated = state.calculateInsulin()
+                                    if state.useSuperBolus {
+                                        state.useFattyMealCorrectionFactor = false
+                                    }
                                 }
                             }
                         }
@@ -180,8 +355,7 @@ extension Bolus {
                         Button {
                             keepForNextWiew = true
                             state.add()
-                            state.hideModal()
-//                            appState.currentTab = .home
+                            appState.currentTab = .home
                         }
                         label: { Text(exceededMaxBolus ? "Max Bolus exceeded!" : "Enact bolus") }
                             .frame(maxWidth: .infinity, alignment: .center)
@@ -194,44 +368,32 @@ extension Bolus {
                     Section {
                         Button {
                             keepForNextWiew = true
-                            state.hideModal()
-//                            appState.currentTab = .home
+                            appState.currentTab = .home
                         }
                         label: { Text("Continue without bolus") }.frame(maxWidth: .infinity, alignment: .center)
                     }.listRowBackground(Color.chart)
                 }
             }.scrollContentBackground(.hidden).background(color)
                 .blur(radius: showInfo ? 3 : 0)
-                .navigationTitle("Enact Bolus")
-                .navigationBarTitleDisplayMode(.inline)
-                .toolbar {
+                .navigationTitle("Treatments")
+                .navigationBarTitleDisplayMode(.large)
+                .toolbar(content: {
                     ToolbarItem(placement: .topBarLeading) {
-                        if fetch {
-                            Button {
-                                keepForNextWiew = true
-                                state.backToCarbsView(complexEntry: true, meal, override: false)
-                            } label: {
-                                HStack {
-                                    Image(systemName: "chevron.backward")
-                                    Text("Meal")
-                                }
-                            }
-                        } else {
-                            Button {
-                                state.hideModal()
-                            } label: {
-                                Text("Close")
-                            }
+                        Button {
+                            state.hideModal()
+                        } label: {
+                            Text("Close")
                         }
                     }
-                }
-
+                })
                 .onAppear {
                     configureView {
                         state.waitForSuggestionInitial = waitForSuggestion
                         state.waitForSuggestion = waitForSuggestion
                         state.insulinCalculated = state.calculateInsulin()
                     }
+                    state.carbs = 0
+                    treatmentsViewMode = .calcMode
                 }
                 .onDisappear {
                     if fetch, hasFatOrProtein, !keepForNextWiew, state.useCalc {

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

@@ -2,10 +2,12 @@ import SwiftUI
 import Swinject
 
 extension Bolus {
-    struct RootView: BaseView {
+    struct RootView: View {
         let resolver: Resolver
         let waitForSuggestion: Bool
         let fetch: Bool
+        let editMode: Bool
+        let override: Bool
         @StateObject var state = StateModel()
         @ObservedObject var appState = AppState()
 
@@ -16,6 +18,8 @@ extension Bolus {
                     resolver: resolver,
                     waitForSuggestion: waitForSuggestion,
                     fetch: fetch,
+                    editMode: editMode,
+                    override: override,
                     state: state,
                     appState: appState
                 )

+ 116 - 112
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -13,6 +13,7 @@ extension Home {
         @State var isStatusPopupPresented = false
         @State var showCancelAlert = false
         @State var isMenuPresented = false
+        @State var showTreatments = false
         @State var selectedTab: Int = 0
         @State var currentTab: Tab
 
@@ -389,111 +390,111 @@ extension Home {
             }
         }
 
-        @ViewBuilder private func bottomPanel(_: GeometryProxy) -> some View {
-            let colorIcon: Color = (colorScheme == .dark ? Color.white : Color.black).opacity(0.9)
-
-            ZStack {
-                Rectangle()
-                    .fill(Color("Chart"))
-                    .frame(height: UIScreen.main.bounds.height / 13)
-                    .cornerRadius(15)
-                    .shadow(
-                        color: colorScheme == .dark ? Color(red: 0.02745098039, green: 0.1098039216, blue: 0.1411764706) : Color
-                            .black.opacity(0.33),
-                        radius: 3
-                    )
-                    .padding([.leading, .trailing], 10)
-
-                HStack {
-                    Button {
-                        state.showModal(for: .dataTable)
-                    }
-                    label: {
-                        if #available(iOS 17.0, *) {
-                            Image(systemName: "book.pages")
-                                .font(.system(size: 24))
-                                .foregroundColor(colorIcon)
-                                .padding(8)
-                        } else {
-                            Image(systemName: "book")
-                                .font(.system(size: 24))
-                                .foregroundColor(colorIcon)
-                                .padding(8)
-                        }
-                    }
-                    .foregroundColor(colorIcon)
-                    .buttonStyle(.borderless)
-                    Spacer()
-                    Button { state.showModal(for: .addCarbs(editMode: false, override: false)) }
-                    label: {
-                        ZStack(alignment: Alignment(horizontal: .trailing, vertical: .bottom)) {
-                            Image(systemName: "fork.knife")
-                                .font(.system(size: 24))
-                                .foregroundColor(colorIcon)
-                                .padding(8)
-                            if let carbsReq = state.carbsRequired {
-                                Text(numberFormatter.string(from: carbsReq as NSNumber)!)
-                                    .font(.caption)
-                                    .foregroundColor(.white)
-                                    .padding(4)
-                                    .background(Capsule().fill(Color.red))
-                            }
-                        }
-                    }.buttonStyle(.borderless)
-                    Spacer()
-                    Button {
-                        state.showModal(for: .bolus(
-                            waitForSuggestion: true,
-                            fetch: false
-                        ))
-                    }
-                    label: {
-                        Image(systemName: "syringe.fill")
-                            .font(.system(size: 24))
-                            .foregroundColor(colorIcon)
-                            .padding(8)
-                    }
-                    .foregroundColor(colorIcon)
-                    .buttonStyle(.borderless)
-                    Spacer()
-                    if state.allowManualTemp {
-                        Button { state.showModal(for: .manualTempBasal) }
-                        label: {
-                            Image("bolus1")
-                                .renderingMode(.template)
-                                .resizable()
-                                .frame(width: 24, height: 24)
-                                .padding(8)
-                        }
-                        .foregroundColor(colorIcon)
-                        .buttonStyle(.borderless)
-                        Spacer()
-                    }
-                    let isOverrideActive = fetchedPercent.first?.enabled ?? false
-                    Button {
-                        state.showModal(for: .overrideProfilesConfig)
-                    } label: {
-                        Image(systemName: (state.isTempTargetActive || isOverrideActive) ? "person.fill" : "person")
-                            .font(.system(size: 26))
-                            .padding(8)
-                    }
-                    .foregroundColor((state.isTempTargetActive || isOverrideActive) ? Color.purple : colorIcon)
-                    .buttonStyle(.borderless)
-                    Spacer()
-                    Button {
-                        state.showModal(for: .settings)
-                    } label: {
-                        Image(systemName: "gear")
-                            .font(.system(size: 26))
-                            .padding(8)
-                    }
-                    .foregroundColor(colorIcon)
-                    .buttonStyle(.borderless)
-                }
-                .padding(.horizontal, 24)
-                .padding(.bottom, 16)
-            }
-        }
+//        @ViewBuilder private func bottomPanel(_: GeometryProxy) -> some View {
+//            let colorIcon: Color = (colorScheme == .dark ? Color.white : Color.black).opacity(0.9)
+//
+//            ZStack {
+//                Rectangle()
+//                    .fill(Color("Chart"))
+//                    .frame(height: UIScreen.main.bounds.height / 13)
+//                    .cornerRadius(15)
+//                    .shadow(
+//                        color: colorScheme == .dark ? Color(red: 0.02745098039, green: 0.1098039216, blue: 0.1411764706) : Color
+//                            .black.opacity(0.33),
+//                        radius: 3
+//                    )
+//                    .padding([.leading, .trailing], 10)
+//
+//                HStack {
+//                    Button {
+//                        state.showModal(for: .dataTable)
+//                    }
+//                    label: {
+//                        if #available(iOS 17.0, *) {
+//                            Image(systemName: "book.pages")
+//                                .font(.system(size: 24))
+//                                .foregroundColor(colorIcon)
+//                                .padding(8)
+//                        } else {
+//                            Image(systemName: "book")
+//                                .font(.system(size: 24))
+//                                .foregroundColor(colorIcon)
+//                                .padding(8)
+//                        }
+//                    }
+//                    .foregroundColor(colorIcon)
+//                    .buttonStyle(.borderless)
+//                    Spacer()
+//                    Button { state.showModal(for: .addCarbs(editMode: false, override: false)) }
+//                    label: {
+//                        ZStack(alignment: Alignment(horizontal: .trailing, vertical: .bottom)) {
+//                            Image(systemName: "fork.knife")
+//                                .font(.system(size: 24))
+//                                .foregroundColor(colorIcon)
+//                                .padding(8)
+//                            if let carbsReq = state.carbsRequired {
+//                                Text(numberFormatter.string(from: carbsReq as NSNumber)!)
+//                                    .font(.caption)
+//                                    .foregroundColor(.white)
+//                                    .padding(4)
+//                                    .background(Capsule().fill(Color.red))
+//                            }
+//                        }
+//                    }.buttonStyle(.borderless)
+//                    Spacer()
+//                    Button {
+//                        state.showModal(for: .bolus(
+//                            waitForSuggestion: true,
+//                            fetch: false
+//                        ))
+//                    }
+//                    label: {
+//                        Image(systemName: "syringe.fill")
+//                            .font(.system(size: 24))
+//                            .foregroundColor(colorIcon)
+//                            .padding(8)
+//                    }
+//                    .foregroundColor(colorIcon)
+//                    .buttonStyle(.borderless)
+//                    Spacer()
+//                    if state.allowManualTemp {
+//                        Button { state.showModal(for: .manualTempBasal) }
+//                        label: {
+//                            Image("bolus1")
+//                                .renderingMode(.template)
+//                                .resizable()
+//                                .frame(width: 24, height: 24)
+//                                .padding(8)
+//                        }
+//                        .foregroundColor(colorIcon)
+//                        .buttonStyle(.borderless)
+//                        Spacer()
+//                    }
+//                    let isOverrideActive = fetchedPercent.first?.enabled ?? false
+//                    Button {
+//                        state.showModal(for: .overrideProfilesConfig)
+//                    } label: {
+//                        Image(systemName: (state.isTempTargetActive || isOverrideActive) ? "person.fill" : "person")
+//                            .font(.system(size: 26))
+//                            .padding(8)
+//                    }
+//                    .foregroundColor((state.isTempTargetActive || isOverrideActive) ? Color.purple : colorIcon)
+//                    .buttonStyle(.borderless)
+//                    Spacer()
+//                    Button {
+//                        state.showModal(for: .settings)
+//                    } label: {
+//                        Image(systemName: "gear")
+//                            .font(.system(size: 26))
+//                            .padding(8)
+//                    }
+//                    .foregroundColor(colorIcon)
+//                    .buttonStyle(.borderless)
+//                }
+//                .padding(.horizontal, 24)
+//                .padding(.bottom, 16)
+//            }
+//        }
 
         @ViewBuilder func bolusProgressBar(_ progress: Decimal) -> some View {
             GeometryReader { geo in
@@ -956,8 +957,7 @@ extension Home {
                     .tabItem { Label("History", systemImage: historySFSymbol) }
                     .tag(Tab.history)
 
-//                Spacer()
-//                TreatmentsView().tabItem { Label("Treatmens", systemImage: "plus") }.tag(Tab.treatments)
+                Spacer()
 
                 NavigationStack { OverrideProfilesConfig.RootView(resolver: resolver) }
                     .tabItem {
@@ -976,11 +976,15 @@ extension Home {
                     .tag(Tab.settings)
             }
             .tint(Color.tabBar)
-//            .overlay(alignment: .bottom) {
-//                Button(action: { state.showModal(for: .bolus(waitForSuggestion: false, fetch: false)) }, label: {
-//                    Image(systemName: "plus.circle.fill").font(.system(size: 40)).foregroundStyle(Color.gray.opacity(0.9))
-//                })
-//            }
+            .overlay(alignment: .bottom) {
+                Button(
+                    action: {
+                        state.showModal(for: .bolus(waitForSuggestion: false, fetch: false, editMode: false, override: false)) },
+                    label: {
+                        Image(systemName: "plus.circle.fill").font(.system(size: 40)).foregroundStyle(Color.gray.opacity(0.9))
+                    }
+                ).padding(.bottom, 2)
+            }
         }
 
         var body: some View {

+ 9 - 3
FreeAPS/Sources/Router/Screen.swift

@@ -16,7 +16,7 @@ enum Screen: Identifiable, Hashable {
     case preferencesEditor
     case addCarbs(editMode: Bool, override: Bool)
     case addTempTarget
-    case bolus(waitForSuggestion: Bool, fetch: Bool)
+    case bolus(waitForSuggestion: Bool, fetch: Bool, editMode: Bool, override: Bool)
     case manualTempBasal
     case autotuneConfig
     case dataTable
@@ -69,8 +69,14 @@ extension Screen {
             AddCarbs.RootView(resolver: resolver, editMode: editMode, override: override)
         case .addTempTarget:
             AddTempTarget.RootView(resolver: resolver)
-        case let .bolus(waitForSuggestion, fetch):
-            Bolus.RootView(resolver: resolver, waitForSuggestion: waitForSuggestion, fetch: fetch)
+        case let .bolus(waitForSuggestion, fetch, editMode, override):
+            Bolus.RootView(
+                resolver: resolver,
+                waitForSuggestion: waitForSuggestion,
+                fetch: fetch,
+                editMode: editMode,
+                override: override
+            )
         case .manualTempBasal:
             ManualTempBasal.RootView(resolver: resolver)
         case .autotuneConfig: