Kaynağa Gözat

Merge pull request #475 from nightscout/onboarding-fixes

Onboarding Fixes, Part 3
Sam King 1 yıl önce
ebeveyn
işleme
8722516489

+ 4 - 0
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -142050,7 +142050,11 @@
         }
       }
     },
+    "Medtronic and Dana Users Only" : {
+
+    },
     "Medtronic Users Only" : {
+      "extractionState" : "stale",
       "localizations" : {
         "bg" : {
           "stringUnit" : {

+ 1 - 1
Trio/Sources/Modules/AutosensSettings/View/AutosensSettingsRootView.swift

@@ -204,7 +204,7 @@ extension AutosensSettings {
                     miniHint: String(localized: "Pump rewind initiates a reset in Sensitivity Ratio."),
                     verboseHint: VStack(alignment: .leading, spacing: 5) {
                         Text("Default: ON").bold()
-                        Text("Medtronic Users Only").bold()
+                        Text("Medtronic and Dana Users Only").bold()
                         VStack(alignment: .leading, spacing: 10) {
                             Text(
                                 "This feature resets the Sensitivity Ratio to neutral when you rewind your pump on the assumption that this corresponds to a site change."

+ 53 - 0
Trio/Sources/Modules/Onboarding/OnboardingStateModel.swift

@@ -106,9 +106,20 @@ extension Onboarding {
 
         var hasReadAlgorithmSetupInformation: Bool = false
 
+        // Autosens Settings
         var autosensMin: Decimal = 0.7
         var autosensMax: Decimal = 1.2
         var rewindResetsAutosens: Bool = true
+
+        var filteredAutosensSettingsSubsteps: [AutosensSettingsSubstep] {
+            if pumpOptionForOnboardingUnits == .minimed || pumpOptionForOnboardingUnits == .dana {
+                return AutosensSettingsSubstep.allCases
+            } else {
+                return [AutosensSettingsSubstep.autosensMin, AutosensSettingsSubstep.autosensMax]
+            }
+        }
+
+        // SMB Settings
         var enableSMBAlways: Bool = false
         var enableSMBWithCOB: Bool = false
         var enableSMBWithTempTarget: Bool = false
@@ -120,6 +131,8 @@ extension Onboarding {
         var maxSMBMinutes: Decimal = 30
         var maxUAMMinutes: Decimal = 30
         var maxDeltaGlucoseThreshold: Decimal = 0.2
+
+        // Target Behavior
         var highTempTargetRaisesSensitivity: Bool = false
         var lowTempTargetLowersSensitivity: Bool = false
         var sensitivityRaisesTarget: Bool = false
@@ -181,6 +194,46 @@ extension Onboarding {
             return formatter
         }
 
+        /// Remaps therapy items affected by a glucose unit change (mg/dL vs mmol/L).
+        ///
+        /// This function updates glucose target and insulin sensitivity (ISF) items to use the closest valid index
+        /// from the newly available rate arrays, preserving the original value intent.
+        ///
+        /// Call this after the user changes the unit selection.
+        ///
+        /// See also: `UnitSelectionStepView` `.onChange()` handlers.
+        func remapTherapyItemsForChangedUnits() {
+            // Targets
+            targetItems = targetItems.map { item in
+                let newLowIndex = closestIndex(for: targetRateValues[item.lowIndex], in: targetRateValues)
+                let newTimeIndex = closestIndex(for: targetTimeValues[item.timeIndex], in: targetTimeValues)
+                return TargetsEditor.Item(lowIndex: newLowIndex, highIndex: newLowIndex, timeIndex: newTimeIndex)
+            }
+
+            // ISF
+            isfItems = isfItems.map { item in
+                let newRateIndex = closestIndex(for: isfRateValues[item.rateIndex], in: isfRateValues)
+                let newTimeIndex = closestIndex(for: isfTimeValues[item.timeIndex], in: isfTimeValues)
+                return ISFEditor.Item(rateIndex: newRateIndex, timeIndex: newTimeIndex)
+            }
+        }
+
+        /// Remaps therapy items affected by a pump model change.
+        ///
+        /// This function updates basal profile items to use the closest valid index
+        /// from the updated basal rate and time arrays, preserving the user's settings.
+        ///
+        /// Call this after the user selects a new pump model.
+        ///
+        /// See also: `UnitSelectionStepView` `.onChange()` handlers.
+        func remapTherapyItemsForChangedPumpModel() {
+            basalProfileItems = basalProfileItems.map { item in
+                let newRateIndex = closestIndex(for: basalProfileRateValues[item.rateIndex], in: basalProfileRateValues)
+                let newTimeIndex = closestIndex(for: basalProfileTimeValues[item.timeIndex], in: basalProfileTimeValues)
+                return BasalProfileEditor.Item(rateIndex: newRateIndex, timeIndex: newTimeIndex)
+            }
+        }
+
         // MARK: - Fetch existing therapy settings from file
 
         /// Loads existing therapy settings from the provider and maps them into UI editor items.

+ 18 - 18
Trio/Sources/Modules/Onboarding/View/OnboardingRootView.swift

@@ -80,7 +80,7 @@ extension Onboarding {
                                 stepsWithSubsteps: [
                                     .nightscout: NightscoutSubstep.allCases.count,
                                     .deliveryLimits: DeliveryLimitSubstep.allCases.count,
-                                    .autosensSettings: AutosensSettingsSubstep.allCases.count,
+                                    .autosensSettings: state.filteredAutosensSettingsSubsteps.count,
                                     .smbSettings: SMBSettingsSubstep.allCases.count,
                                     .targetBehavior: TargetBehaviorSubstep.allCases.count
                                 ],
@@ -431,11 +431,14 @@ struct OnboardingNavigationButtons: View {
             }
 
         case .autosensSettings:
-            if let previous = AutosensSettingsSubstep(rawValue: currentAutosensSubstep.rawValue - 1) {
-                currentAutosensSubstep = previous
+            let steps = state.filteredAutosensSettingsSubsteps
+            if let current = steps.firstIndex(of: currentAutosensSubstep),
+               current > 0
+            {
+                currentAutosensSubstep = steps[current - 1]
             } else if let previousStep = currentStep.previous {
                 currentStep = previousStep
-                currentAutosensSubstep = .autosensMin
+                currentAutosensSubstep = steps.first ?? .autosensMin
             }
 
         case .smbSettings:
@@ -452,10 +455,12 @@ struct OnboardingNavigationButtons: View {
                 currentStep = previousStep
                 currentSMBSubstep = .enableSMBAlways
 
-                /// Skip Autosens substep `.rewindResetsAutosens` if pump model is not `.minimed`.
-                if state.pumpOptionForOnboardingUnits == .minimed || state.pumpOptionForOnboardingUnits == .dana {
+                switch state.pumpOptionForOnboardingUnits {
+                case .dana,
+                     .minimed:
                     currentAutosensSubstep = .rewindResetsAutosens
-                } else {
+                case .omnipodDash,
+                     .omnipodEros:
                     currentAutosensSubstep = .autosensMax
                 }
             }
@@ -507,19 +512,14 @@ struct OnboardingNavigationButtons: View {
             }
 
         case .autosensSettings:
-            if let next = AutosensSettingsSubstep(rawValue: currentAutosensSubstep.rawValue + 1) {
-                /// Skip Autosens substep `.rewindResetsAutosens` if pump model is not `.minimed`.
-                if currentAutosensSubstep == .autosensMax,
-                   state.pumpOptionForOnboardingUnits != .minimed || state.pumpOptionForOnboardingUnits != .dana,
-                   let nextMainStep = currentStep.next
-                {
-                    currentStep = nextMainStep
-                } else {
-                    currentAutosensSubstep = next
-                }
+            let steps = state.filteredAutosensSettingsSubsteps
+            if let current = steps.firstIndex(of: currentAutosensSubstep),
+               current + 1 < steps.count
+            {
+                currentAutosensSubstep = steps[current + 1]
             } else if let nextStep = currentStep.next {
                 currentStep = nextStep
-                currentAutosensSubstep = .autosensMin
+                currentAutosensSubstep = steps.first ?? .autosensMin
             }
 
         case .smbSettings:

+ 12 - 1
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/AlgorithmSettings/AlgorithmSettingsSubstepView.swift

@@ -16,6 +16,17 @@ struct AlgorithmSettingsSubstepView<Substep: AlgorithmSubstepProtocol & RawRepre
 
     private let settingsProvider = PickerSettingsProvider.shared
 
+    private var shouldDisableRewindResetsAutosens: Bool {
+        switch state.pumpOptionForOnboardingUnits {
+        case .dana,
+             .minimed:
+            return false
+        case .omnipodDash,
+             .omnipodEros:
+            return true
+        }
+    }
+
     var body: some View {
         VStack(alignment: .leading, spacing: 16) {
             Text(substep.title)
@@ -56,7 +67,7 @@ struct AlgorithmSettingsSubstepView<Substep: AlgorithmSubstepProtocol & RawRepre
                         decimalValue: $decimalPlaceholder,
                         booleanValue: $state.rewindResetsAutosens,
                         type: OnboardingInputSectionType.boolean,
-                        disabled: state.pumpOptionForOnboardingUnits != .minimed
+                        disabled: shouldDisableRewindResetsAutosens
                     )
                 case .enableSMBAlways:
                     algorithmSettingsInput(

+ 5 - 7
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/UnitSelectionStepView.swift

@@ -31,15 +31,13 @@ struct UnitSelectionStepView: View {
                     }
                 }
                 .onChange(of: state.pumpOptionForOnboardingUnits, { _, newValue in
-                    // Reset therapy settings and related values when pump model changes
-                    state.targetItems = []
-                    state.basalProfileItems = []
-                    state.carbRatioItems = []
-                    state.isfItems = []
-
-                    // Conditionally set rewind setting, if pump model is MDT
+                    state.remapTherapyItemsForChangedPumpModel()
+                    // Conditionally set rewind setting, if pump model is Medtronic (.minimed) or Dana (i/RS)
                     state.rewindResetsAutosens = (newValue == .minimed || newValue == .dana)
                 })
+                .onChange(of: state.units, { _, _ in
+                    state.remapTherapyItemsForChangedUnits()
+                })
             }
             .padding()
             .background(Color.chart.opacity(0.65))

+ 1 - 1
Trio/Sources/Modules/Onboarding/View/OnboardingView+AlgorithmUtil.swift

@@ -191,7 +191,7 @@ enum AlgorithmSettingsSubstep: Int, CaseIterable, Identifiable {
         case .rewindResetsAutosens:
             return VStack(alignment: .leading, spacing: 5) {
                 Text("Default: ON").bold().foregroundStyle(Color.primary)
-                Text("Medtronic Users Only").bold()
+                Text("Medtronic and Dana Users Only").bold()
                 VStack(alignment: .leading, spacing: 8) {
                     Text(
                         "This feature resets the Autosens Ratio to neutral when you rewind your pump on the assumption that this corresponds to a site change."