Przeglądaj źródła

Perform validate on delete; ensure schedule spans 24hrs

Deniz Cengiz 1 rok temu
rodzic
commit
f328a2025b

+ 22 - 34
Trio/Sources/Modules/Onboarding/OnboardingStateModel.swift

@@ -162,7 +162,6 @@ extension Onboarding {
         func getTargetTherapyItems(from targets: [TargetsEditor.Item]) -> [TherapySettingItem] {
             targets.map {
                 TherapySettingItem(
-                    id: UUID(),
                     time: targetTimeValues[$0.timeIndex],
                     value: targetRateValues[$0.lowIndex]
                 )
@@ -181,7 +180,6 @@ extension Onboarding {
         func getBasalTherapyItems(from basalRates: [BasalProfileEditor.Item]) -> [TherapySettingItem] {
             basalRates.map {
                 TherapySettingItem(
-                    id: UUID(),
                     time: basalProfileTimeValues[$0.timeIndex],
                     value: basalProfileRateValues[$0.rateIndex]
                 )
@@ -200,7 +198,6 @@ extension Onboarding {
         func getCarbRatioTherapyItems(from carbRatios: [CarbRatioEditor.Item]) -> [TherapySettingItem] {
             carbRatios.map {
                 TherapySettingItem(
-                    id: UUID(),
                     time: carbRatioTimeValues[$0.timeIndex],
                     value: carbRatioRateValues[$0.rateIndex]
                 )
@@ -219,7 +216,6 @@ extension Onboarding {
         func getSensitivityTherapyItems(from sensitivities: [ISFEditor.Item]) -> [TherapySettingItem] {
             sensitivities.map {
                 TherapySettingItem(
-                    id: UUID(),
                     time: isfTimeValues[$0.timeIndex],
                     value: isfRateValues[$0.rateIndex]
                 )
@@ -260,13 +256,11 @@ extension Onboarding.StateModel {
     }
 
     func validateCarbRatios() {
-        DispatchQueue.main.async {
-            let uniq = Array(Set(self.carbRatioItems))
-            let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
-            sorted.first?.timeIndex = 0
-            if self.carbRatioItems != sorted {
-                self.carbRatioItems = sorted
-            }
+        let uniq = Array(Set(carbRatioItems))
+        let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
+        sorted.first?.timeIndex = 0
+        if carbRatioItems != sorted {
+            carbRatioItems = sorted
         }
     }
 }
@@ -294,13 +288,11 @@ extension Onboarding.StateModel {
     }
 
     func validateTarget() {
-        DispatchQueue.main.async {
-            let uniq = Array(Set(self.targetItems))
-            let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
-            sorted.first?.timeIndex = 0
-            if self.targetItems != sorted {
-                self.targetItems = sorted
-            }
+        let uniq = Array(Set(targetItems))
+        let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
+        sorted.first?.timeIndex = 0
+        if targetItems != sorted {
+            targetItems = sorted
         }
     }
 }
@@ -330,13 +322,11 @@ extension Onboarding.StateModel {
     }
 
     func validateISF() {
-        DispatchQueue.main.async {
-            let uniq = Array(Set(self.isfItems))
-            let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
-            sorted.first?.timeIndex = 0
-            if self.isfItems != sorted {
-                self.isfItems = sorted
-            }
+        let uniq = Array(Set(isfItems))
+        let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
+        sorted.first?.timeIndex = 0
+        if isfItems != sorted {
+            isfItems = sorted
         }
     }
 }
@@ -362,15 +352,13 @@ extension Onboarding.StateModel {
     }
 
     func validateBasal() {
-        DispatchQueue.main.async {
-            let uniq = Array(Set(self.basalProfileItems))
-            let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
-            if let first = sorted.first, first.timeIndex != 0 {
-                sorted[0].timeIndex = 0
-            }
-            if self.basalProfileItems != sorted {
-                self.basalProfileItems = sorted
-            }
+        let uniq = Array(Set(basalProfileItems))
+        let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
+        if let first = sorted.first, first.timeIndex != 0 {
+            sorted[0].timeIndex = 0
+        }
+        if basalProfileItems != sorted {
+            basalProfileItems = sorted
         }
     }
 }

+ 2 - 7
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/BasalProfileStepView.swift

@@ -58,7 +58,8 @@ struct BasalProfileStepView: View {
                     items: $therapyItems,
                     unit: .unitPerHour,
                     timeOptions: state.basalProfileTimeValues,
-                    valueOptions: state.basalProfileRateValues
+                    valueOptions: state.basalProfileRateValues,
+                    validateOnDelete: state.validateBasal
                 )
 
                 Spacer(minLength: 20)
@@ -108,12 +109,6 @@ struct BasalProfileStepView: View {
         state.basalProfileItems.append(newItem)
     }
 
-    // Computed property to check if we can add more basal rates
-    private var canAddBasalRate: Bool {
-        guard let lastItem = state.basalProfileItems.last else { return true }
-        return lastItem.timeIndex < state.basalProfileTimeValues.count - 1
-    }
-
     // Calculate the total daily basal insulin
     private func calculateTotalDailyBasal() -> Double {
         let items = state.basalProfileItems

+ 2 - 7
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/CarbRatioStepView.swift

@@ -58,7 +58,8 @@ struct CarbRatioStepView: View {
                     items: $therapyItems,
                     unit: .gramPerUnit,
                     timeOptions: state.carbRatioTimeValues,
-                    valueOptions: state.carbRatioRateValues
+                    valueOptions: state.carbRatioRateValues,
+                    validateOnDelete: state.validateCarbRatios
                 )
 
                 // Example calculation based on first carb ratio
@@ -136,12 +137,6 @@ struct CarbRatioStepView: View {
         state.carbRatioItems.append(newItem)
     }
 
-    // Computed property to check if we can add more carb ratios
-    private var canAddRatio: Bool {
-        guard let lastItem = state.carbRatioItems.last else { return true }
-        return lastItem.timeIndex < state.carbRatioTimeValues.count - 1
-    }
-
     // Chart for visualizing carb ratios
     private var carbRatioChart: some View {
         Chart {

+ 2 - 7
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/GlucoseTargetStepView.swift

@@ -60,7 +60,8 @@ struct GlucoseTargetStepView: View {
                     items: $therapyItems,
                     unit: state.units == .mgdL ? .mgdL : .mmolL,
                     timeOptions: state.targetTimeValues,
-                    valueOptions: state.targetRateValues
+                    valueOptions: state.targetRateValues,
+                    validateOnDelete: state.validateTarget
                 )
             }
         }
@@ -89,12 +90,6 @@ struct GlucoseTargetStepView: View {
         state.targetItems.append(newItem)
     }
 
-    // Computed property to check if we can add more targets
-    private var canAddTarget: Bool {
-        guard let lastItem = state.targetItems.last else { return true }
-        return lastItem.timeIndex < state.targetTimeValues.count - 1
-    }
-
     // Chart for visualizing glucose targets
     private var glucoseTargetChart: some View {
         Chart {

+ 2 - 7
Trio/Sources/Modules/Onboarding/View/OnboardingSteps/InsulinSensitivityStepView.swift

@@ -58,7 +58,8 @@ struct InsulinSensitivityStepView: View {
                     items: $therapyItems,
                     unit: state.units == .mgdL ? .mgdLPerUnit : .mmolLPerUnit,
                     timeOptions: state.isfTimeValues,
-                    valueOptions: state.isfRateValues
+                    valueOptions: state.isfRateValues,
+                    validateOnDelete: state.validateISF
                 )
 
                 // Example calculation based on first ISF
@@ -151,12 +152,6 @@ struct InsulinSensitivityStepView: View {
         state.isfItems.append(newItem)
     }
 
-    // Computed property to check if we can add more ISF values
-    private var canAddISF: Bool {
-        guard let lastItem = state.isfItems.last else { return true }
-        return lastItem.timeIndex < state.isfTimeValues.count - 1
-    }
-
     // Chart for visualizing ISF profile
     private var isfChart: some View {
         Chart {

+ 34 - 3
Trio/Sources/Modules/Onboarding/View/TherapySettingEditorView.swift

@@ -5,6 +5,7 @@ struct TherapySettingEditorView: View {
     var unit: TherapySettingUnit
     var timeOptions: [TimeInterval]
     var valueOptions: [Decimal]
+    var validateOnDelete: (() -> Void)?
 
     @State private var selectedItemID: UUID?
 
@@ -78,6 +79,7 @@ struct TherapySettingEditorView: View {
                         Button(role: .destructive) {
                             items.remove(at: index)
                             selectedItemID = nil
+                            validateTherapySettingItems()
                         } label: {
                             Label("Delete", systemImage: "trash")
                         }
@@ -142,6 +144,21 @@ struct TherapySettingEditorView: View {
         .padding(.vertical, 8)
     }
 
+    private func validateTherapySettingItems() {
+        // validates therapy items (i.e. parsed therapy settings into wrapper class)
+        var newItems = Array(Set(items)).sorted { $0.time < $1.time }
+        if let first = newItems.first {
+            first.time = 0
+        }
+
+        if items != newItems {
+            items = newItems
+        }
+
+        // validates underlying "raw" therapy setting (i.e. item of type basal, target, isf, carb ratio)
+        validateOnDelete?()
+    }
+
     private var timeFormatter: DateFormatter {
         let formatter = DateFormatter()
         formatter.timeZone = TimeZone(secondsFromGMT: 0)
@@ -163,10 +180,24 @@ struct TherapySettingEditorView: View {
     }
 }
 
-struct TherapySettingItem: Identifiable, Equatable, Hashable {
+class TherapySettingItem: Identifiable, Equatable, Hashable {
     var id = UUID()
-    var time: TimeInterval // seconds since start of day
-    var value: Decimal
+    var time: TimeInterval = 0 // seconds since start of day
+    var value: Decimal = 0
+
+    init(time: TimeInterval, value: Decimal) {
+        self.time = time
+        self.value = value
+    }
+
+    static func == (lhs: TherapySettingItem, rhs: TherapySettingItem) -> Bool {
+        lhs.time == rhs.time && lhs.value == rhs.value
+    }
+
+    func hash(into hasher: inout Hasher) {
+        hasher.combine(time)
+        hasher.combine(value)
+    }
 }
 
 enum TherapySettingUnit: String, CaseIterable {