Ver código fonte

Improve UX with what settings are populated in root and edit views
When .onDisappear from the editPresetPopover back to root view behave the same way as .onAppear in root view when coming from home screen, that is:
- If ongoing override, populate settings with the ongoing override setting.
- If no ongoing override, populate settings with user defaults
And when entering edit by selecting edit on any override -> populate the settings in edit mode with that selected overrides settings as starting point for the edit

Refactor code based on input from @avouspierre

dsnallfot 2 anos atrás
pai
commit
ac8a51eb41

+ 94 - 1
FreeAPS/Sources/Modules/OverrideProfilesConfig/OverrideProfilesStateModel.swift

@@ -29,6 +29,24 @@ extension OverrideProfilesConfig {
 
 
         var units: GlucoseUnits = .mmolL
         var units: GlucoseUnits = .mmolL
 
 
+        private var formatter: NumberFormatter {
+            let formatter = NumberFormatter()
+            formatter.numberStyle = .decimal
+            formatter.maximumFractionDigits = 0
+            return formatter
+        }
+
+        private var glucoseFormatter: NumberFormatter {
+            let formatter = NumberFormatter()
+            formatter.numberStyle = .decimal
+            formatter.maximumFractionDigits = 0
+            if units == .mmolL {
+                formatter.maximumFractionDigits = 1
+            }
+            formatter.roundingMode = .halfUp
+            return formatter
+        }
+
         override func subscribe() {
         override func subscribe() {
             units = settingsManager.settings.units
             units = settingsManager.settings.units
             defaultSmbMinutes = settingsManager.preferences.maxSMBBasalMinutes
             defaultSmbMinutes = settingsManager.preferences.maxSMBBasalMinutes
@@ -38,6 +56,59 @@ extension OverrideProfilesConfig {
 
 
         let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
         let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
 
 
+        struct ProfileViewData {
+            let target: Decimal
+            let duration: Decimal
+            let name: String
+            let percent: Double
+            let perpetual: Bool
+            let durationString: String
+            let scheduledSMBString: String
+            let smbString: String
+            let targetString: String
+            let maxMinutesSMB: Decimal
+            let maxMinutesUAM: Decimal
+            let isfString: String
+            let crString: String
+            let isfAndCRString: String
+        }
+
+        func profileViewData(for preset: OverridePresets) -> ProfileViewData {
+            let target = units == .mmolL ? (((preset.target ?? 0) as NSDecimalNumber) as Decimal)
+                .asMmolL : (preset.target ?? 0) as Decimal
+            let duration = (preset.duration ?? 0) as Decimal
+            let name = ((preset.name ?? "") == "") || (preset.name?.isEmpty ?? true) ? "" : preset.name!
+            let percent = preset.percentage / 100
+            let perpetual = preset.indefinite
+            let durationString = perpetual ? "" : "\(formatter.string(from: duration as NSNumber)!)"
+            let scheduledSMBString = (preset.smbIsOff && preset.smbIsScheduledOff) ? "Scheduled SMBs" : ""
+            let smbString = (preset.smbIsOff && scheduledSMBString == "") ? "SMBs are off" : ""
+            let targetString = target != 0 ? "\(glucoseFormatter.string(from: target as NSNumber)!)" : ""
+            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 isfString = preset.isf ? "ISF" : ""
+            let crString = preset.cr ? "CR" : ""
+            let dash = crString != "" ? "/" : ""
+            let isfAndCRString = isfString + dash + crString
+
+            return ProfileViewData(
+                target: target,
+                duration: duration,
+                name: name,
+                percent: percent,
+                perpetual: perpetual,
+                durationString: durationString,
+                scheduledSMBString: scheduledSMBString,
+                smbString: smbString,
+                targetString: targetString,
+                maxMinutesSMB: maxMinutesSMB,
+                maxMinutesUAM: maxMinutesUAM,
+                isfString: isfString,
+                crString: crString,
+                isfAndCRString: isfAndCRString
+            )
+        }
+
         func saveSettings() {
         func saveSettings() {
             coredataContext.perform { [self] in
             coredataContext.perform { [self] in
                 let saveOverride = Override(context: self.coredataContext)
                 let saveOverride = Override(context: self.coredataContext)
@@ -167,7 +238,6 @@ extension OverrideProfilesConfig {
                 let requestEnabled = Override.fetchRequest() as NSFetchRequest<Override>
                 let requestEnabled = Override.fetchRequest() as NSFetchRequest<Override>
                 let sortIsEnabled = NSSortDescriptor(key: "date", ascending: false)
                 let sortIsEnabled = NSSortDescriptor(key: "date", ascending: false)
                 requestEnabled.sortDescriptors = [sortIsEnabled]
                 requestEnabled.sortDescriptors = [sortIsEnabled]
-                // requestEnabled.fetchLimit = 1
                 try? overrideArray = coredataContext.fetch(requestEnabled)
                 try? overrideArray = coredataContext.fetch(requestEnabled)
                 isEnabled = overrideArray.first?.enabled ?? false
                 isEnabled = overrideArray.first?.enabled ?? false
                 percentage = overrideArray.first?.percentage ?? 100
                 percentage = overrideArray.first?.percentage ?? 100
@@ -230,6 +300,29 @@ extension OverrideProfilesConfig {
             }
             }
         }
         }
 
 
+        func populateSettings(from preset: OverridePresets) {
+            profileName = preset.name ?? ""
+            percentage = preset.percentage
+            duration = (preset.duration ?? 0) as Decimal
+            _indefinite = preset.indefinite
+            override_target = preset.target != nil
+            if let targetValue = preset.target as NSDecimalNumber? {
+                target = units == .mmolL ? (targetValue as Decimal).asMmolL : targetValue as Decimal
+            } else {
+                target = 0
+            }
+            advancedSettings = preset.advancedSettings
+            smbIsOff = preset.smbIsOff
+            smbIsScheduledOff = preset.smbIsScheduledOff
+            isf = preset.isf
+            cr = preset.cr
+            smbMinutes = (preset.smbMinutes ?? 0) as Decimal
+            uamMinutes = (preset.uamMinutes ?? 0) as Decimal
+            isfAndCr = preset.isfAndCr
+            start = (preset.start ?? 0) as Decimal
+            end = (preset.end ?? 0) as Decimal
+        }
+
         func cancelProfile() {
         func cancelProfile() {
             _indefinite = true
             _indefinite = true
             isEnabled = false
             isEnabled = false

+ 19 - 56
FreeAPS/Sources/Modules/OverrideProfilesConfig/View/OverrideProfilesRootView.swift

@@ -29,6 +29,7 @@ extension OverrideProfilesConfig {
                 format: "name != %@", "" as String
                 format: "name != %@", "" as String
             )
             )
         ) var fetchedProfiles: FetchedResults<OverridePresets>
         ) var fetchedProfiles: FetchedResults<OverridePresets>
+        var units: GlucoseUnits = .mmolL
 
 
         private var formatter: NumberFormatter {
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
             let formatter = NumberFormatter()
@@ -94,6 +95,9 @@ extension OverrideProfilesConfig {
                     state.populateSettings(from: preset)
                     state.populateSettings(from: preset)
                 }
                 }
             }
             }
+            .onDisappear {
+                state.savedSettings()
+            }
         }
         }
 
 
         @ViewBuilder private func nameSection(header: String) -> some View {
         @ViewBuilder private func nameSection(header: String) -> some View {
@@ -396,43 +400,28 @@ extension OverrideProfilesConfig {
         }
         }
 
 
         @ViewBuilder private func profilesView(for preset: OverridePresets) -> some View {
         @ViewBuilder private func profilesView(for preset: OverridePresets) -> some View {
-            let target = state.units == .mmolL ? (((preset.target ?? 0) as NSDecimalNumber) as Decimal)
-                .asMmolL : (preset.target ?? 0) as Decimal
-            let duration = (preset.duration ?? 0) as Decimal
-            let name = ((preset.name ?? "") == "") || (preset.name?.isEmpty ?? true) ? "" : preset.name!
-            let percent = preset.percentage / 100
-            let perpetual = preset.indefinite
-            let durationString = perpetual ? "" : "\(formatter.string(from: duration as NSNumber)!)"
-            let scheduledSMBstring = (preset.smbIsOff && preset.smbIsScheduledOff) ? "Scheduled SMBs" : ""
-            let smbString = (preset.smbIsOff && scheduledSMBstring == "") ? "SMBs are off" : ""
-            let targetString = target != 0 ? "\(glucoseFormatter.string(from: target as NSNumber)!)" : ""
-            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 isfString = preset.isf ? "ISF" : ""
-            let crString = preset.cr ? "CR" : ""
-            let dash = crString != "" ? "/" : ""
-            let isfAndCRstring = isfString + dash + crString
+            let data = state.profileViewData(for: preset)
 
 
-            if name != "" {
+            if data.name != "" {
                 HStack {
                 HStack {
                     VStack {
                     VStack {
                         HStack {
                         HStack {
-                            Text(name)
+                            Text(data.name)
                             Spacer()
                             Spacer()
                         }
                         }
                         HStack(spacing: 5) {
                         HStack(spacing: 5) {
-                            Text(percent.formatted(.percent.grouping(.never).rounded().precision(.fractionLength(0))))
-                            if targetString != "" {
-                                Text(targetString)
-                                Text(targetString != "" ? state.units.rawValue : "")
+                            Text(data.percent.formatted(.percent.grouping(.never).rounded().precision(.fractionLength(0))))
+                            if data.targetString != "" {
+                                Text(data.targetString)
+                                Text(data.targetString != "" ? state.units.rawValue : "")
                             }
                             }
-                            if durationString != "" { Text(durationString + (perpetual ? "" : "min")) }
-                            if smbString != "" { Text(smbString).foregroundColor(.secondary).font(.caption) }
-                            if scheduledSMBstring != "" { Text(scheduledSMBstring) }
+                            if data.durationString != "" { Text(data.durationString + (data.perpetual ? "" : "min")) }
+                            if data.smbString != "" { Text(data.smbString).foregroundColor(.secondary).font(.caption) }
+                            if data.scheduledSMBString != "" { Text(data.scheduledSMBString) }
                             if preset.advancedSettings {
                             if preset.advancedSettings {
-                                Text(maxMinutesSMB == 0 ? "" : maxMinutesSMB.formatted() + " SMB")
-                                Text(maxMinutesUAM == 0 ? "" : maxMinutesUAM.formatted() + " UAM")
-                                Text(isfAndCRstring)
+                                Text(data.maxMinutesSMB == 0 ? "" : data.maxMinutesSMB.formatted() + " SMB")
+                                Text(data.maxMinutesUAM == 0 ? "" : data.maxMinutesUAM.formatted() + " UAM")
+                                Text(data.isfAndCRString)
                             }
                             }
                             Spacer()
                             Spacer()
                         }
                         }
@@ -467,10 +456,10 @@ extension OverrideProfilesConfig {
 
 
             if state.units == .mmolL {
             if state.units == .mmolL {
                 targetInStateUnits = state.target
                 targetInStateUnits = state.target
-                targetInPresetUnits = Decimal(Double(truncating: originalPreset.target ?? 0) * 0.0555)
+                targetInPresetUnits = (originalPreset.target as NSDecimalNumber?)?.decimalValue.asMmolL ?? 0
             } else {
             } else {
                 targetInStateUnits = state.target
                 targetInStateUnits = state.target
-                targetInPresetUnits = (originalPreset.target ?? 0) as Decimal
+                targetInPresetUnits = (originalPreset.target as NSDecimalNumber?)?.decimalValue ?? 0
             }
             }
 
 
             let hasChanges = state.profileName != originalPreset.name ||
             let hasChanges = state.profileName != originalPreset.name ||
@@ -479,7 +468,6 @@ extension OverrideProfilesConfig {
                 state._indefinite != originalPreset.indefinite ||
                 state._indefinite != originalPreset.indefinite ||
                 state.override_target != (originalPreset.target != nil) ||
                 state.override_target != (originalPreset.target != nil) ||
                 (state.override_target && targetInStateUnits != targetInPresetUnits) ||
                 (state.override_target && targetInStateUnits != targetInPresetUnits) ||
-                // state.advancedSettings != originalPreset.advancedSettings ||
                 state.smbIsOff != originalPreset.smbIsOff ||
                 state.smbIsOff != originalPreset.smbIsOff ||
                 state.smbIsScheduledOff != originalPreset.smbIsScheduledOff ||
                 state.smbIsScheduledOff != originalPreset.smbIsScheduledOff ||
                 state.isf != originalPreset.isf ||
                 state.isf != originalPreset.isf ||
@@ -506,28 +494,3 @@ extension OverrideProfilesConfig {
         }
         }
     }
     }
 }
 }
-
-extension OverrideProfilesConfig.StateModel {
-    func populateSettings(from preset: OverridePresets) {
-        profileName = preset.name ?? ""
-        percentage = preset.percentage
-        duration = (preset.duration ?? 0) as Decimal
-        _indefinite = preset.indefinite
-        override_target = preset.target != nil
-        if let targetValue = preset.target as Decimal? {
-            target = units == .mmolL ? Decimal(Double(truncating: targetValue as NSNumber) * 0.0555) : targetValue
-        } else {
-            target = 0
-        }
-        advancedSettings = preset.advancedSettings
-        smbIsOff = preset.smbIsOff
-        smbIsScheduledOff = preset.smbIsScheduledOff
-        isf = preset.isf
-        cr = preset.cr
-        smbMinutes = (preset.smbMinutes ?? 0) as Decimal
-        uamMinutes = (preset.uamMinutes ?? 0) as Decimal
-        isfAndCr = preset.isfAndCr
-        start = (preset.start ?? 0) as Decimal
-        end = (preset.end ?? 0) as Decimal
-    }
-}