Quellcode durchsuchen

Ensure first entry is always 00:00; only non-taken times can be chosen

Deniz Cengiz vor 1 Jahr
Ursprung
Commit
84f3ebb397
1 geänderte Dateien mit 27 neuen und 15 gelöschten Zeilen
  1. 27 15
      Trio/Sources/Modules/Onboarding/View/TherapySettingEditorView.swift

+ 27 - 15
Trio/Sources/Modules/Onboarding/View/TherapySettingEditorView.swift

@@ -8,7 +8,6 @@ struct TherapySettingEditorView: View {
     var validateOnDelete: (() -> Void)?
 
     @State private var selectedItemID: UUID?
-    @State private var refreshUI = UUID() // to update list and UI picker value(s) change(s)
 
     var body: some View {
         List {
@@ -47,7 +46,10 @@ struct TherapySettingEditorView: View {
                         HStack {
                             HStack {
                                 Text(displayText(for: unit, decimalValue: item.value))
-                                    .foregroundStyle(selectedItemID == item.id ? Color.accentColor : Color.primary)
+                                    .foregroundStyle(
+                                        selectedItemID == item.id ? Color.accentColor : Color
+                                            .primary
+                                    )
                                 Text(unit.displayName)
                                     .foregroundStyle(Color.secondary)
                             }
@@ -60,12 +62,10 @@ struct TherapySettingEditorView: View {
                                 let time = timeOptions[timeIndex]
                                 let date = Date(timeIntervalSince1970: time)
                                 let timeString = timeFormatter.string(from: date)
-                                Text(timeString)
-                                    .foregroundStyle(selectedItemID == item.id ? Color.accentColor : Color.primary)
+                                Text(timeString).foregroundStyle(selectedItemID == item.id ? Color.accentColor : Color.primary)
                             }
                         }
                         .contentShape(Rectangle())
-                        .id(refreshUI) // force list update
                     }
                     .buttonStyle(.plain)
 
@@ -114,6 +114,7 @@ struct TherapySettingEditorView: View {
         .onAppear {
             // ensure picker is closed when view appears
             selectedItemID = nil
+            validateTherapySettingItems()
         }
     }
 
@@ -123,13 +124,21 @@ struct TherapySettingEditorView: View {
         valueOptions: [Decimal],
         unit: TherapySettingUnit
     ) -> some View {
+        // Compute unavailable times (already taken by other entries)
+        let takenTimes = Set(items.filter { $0.id != item.wrappedValue.id }.map(\.time))
+        // Allow current selection even if it’s in the set of taken times.
+        let availableTimes = timeOptions.filter { $0 == item.wrappedValue.time || !takenTimes.contains($0) }
+        // Determine if this is first item in list (which is locked to 00:00)
+        var isFirstItem: Bool {
+            items.first == item.wrappedValue
+        }
+
         VStack(spacing: 8) {
             HStack {
                 Picker("Value", selection: Binding(
                     get: { Double(item.wrappedValue.value) },
                     set: {
                         item.wrappedValue.value = Decimal($0)
-                        refreshUI = UUID()
                     }
                 )) {
                     ForEach(valueOptions, id: \.self) { value in
@@ -141,17 +150,23 @@ struct TherapySettingEditorView: View {
 
                 Picker("Time", selection: Binding(
                     get: { item.wrappedValue.time },
-                    set: {
-                        item.wrappedValue.time = $0
-                        validateTherapySettingItems()
-                        refreshUI = UUID()
+                    set: { newTime in
+                        // Only update if new time is either not taken, or it is the current value
+                        if newTime == item.wrappedValue.time || !takenTimes.contains(newTime) {
+                            item.wrappedValue.time = newTime
+                            validateTherapySettingItems()
+                        }
                     }
                 )) {
-                    ForEach(timeOptions, id: \.self) { time in
+                    ForEach(availableTimes, id: \.self) { time in
                         Text(timeFormatter.string(from: Date(timeIntervalSince1970: time)))
                             .tag(time)
+                            .foregroundStyle(item.wrappedValue.time != 0 ? Color.primary : Color.secondary)
                     }
                 }
+                // Lock time picker if first item and make it slightly opague
+                .opacity(isFirstItem ? 0.5 : 1)
+                .disabled(isFirstItem)
                 .frame(maxWidth: .infinity)
                 .clipped()
             }
@@ -171,11 +186,8 @@ struct TherapySettingEditorView: View {
     private func validateTherapySettingItems() {
         // validates therapy items (i.e. parsed therapy settings into wrapper class)
         let newItems = Array(Set(items)).sorted { $0.time < $1.time }
-        if var first = newItems.first {
+        if var first = newItems.first, first.time != 0 {
             first.time = 0
-        }
-
-        if items != newItems {
             items = newItems
         }