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

fix target units when saving in `Edit Override` sheet using mmol/L, ...

don't show SMB Mins in label when SMBs are disabled,
also @dnzxy added a Help sheet,
and he updated display to format mmol/L display without glucoseFormatter

Co-Authored-By: Deniz Cengiz <48965855+dnzxy@users.noreply.github.com>
Mike Plante 1 год назад
Родитель
Сommit
1710a4a800

+ 3 - 0
FreeAPS/Sources/Modules/OverrideConfig/OverrideStateModel.swift

@@ -52,6 +52,9 @@ extension OverrideConfig {
         var hbt: Double = 160
         var didSaveSettings: Bool = false
 
+        var isHelpSheetPresented: Bool = false
+        var helpSheetDetent = PresentationDetent.large
+
         var alertMessage: String {
             let target: String = units == .mgdL ? "70-270 mg/dl" : "4-15 mmol/l"
             return "Please enter a valid target between" + " \(target)."

+ 53 - 26
FreeAPS/Sources/Modules/OverrideConfig/View/AddOverrideForm.swift

@@ -57,17 +57,6 @@ struct AddOverrideForm: View {
         return formatter
     }
 
-    private var glucoseFormatter: NumberFormatter {
-        let formatter = NumberFormatter()
-        formatter.numberStyle = .decimal
-        formatter.maximumFractionDigits = 0
-        if state.units == .mmolL {
-            formatter.maximumFractionDigits = 1
-        }
-        formatter.roundingMode = .halfUp
-        return formatter
-    }
-
     var body: some View {
         NavigationView {
             List {
@@ -89,8 +78,47 @@ struct AddOverrideForm: View {
                         Text("Cancel")
                     })
                 }
+                ToolbarItem(placement: .topBarTrailing) {
+                    Button(
+                        action: {
+                            state.isHelpSheetPresented.toggle()
+                        },
+                        label: {
+                            Image(systemName: "questionmark.circle")
+                        }
+                    )
+                }
             }
             .onAppear { targetStep = state.units == .mgdL ? 5 : 9 }
+            .sheet(isPresented: $state.isHelpSheetPresented) {
+                NavigationStack {
+                    List {
+                        Text(
+                            "Lorem Ipsum Dolor Sit Amet"
+                        )
+
+                        Text(
+                            "Lorem Ipsum Dolor Sit Amet"
+                        )
+
+                        Text(
+                            "Lorem Ipsum Dolor Sit Amet"
+                        )
+                    }
+                    .padding(.trailing, 10)
+                    .navigationBarTitle("Help", displayMode: .inline)
+
+                    Button { state.isHelpSheetPresented.toggle() }
+                    label: { Text("Got it!").frame(maxWidth: .infinity, alignment: .center) }
+                        .buttonStyle(.bordered)
+                        .padding(.top)
+                }
+                .padding()
+                .presentationDetents(
+                    [.fraction(0.9), .large],
+                    selection: $state.helpSheetDetent
+                )
+            }
         }
     }
 
@@ -238,8 +266,11 @@ struct AddOverrideForm: View {
                         HStack {
                             Text("Target Glucose")
                             Spacer()
-                            Text(formattedGlucose(glucose: state.target))
-                                .foregroundColor(!displayPickerTarget ? .primary : .accentColor)
+                            Text(
+                                (state.units == .mgdL ? state.target.description : state.target.formattedAsMmolL) + " " + state
+                                    .units.rawValue
+                            )
+                            .foregroundColor(!displayPickerTarget ? .primary : .accentColor)
                         }
                         .padding(.vertical, pad)
                         .onTapGesture {
@@ -253,9 +284,12 @@ struct AddOverrideForm: View {
                                     // Radio buttons for step iteration
                                     let stepChoices: [Decimal] = state.units == .mgdL ? [1, 5] : [1, 9]
                                     ForEach(stepChoices, id: \.self) { step in
+                                        let label = (state.units == .mgdL ? step.description : step.formattedAsMmolL) + " " +
+                                            state.units.rawValue
+
                                         RadioButton(
                                             isSelected: targetStep == step,
-                                            label: "\(state.units == .mgdL ? step : step.asMmolL) \(state.units.rawValue)"
+                                            label: label
                                         ) {
                                             targetStep = step
                                             state.target = roundTargetToStep(state.target, targetStep)
@@ -276,8 +310,11 @@ struct AddOverrideForm: View {
                                         generateTargetPickerValues(),
                                         id: \.self
                                     ) { glucose in
-                                        Text(formattedGlucose(glucose: glucose))
-                                            .tag(glucose)
+                                        Text(
+                                            (state.units == .mgdL ? glucose.description : glucose.formattedAsMmolL) + " " + state
+                                                .units.rawValue
+                                        )
+                                        .tag(glucose)
                                     }
                                 }
                                 .pickerStyle(WheelPickerStyle())
@@ -517,16 +554,6 @@ struct AddOverrideForm: View {
         return (false, nil)
     }
 
-    private func formattedGlucose(glucose: Decimal) -> String {
-        let formattedValue: String
-        if state.units == .mgdL {
-            formattedValue = glucoseFormatter.string(from: glucose as NSDecimalNumber) ?? "\(glucose)"
-        } else {
-            formattedValue = glucose.formattedAsMmolL
-        }
-        return "\(formattedValue) \(state.units.rawValue)"
-    }
-
     private func roundOverridePercentageToStep() {
         // Check if overridePercentage is not divisible by the selected step
         if state.overridePercentage.truncatingRemainder(dividingBy: Double(percentageStep)) != 0 {

+ 49 - 34
FreeAPS/Sources/Modules/OverrideConfig/View/EditOverrideForm.swift

@@ -101,17 +101,6 @@ struct EditOverrideForm: View {
         return formatter
     }
 
-    private var glucoseFormatter: NumberFormatter {
-        let formatter = NumberFormatter()
-        formatter.numberStyle = .decimal
-        formatter.maximumFractionDigits = 0
-        if state.units == .mmolL {
-            formatter.maximumFractionDigits = 1
-        }
-        formatter.roundingMode = .halfUp
-        return formatter
-    }
-
     private var percentageSelection: Binding<Double> {
         Binding<Double>(
             get: {
@@ -146,6 +135,16 @@ struct EditOverrideForm: View {
                         Text("Cancel")
                     })
                 }
+                ToolbarItem(placement: .topBarTrailing) {
+                    Button(
+                        action: {
+                            state.isHelpSheetPresented.toggle()
+                        },
+                        label: {
+                            Image(systemName: "questionmark.circle")
+                        }
+                    )
+                }
             }
             .onAppear { targetStep = state.units == .mgdL ? 5 : 9 }
             .onDisappear {
@@ -154,6 +153,35 @@ struct EditOverrideForm: View {
                     resetValues()
                 }
             }
+            .sheet(isPresented: $state.isHelpSheetPresented) {
+                NavigationStack {
+                    List {
+                        Text(
+                            "Lorem Ipsum Dolor Sit Amet"
+                        )
+
+                        Text(
+                            "Lorem Ipsum Dolor Sit Amet"
+                        )
+
+                        Text(
+                            "Lorem Ipsum Dolor Sit Amet"
+                        )
+                    }
+                    .padding(.trailing, 10)
+                    .navigationBarTitle("Help", displayMode: .inline)
+
+                    Button { state.isHelpSheetPresented.toggle() }
+                    label: { Text("Got it!").frame(maxWidth: .infinity, alignment: .center) }
+                        .buttonStyle(.bordered)
+                        .padding(.top)
+                }
+                .padding()
+                .presentationDetents(
+                    [.fraction(0.9), .large],
+                    selection: $state.helpSheetDetent
+                )
+            }
         }
     }
 
@@ -332,7 +360,6 @@ struct EditOverrideForm: View {
                             set: { target = $0 }
                         ),
                         options: generateTargetPickerValues(),
-                        formatter: { formattedGlucose(glucose: $0) },
                         units: state.units,
                         hasChanges: $hasChanges,
                         targetStep: $targetStep
@@ -590,16 +617,6 @@ struct EditOverrideForm: View {
         return (false, nil)
     }
 
-    private func formattedGlucose(glucose: Decimal) -> String {
-        let formattedValue: String
-        if state.units == .mgdL {
-            formattedValue = glucoseFormatter.string(from: glucose as NSDecimalNumber) ?? "\(glucose)"
-        } else {
-            formattedValue = glucose.formattedAsMmolL
-        }
-        return "\(formattedValue) \(state.units.rawValue)"
-    }
-
     private func saveChanges() {
         if !override.isPreset, hasChanges, name == (override.name ?? "") {
             override.name = "Custom Override"
@@ -609,13 +626,7 @@ struct EditOverrideForm: View {
         override.percentage = percentage
         override.indefinite = indefinite
         override.duration = NSDecimalNumber(decimal: duration)
-        if target_override {
-            override.target = target.map {
-                state.units == .mmolL ? NSDecimalNumber(decimal: $0.asMgdL) : NSDecimalNumber(decimal: $0)
-            }
-        } else {
-            override.target = 0
-        }
+        override.target = NSDecimalNumber(decimal: target ?? 100)
         override.advancedSettings = advancedSettings
         override.smbIsOff = smbIsOff
         override.smbIsScheduledOff = smbIsScheduledOff
@@ -726,7 +737,6 @@ struct TargetPicker: View {
     let label: String
     @Binding var selection: Decimal
     let options: [Decimal]
-    let formatter: (Decimal) -> String
     let units: GlucoseUnits
     @Binding var hasChanges: Bool
     @Binding var targetStep: Decimal
@@ -737,8 +747,10 @@ struct TargetPicker: View {
             HStack {
                 Text(label)
                 Spacer()
-                Text(formatter(selection))
-                    .foregroundColor(!isDisplayed ? .primary : .accentColor)
+                Text(
+                    (units == .mgdL ? selection.description : selection.formattedAsMmolL) + " " + units.rawValue
+                )
+                .foregroundColor(!isDisplayed ? .primary : .accentColor)
             }
             .onTapGesture {
                 isDisplayed.toggle()
@@ -750,9 +762,11 @@ struct TargetPicker: View {
                         // Radio buttons for step iteration
                         let stepChoices: [Decimal] = units == .mgdL ? [1, 5] : [1, 9]
                         ForEach(stepChoices, id: \.self) { step in
+                            let label = (units == .mgdL ? step.description : step.formattedAsMmolL) + " " +
+                                units.rawValue
                             RadioButton(
                                 isSelected: targetStep == step,
-                                label: "\(units == .mgdL ? step : step.asMmolL) \(units.rawValue)"
+                                label: label
                             ) {
                                 targetStep = step
                                 selection = roundTargetToStep(selection, step)
@@ -773,7 +787,8 @@ struct TargetPicker: View {
                         }
                     ), label: Text("")) {
                         ForEach(options, id: \.self) { option in
-                            Text(formatter(option)).tag(option)
+                            Text((units == .mgdL ? option.description : option.formattedAsMmolL) + " " + units.rawValue)
+                                .tag(option)
                         }
                     }
                     .pickerStyle(WheelPickerStyle())

+ 8 - 2
FreeAPS/Sources/Modules/OverrideConfig/View/OverrideRootView.swift

@@ -507,9 +507,15 @@ extension OverrideConfig {
             let targetString = target != 0 ? "\(target.description) \(state.units.rawValue)" : ""
             let maxMinutesSMB = (preset.smbMinutes as Decimal?) != nil ? (preset.smbMinutes ?? 0) as Decimal : 0
             let maxMinutesUAM = (preset.uamMinutes as Decimal?) != nil ? (preset.uamMinutes ?? 0) as Decimal : 0
-            let maxSmbMinsString = (maxMinutesSMB != 0 && preset.advancedSettings && maxMinutesSMB != state.defaultSmbMinutes) ?
+            let maxSmbMinsString = (
+                maxMinutesSMB != 0 && preset.advancedSettings && !preset.smbIsOff && maxMinutesSMB != state
+                    .defaultSmbMinutes
+            ) ?
                 "\(maxMinutesSMB.formatted()) min SMB" : ""
-            let maxUamMinsString = (maxMinutesUAM != 0 && preset.advancedSettings && maxMinutesUAM != state.defaultUamMinutes) ?
+            let maxUamMinsString = (
+                maxMinutesUAM != 0 && preset.advancedSettings && !preset.smbIsOff && maxMinutesUAM != state
+                    .defaultUamMinutes
+            ) ?
                 "\(maxMinutesUAM.formatted()) min UAM" : ""
             let isfAndCRstring: String = {
                 switch (preset.isfAndCr, preset.isf, preset.cr) {