Bläddra i källkod

add -/+ buttons to override slider, reorganize override UI

Mike Plante 1 år sedan
förälder
incheckning
2a65f3dbc6

+ 185 - 160
FreeAPS/Sources/Modules/OverrideConfig/View/AddOverrideForm.swift

@@ -4,7 +4,6 @@ import SwiftUI
 struct AddOverrideForm: View {
     @Environment(\.presentationMode) var presentationMode
     @StateObject var state: OverrideConfig.StateModel
-    @State private var isEditing = false
     @State private var displayPickerStart: Bool = false
     @State private var displayPickerEnd: Bool = false
     @State private var displayPickerSmbMinutes: Bool = false
@@ -79,54 +78,99 @@ struct AddOverrideForm: View {
 
         Section {
             VStack {
-                Spacer()
-                Text("\(state.overrideSliderPercentage.formatted(.number)) %")
-                    .foregroundColor(
-                        state
-                            .overrideSliderPercentage >= 130 ? .red :
-                            (isEditing ? .orange : Color.tabBar)
-                    )
-                    .font(.largeTitle)
+                HStack {
+                    Spacer()
+
+                    // Decrement button
+                    Button(action: {
+                        if state.overrideSliderPercentage > 10 {
+                            state.overrideSliderPercentage -= 1
+                        }
+                    }) {
+                        Image(systemName: "minus.circle.fill")
+                            .font(.title)
+                            .foregroundColor(state.overrideSliderPercentage > 10 ? .accentColor : .loopGray)
+                    }
+                    .buttonStyle(PlainButtonStyle())
+
+                    Spacer()
+
+                    Text("\(Int(state.overrideSliderPercentage)) %")
+                        .font(.largeTitle)
+                        .foregroundColor(.accentColor)
+
+                    Spacer()
+
+                    // Increment button
+                    Button(action: {
+                        if state.overrideSliderPercentage < 200 {
+                            state.overrideSliderPercentage += 1
+                        }
+                    }) {
+                        Image(systemName: "plus.circle.fill")
+                            .font(.title)
+                            .foregroundColor(state.overrideSliderPercentage < 200 ? .accentColor : .loopGray)
+                    }
+                    .buttonStyle(PlainButtonStyle())
+
+                    Spacer()
+                }
+                .padding()
+
+                // Slider to adjust value
                 Slider(
                     value: $state.overrideSliderPercentage,
                     in: 10 ... 200,
-                    step: 1,
-                    onEditingChanged: { editing in
-                        isEditing = editing
-                    }
+                    step: 1
                 )
-                Spacer()
+
+                Toggle(isOn: $state.isfAndCr) {
+                    Text("Change ISF and CR")
+                }
+                if !state.isfAndCr {
+                    Toggle(isOn: $state.isf) {
+                        Text("Change ISF")
+                    }
+
+                    Toggle(isOn: $state.cr) {
+                        Text("Change CR")
+                    }
+                }
+
+                Divider()
+
                 Toggle(isOn: $state.indefinite) {
                     Text("Enable Indefinitely")
                 }
-            }
-            if !state.indefinite {
-                HStack {
-                    Text("Duration")
-                    TextFieldWithToolBar(text: $state.overrideDuration, placeholder: "0", numberFormatter: formatter)
-                    Text("minutes").foregroundColor(.secondary)
+                if !state.indefinite {
+                    HStack {
+                        Text("Duration")
+                        TextFieldWithToolBar(text: $state.overrideDuration, placeholder: "0", numberFormatter: formatter)
+                        Text("min").foregroundColor(.secondary)
+                    }
                 }
-            }
 
-            HStack {
+                Divider()
+
                 Toggle(isOn: $state.shouldOverrideTarget) {
                     Text("Override Profile Target")
                 }
-            }
-            if state.shouldOverrideTarget {
-                HStack {
-                    Text("Target Glucose")
-                    TextFieldWithToolBar(text: $state.target, placeholder: "0", numberFormatter: glucoseFormatter)
-                    Text(state.units.rawValue).foregroundColor(.secondary)
+                if state.shouldOverrideTarget {
+                    HStack {
+                        Text("Target Glucose")
+                        TextFieldWithToolBar(text: $state.target, placeholder: "0", numberFormatter: glucoseFormatter)
+                        Text(state.units.rawValue).foregroundColor(.secondary)
+                    }
                 }
-            }
-            HStack {
+
+                Divider()
+
                 Toggle(isOn: $state.advancedSettings) {
                     Text("More Options")
                 }
-            }
-            if state.advancedSettings {
-                HStack {
+                if state.advancedSettings {
+                    Divider()
+
                     Toggle(isOn: Binding(
                         get: { state.smbIsOff },
                         set: { newValue in
@@ -138,8 +182,9 @@ struct AddOverrideForm: View {
                     )) {
                         Text("Disable SMBs")
                     }
-                }
-                HStack {
+
+                    Divider()
+
                     Toggle(isOn: Binding(
                         get: { state.smbIsScheduledOff },
                         set: { newValue in
@@ -151,150 +196,130 @@ struct AddOverrideForm: View {
                     )) {
                         Text("Schedule When SMBs Are Disabled")
                     }
-                }
 
-                if state.smbIsScheduledOff {
-                    // First Hour SMBs Are Disabled
-                    VStack {
-                        HStack {
-                            Text("First Hour SMBs Are Disabled")
-                            Spacer()
-
-                            // Display current selection based on format
-                            Text(
-                                is24HourFormat() ? format24Hour(Int(truncating: state.start as NSNumber)) + ":00" :
-                                    convertTo12HourFormat(Int(truncating: state.start as NSNumber))
-                            )
-                            .foregroundColor(!displayPickerStart ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerStart.toggle() // Toggle the picker visibility
-                        }
+                    if state.smbIsScheduledOff {
+                        // First Hour SMBs Are Disabled
+                        VStack {
+                            HStack {
+                                Text("From")
+                                Spacer()
 
-                        // Show picker if toggled
-                        if displayPickerStart {
-                            Picker(selection: Binding(
-                                get: { Int(truncating: state.start as NSNumber) },
-                                set: { state.start = Decimal($0) }
-                            ), label: Text("")) {
-                                ForEach(0 ..< 24, id: \.self) { hour in
-                                    Text(is24HourFormat() ? format24Hour(hour) + ":00" : convertTo12HourFormat(hour)).tag(hour)
+                                Text(
+                                    is24HourFormat() ? format24Hour(Int(truncating: state.start as NSNumber)) + ":00" :
+                                        convertTo12HourFormat(Int(truncating: state.start as NSNumber))
+                                )
+                                .foregroundColor(!displayPickerStart ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerStart.toggle()
+                            }
+
+                            if displayPickerStart {
+                                Picker(selection: Binding(
+                                    get: { Int(truncating: state.start as NSNumber) },
+                                    set: { state.start = Decimal($0) }
+                                ), label: Text("")) {
+                                    ForEach(0 ..< 24, id: \.self) { hour in
+                                        Text(is24HourFormat() ? format24Hour(hour) + ":00" : convertTo12HourFormat(hour))
+                                            .tag(hour)
+                                    }
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle()) // Use wheel style
-                            .frame(maxWidth: .infinity)
-                        }
-                    }
-                    .padding(.top)
-
-                    // First Hour SMBs Are Resumed
-                    VStack {
-                        HStack {
-                            Text("First Hour SMBs Are Resumed")
-                            Spacer()
-
-                            // Display current selection based on format
-                            Text(
-                                is24HourFormat() ? format24Hour(Int(truncating: state.end as NSNumber)) + ":00" :
-                                    convertTo12HourFormat(Int(truncating: state.end as NSNumber))
-                            )
-                            .foregroundColor(!displayPickerEnd ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerEnd.toggle() // Toggle the picker visibility
                         }
+                        .padding(.top, 10)
+
+                        // First Hour SMBs Are Resumed
+                        VStack {
+                            HStack {
+                                Text("To")
+                                Spacer()
+                                Text(
+                                    is24HourFormat() ? format24Hour(Int(truncating: state.end as NSNumber)) + ":00" :
+                                        convertTo12HourFormat(Int(truncating: state.end as NSNumber))
+                                )
+                                .foregroundColor(!displayPickerEnd ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerEnd.toggle()
+                            }
 
-                        // Show picker if toggled
-                        if displayPickerEnd {
-                            Picker(selection: Binding(
-                                get: { Int(truncating: state.end as NSNumber) },
-                                set: { state.end = Decimal($0) }
-                            ), label: Text("")) {
-                                ForEach(0 ..< 24, id: \.self) { hour in
-                                    Text(is24HourFormat() ? format24Hour(hour) + ":00" : convertTo12HourFormat(hour)).tag(hour)
+                            if displayPickerEnd {
+                                Picker(selection: Binding(
+                                    get: { Int(truncating: state.end as NSNumber) },
+                                    set: { state.end = Decimal($0) }
+                                ), label: Text("")) {
+                                    ForEach(0 ..< 24, id: \.self) { hour in
+                                        Text(is24HourFormat() ? format24Hour(hour) + ":00" : convertTo12HourFormat(hour))
+                                            .tag(hour)
+                                    }
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle()) // Use wheel style
-                            .frame(maxWidth: .infinity)
-                        }
-                    }
-                    .padding(.top)
-                }
-                HStack {
-                    Toggle(isOn: $state.isfAndCr) {
-                        Text("Change ISF and CR")
-                    }
-                }
-                if !state.isfAndCr {
-                    HStack {
-                        Toggle(isOn: $state.isf) {
-                            Text("Change ISF")
-                        }
-                    }
-                    HStack {
-                        Toggle(isOn: $state.cr) {
-                            Text("Change CR")
                         }
+                        .padding(.vertical, 10)
                     }
-                }
-                if !state.smbIsOff {
-                    // SMB Minutes Picker
-                    VStack {
-                        HStack {
-                            Text("Max SMB Minutes")
-                            Spacer()
-
-                            // Display current selection based on format
-                            Text("\(state.smbMinutes.formatted(.number)) min")
-                                .foregroundColor(!displayPickerSmbMinutes ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerSmbMinutes.toggle() // Toggle the picker visibility
-                        }
 
-                        // Show picker if toggled
-                        if displayPickerSmbMinutes {
-                            Picker(selection: Binding(
-                                get: { Int(truncating: state.smbMinutes as NSNumber) },
-                                set: { state.smbMinutes = Decimal($0) }
-                            ), label: Text("")) {
-                                ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
-                                    Text("\(minute) min").tag(minute)
+                    if !state.smbIsOff {
+                        Divider()
+
+                        // SMB Minutes Picker
+                        VStack {
+                            HStack {
+                                Text("Max SMB Minutes")
+                                Spacer()
+
+                                Text("\(state.smbMinutes.formatted(.number)) min")
+                                    .foregroundColor(!displayPickerSmbMinutes ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerSmbMinutes.toggle()
+                            }
+
+                            if displayPickerSmbMinutes {
+                                Picker(selection: Binding(
+                                    get: { Int(truncating: state.smbMinutes as NSNumber) },
+                                    set: { state.smbMinutes = Decimal($0) }
+                                ), label: Text("")) {
+                                    ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
+                                        Text("\(minute) min").tag(minute)
+                                    }
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle()) // Use wheel style
-                            .frame(maxWidth: .infinity)
-                        }
-                    }
-                    .padding(.top)
-
-                    // UAM SMB Minutes Picker
-                    VStack {
-                        HStack {
-                            Text("Max UAM SMB Minutes")
-                            Spacer()
-                            Text("\(state.uamMinutes.formatted(.number)) min")
-                                .foregroundColor(!displayPickerUamMinutes ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerUamMinutes.toggle() // Toggle picker visibility
                         }
+                        .padding(.top)
+
+                        // UAM SMB Minutes Picker
+                        VStack {
+                            HStack {
+                                Text("Max UAM SMB Minutes")
+                                Spacer()
+                                Text("\(state.uamMinutes.formatted(.number)) min")
+                                    .foregroundColor(!displayPickerUamMinutes ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerUamMinutes.toggle()
+                            }
 
-                        // Show picker if toggled
-                        if displayPickerUamMinutes {
-                            Picker(selection: Binding(
-                                get: { Int(truncating: state.uamMinutes as NSNumber) },
-                                set: { state.uamMinutes = Decimal($0) }
-                            ), label: Text("")) {
-                                ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
-                                    Text("\(minute) min").tag(minute)
+                            if displayPickerUamMinutes {
+                                Picker(selection: Binding(
+                                    get: { Int(truncating: state.uamMinutes as NSNumber) },
+                                    set: { state.uamMinutes = Decimal($0) }
+                                ), label: Text("")) {
+                                    ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
+                                        Text("\(minute) min").tag(minute)
+                                    }
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle()) // Use wheel style
-                            .frame(maxWidth: .infinity)
                         }
+                        .padding(.top)
                     }
-                    .padding(.top)
                 }
             }
 

+ 252 - 214
FreeAPS/Sources/Modules/OverrideConfig/View/EditOverrideForm.swift

@@ -132,266 +132,304 @@ struct EditOverrideForm: View {
         }
         Section {
             VStack {
-                Spacer()
-                Text("\(percentage.formatted(.number)) %")
-                    .foregroundColor(
-                        state
-                            .overrideSliderPercentage >= 130 ? .red :
-                            (isEditing ? .orange : Color.tabBar)
-                    )
-                    .font(.largeTitle)
+                HStack {
+                    Spacer()
+
+                    // Decrement button
+                    Button(action: {
+                        if percentage > 10 {
+                            percentage -= 1
+                        }
+                    }) {
+                        Image(systemName: "minus.circle.fill")
+                            .font(.title)
+                            .foregroundColor(percentage > 10 ? .accentColor : .loopGray)
+                    }
+                    .buttonStyle(PlainButtonStyle())
+
+                    Spacer()
+
+                    Text("\(percentage.formatted(.number)) %")
+                        .foregroundColor(.accentColor)
+                        .font(.largeTitle)
+
+                    Spacer()
+
+                    // Increment button
+                    Button(action: {
+                        if percentage < 200 {
+                            percentage += 1
+                        }
+                    }) {
+                        Image(systemName: "plus.circle.fill")
+                            .font(.title)
+                            .foregroundColor(percentage < 200 ? .accentColor : .loopGray)
+                    }
+                    .buttonStyle(PlainButtonStyle())
+
+                    Spacer()
+                }
+                .padding()
+
                 Slider(
                     value: $percentage,
                     in: 10 ... 200,
                     step: 1
                 ).onChange(of: percentage) { _ in hasChanges = true }
-                Spacer()
+
+                Toggle(isOn: $isfAndCr) {
+                    Text("Change ISF and CR")
+                }.onChange(of: isfAndCr) { _ in hasChanges = true }
+
+                if !isfAndCr {
+                    Toggle(isOn: $isf) {
+                        Text("Change ISF")
+                    }.onChange(of: isf) { _ in hasChanges = true }
+
+                    Toggle(isOn: $cr) {
+                        Text("Change CR")
+                    }.onChange(of: cr) { _ in hasChanges = true }
+                }
+
+                Divider()
+
                 Toggle(isOn: $indefinite) {
                     Text("Enable Indefinitely")
                 }.onChange(of: indefinite) { _ in hasChanges = true }
-            }
-            if !indefinite {
-                HStack {
-                    Text("Duration")
-                    TextFieldWithToolBar(
-                        text: Binding(
-                            get: { duration },
-                            set: {
-                                duration = $0
-                                hasChanges = true
-                            }
-                        ),
-                        placeholder: "0",
-                        numberFormatter: formatter
-                    )
-                    Text("minutes").foregroundColor(.secondary)
+
+                if !indefinite {
+                    HStack {
+                        Text("Duration")
+                        TextFieldWithToolBar(
+                            text: Binding(
+                                get: { duration },
+                                set: {
+                                    duration = $0
+                                    hasChanges = true
+                                }
+                            ),
+                            placeholder: "0",
+                            numberFormatter: formatter
+                        )
+                        Text("min").foregroundColor(.secondary)
+                    }
                 }
-            }
 
-            HStack {
+                Divider()
+
                 Toggle(isOn: $target_override) {
                     Text("Override Override Target")
                 }.onChange(of: target_override) { _ in
                     hasChanges = true
                 }
-            }
-            if target_override {
-                HStack {
-                    Text("Target Glucose")
-                    TextFieldWithToolBar(text: Binding(
-                        get: {
-                            target ?? 0
-                        },
-                        set: {
-                            target = $0
-                            hasChanges = true
-                        }
-                    ), placeholder: "0", numberFormatter: glucoseFormatter)
-                    Text(state.units.rawValue).foregroundColor(.secondary)
-                }
-            }
-
-            Toggle(isOn: $advancedSettings) {
-                Text("More Options")
-            }.onChange(of: advancedSettings) { _ in hasChanges = true }
-
-            if advancedSettings {
-                Toggle(
-                    isOn: Binding(
-                        get: { smbIsOff },
-                        set: { newValue in
-                            smbIsOff = newValue
-                            if newValue {
-                                smbIsScheduledOff = false
+                if target_override {
+                    HStack {
+                        Text("Target Glucose")
+                        TextFieldWithToolBar(text: Binding(
+                            get: {
+                                target ?? 0
+                            },
+                            set: {
+                                target = $0
+                                hasChanges = true
                             }
-                            hasChanges = true
-                        }
-                    )
-                ) {
-                    Text("Disable SMBs")
+                        ), placeholder: "0", numberFormatter: glucoseFormatter)
+                        Text(state.units.rawValue).foregroundColor(.secondary)
+                    }
                 }
 
-                Toggle(
-                    isOn: Binding(
-                        get: { smbIsScheduledOff },
-                        set: { newValue in
-                            smbIsScheduledOff = newValue
-                            if newValue {
-                                smbIsOff = false
-                            }
-                            hasChanges = true
-                        }
-                    )
-                ) {
-                    Text("Schedule When SMBs Are Disabled")
-                }
+                Divider()
 
-                if smbIsScheduledOff {
-                    // First Hour SMBs Are Disabled
-                    VStack {
-                        HStack {
-                            Text("First Hour SMBs Are Disabled")
-                            Spacer()
-
-                            // Display current selection based on format
-                            Text(
-                                is24HourFormat() ? format24Hour(Int(truncating: start! as NSNumber)) + ":00" :
-                                    convertTo12HourFormat(Int(truncating: start! as NSNumber))
-                            )
-                            .foregroundColor(!displayPickerStart ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerStart.toggle() // Toggle the picker visibility
-                        }
+                Toggle(isOn: $advancedSettings) {
+                    Text("More Options")
+                }.onChange(of: advancedSettings) { _ in hasChanges = true }
 
-                        // Show picker if toggled
-                        if displayPickerStart {
-                            Picker(selection: Binding(
-                                get: { Int(truncating: start! as NSNumber) },
-                                set: {
-                                    start = Decimal($0)
-                                    hasChanges = true
-                                }
-                            ), label: Text("")) {
-                                if is24HourFormat() {
-                                    ForEach(0 ..< 24, id: \.self) { hour in
-                                        Text(format24Hour(hour) + ":00").tag(hour)
-                                    }
-                                } else {
-                                    ForEach(0 ..< 24, id: \.self) { hour in
-                                        Text(convertTo12HourFormat(hour)).tag(hour)
-                                    }
+                if advancedSettings {
+                    Divider()
+
+                    Toggle(
+                        isOn: Binding(
+                            get: { smbIsOff },
+                            set: { newValue in
+                                smbIsOff = newValue
+                                if newValue {
+                                    smbIsScheduledOff = false
                                 }
+                                hasChanges = true
                             }
-                            .pickerStyle(WheelPickerStyle()) // Use wheel style
-                            .frame(maxWidth: .infinity)
-                        }
+                        )
+                    ) {
+                        Text("Disable SMBs")
                     }
-                    .padding(.top)
-
-                    // First Hour SMBs Are Resumed
-                    VStack {
-                        HStack {
-                            Text("First Hour SMBs Are Resumed")
-                            Spacer()
-
-                            // Display current selection based on format
-                            Text(
-                                is24HourFormat() ? format24Hour(Int(truncating: end! as NSNumber)) + ":00" :
-                                    convertTo12HourFormat(Int(truncating: end! as NSNumber))
-                            )
-                            .foregroundColor(!displayPickerEnd ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerEnd.toggle() // Toggle the picker visibility
-                        }
 
-                        // Show picker if toggled
-                        if displayPickerEnd {
-                            Picker(selection: Binding(
-                                get: { Int(truncating: end! as NSNumber) },
-                                set: {
-                                    end = Decimal($0)
-                                    hasChanges = true
+                    Divider()
+
+                    Toggle(
+                        isOn: Binding(
+                            get: { smbIsScheduledOff },
+                            set: { newValue in
+                                smbIsScheduledOff = newValue
+                                if newValue {
+                                    smbIsOff = false
                                 }
-                            ), label: Text("")) {
-                                if is24HourFormat() {
-                                    ForEach(0 ..< 24, id: \.self) { hour in
-                                        Text(format24Hour(hour) + ":00").tag(hour)
+                                hasChanges = true
+                            }
+                        )
+                    ) {
+                        Text("Schedule When SMBs Are Disabled")
+                    }
+
+                    if smbIsScheduledOff {
+                        // First Hour SMBs Are Disabled
+                        VStack {
+                            HStack {
+                                Text("From")
+                                Spacer()
+
+                                Text(
+                                    is24HourFormat() ? format24Hour(Int(truncating: start! as NSNumber)) + ":00" :
+                                        convertTo12HourFormat(Int(truncating: start! as NSNumber))
+                                )
+                                .foregroundColor(!displayPickerStart ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerStart.toggle()
+                            }
+
+                            if displayPickerStart {
+                                Picker(selection: Binding(
+                                    get: { Int(truncating: start! as NSNumber) },
+                                    set: {
+                                        start = Decimal($0)
+                                        hasChanges = true
                                     }
-                                } else {
-                                    ForEach(0 ..< 24, id: \.self) { hour in
-                                        Text(convertTo12HourFormat(hour)).tag(hour)
+                                ), label: Text("")) {
+                                    if is24HourFormat() {
+                                        ForEach(0 ..< 24, id: \.self) { hour in
+                                            Text(format24Hour(hour) + ":00").tag(hour)
+                                        }
+                                    } else {
+                                        ForEach(0 ..< 24, id: \.self) { hour in
+                                            Text(convertTo12HourFormat(hour)).tag(hour)
+                                        }
                                     }
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle()) // Use wheel style
-                            .frame(maxWidth: .infinity)
                         }
-                    }
-                    .padding(.top)
-                }
+                        .padding(.top)
 
-                Toggle(isOn: $isfAndCr) {
-                    Text("Change ISF and CR")
-                }.onChange(of: isfAndCr) { _ in hasChanges = true }
+                        // First Hour SMBs Are Resumed
+                        VStack {
+                            HStack {
+                                Text("To")
+                                Spacer()
 
-                if !isfAndCr {
-                    Toggle(isOn: $isf) {
-                        Text("Change ISF")
-                    }.onChange(of: isf) { _ in hasChanges = true }
-
-                    Toggle(isOn: $cr) {
-                        Text("Change CR")
-                    }.onChange(of: cr) { _ in hasChanges = true }
-                }
-
-                if !smbIsOff {
-                    // SMB Minutes Picker
-                    VStack {
-                        HStack {
-                            Text("Max SMB Minutes")
-                            Spacer()
-                            Text("\(smbMinutes?.formatted(.number) ?? "\(state.defaultSmbMinutes)") min")
-                                .foregroundColor(!displayPickerSmbMinutes ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerSmbMinutes.toggle()
-                        }
+                                Text(
+                                    is24HourFormat() ? format24Hour(Int(truncating: end! as NSNumber)) + ":00" :
+                                        convertTo12HourFormat(Int(truncating: end! as NSNumber))
+                                )
+                                .foregroundColor(!displayPickerEnd ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerEnd.toggle()
+                            }
 
-                        if displayPickerSmbMinutes {
-                            Picker(
-                                selection: Binding(
-                                    get: { smbMinutes ?? state.defaultSmbMinutes },
+                            if displayPickerEnd {
+                                Picker(selection: Binding(
+                                    get: { Int(truncating: end! as NSNumber) },
                                     set: {
-                                        smbMinutes = $0
+                                        end = Decimal($0)
                                         hasChanges = true
                                     }
-                                ),
-                                label: Text("")
-                            ) {
-                                ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
-                                    Text("\(minute) min").tag(Decimal(minute))
+                                ), label: Text("")) {
+                                    if is24HourFormat() {
+                                        ForEach(0 ..< 24, id: \.self) { hour in
+                                            Text(format24Hour(hour) + ":00").tag(hour)
+                                        }
+                                    } else {
+                                        ForEach(0 ..< 24, id: \.self) { hour in
+                                            Text(convertTo12HourFormat(hour)).tag(hour)
+                                        }
+                                    }
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle())
-                            .frame(maxWidth: .infinity)
                         }
+                        .padding(.top)
                     }
-                    .padding(.top)
-
-                    // UAM SMB Minutes Picker
-                    VStack {
-                        HStack {
-                            Text("Max UAM SMB Minutes")
-                            Spacer()
-                            Text("\(uamMinutes?.formatted(.number) ?? "\(state.defaultUamMinutes)") min")
-                                .foregroundColor(!displayPickerUamMinutes ? .primary : .accentColor)
-                        }
-                        .onTapGesture {
-                            displayPickerUamMinutes.toggle()
+
+                    if !smbIsOff {
+                        Divider()
+
+                        // SMB Minutes Picker
+                        VStack {
+                            HStack {
+                                Text("Max SMB Minutes")
+                                Spacer()
+                                Text("\(smbMinutes?.formatted(.number) ?? "\(state.defaultSmbMinutes)") min")
+                                    .foregroundColor(!displayPickerSmbMinutes ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerSmbMinutes.toggle()
+                            }
+
+                            if displayPickerSmbMinutes {
+                                Picker(
+                                    selection: Binding(
+                                        get: { smbMinutes ?? state.defaultSmbMinutes },
+                                        set: {
+                                            smbMinutes = $0
+                                            hasChanges = true
+                                        }
+                                    ),
+                                    label: Text("")
+                                ) {
+                                    ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
+                                        Text("\(minute) min").tag(Decimal(minute))
+                                    }
+                                }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
+                            }
                         }
+                        .padding(.top)
+
+                        // UAM SMB Minutes Picker
+                        VStack {
+                            HStack {
+                                Text("Max UAM SMB Minutes")
+                                Spacer()
+                                Text("\(uamMinutes?.formatted(.number) ?? "\(state.defaultUamMinutes)") min")
+                                    .foregroundColor(!displayPickerUamMinutes ? .primary : .accentColor)
+                            }
+                            .onTapGesture {
+                                displayPickerUamMinutes.toggle()
+                            }
 
-                        if displayPickerUamMinutes {
-                            Picker(
-                                selection: Binding(
-                                    get: { uamMinutes ?? state.defaultUamMinutes },
-                                    set: {
-                                        uamMinutes = $0
-                                        hasChanges = true
+                            if displayPickerUamMinutes {
+                                Picker(
+                                    selection: Binding(
+                                        get: { uamMinutes ?? state.defaultUamMinutes },
+                                        set: {
+                                            uamMinutes = $0
+                                            hasChanges = true
+                                        }
+                                    ),
+                                    label: Text("")
+                                ) {
+                                    ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
+                                        Text("\(minute) min").tag(Decimal(minute))
                                     }
-                                ),
-                                label: Text("")
-                            ) {
-                                ForEach(Array(stride(from: 0, through: 180, by: 5)), id: \.self) { minute in
-                                    Text("\(minute) min").tag(Decimal(minute))
                                 }
+                                .pickerStyle(WheelPickerStyle())
+                                .frame(maxWidth: .infinity)
                             }
-                            .pickerStyle(WheelPickerStyle())
-                            .frame(maxWidth: .infinity)
                         }
+                        .padding(.top)
                     }
-                    .padding(.top)
                 }
             }
         }.listRowBackground(Color.chart)
@@ -429,7 +467,7 @@ struct EditOverrideForm: View {
             }, label: {
                 Text("Save")
             })
-                .disabled(!hasChanges)
+                .disabled(!hasChanges || (!indefinite && duration == 0))
                 .frame(maxWidth: .infinity, alignment: .center)
                 .tint(.white)
 

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

@@ -470,9 +470,9 @@ 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 && maxMinutesSMB != state.defaultSmbMinutes) ?
+            let maxSmbMinsString = (maxMinutesSMB != 0 && preset.advancedSettings && maxMinutesSMB != state.defaultSmbMinutes) ?
                 "\(maxMinutesSMB.formatted()) min SMB" : ""
-            let maxUamMinsString = (maxMinutesUAM != 0 && maxMinutesUAM != state.defaultUamMinutes) ?
+            let maxUamMinsString = (maxMinutesUAM != 0 && preset.advancedSettings && maxMinutesUAM != state.defaultUamMinutes) ?
                 "\(maxMinutesUAM.formatted()) min UAM" : ""
             let isfAndCRstring = (preset.isf == preset.cr) ? "" : (preset.isf ? " ISF" : " CR")
             let isSelected = preset.id == selectedPresetID