diff --git a/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json b/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json index 42dbd5e12..5503a2ab2 100644 --- a/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json +++ b/FreeAPS/Resources/json/defaults/freeaps/freeaps_settings.json @@ -44,5 +44,6 @@ "maxFat": 250, "maxProtein": 250, "displayFatAndProteinOnWatch": false, + "confirmBolusFaster": false, "lockScreenView": "simple" } diff --git a/FreeAPS/Sources/APS/DeviceDataManager.swift b/FreeAPS/Sources/APS/DeviceDataManager.swift index 1fb46c79f..e1f93923c 100644 --- a/FreeAPS/Sources/APS/DeviceDataManager.swift +++ b/FreeAPS/Sources/APS/DeviceDataManager.swift @@ -43,10 +43,6 @@ private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = [ MockPumpManager.pluginIdentifier: MockPumpManager.self ] -// private let staticPumpManagersByIdentifier: [String: PumpManagerUI.Type] = staticPumpManagers.reduce(into: [:]) { map, Type in -// map[Type.managerIdentifier] = Type -// } - private let accessLock = NSRecursiveLock(label: "BaseDeviceDataManager.accessLock") final class BaseDeviceDataManager: DeviceDataManager, Injectable { @@ -78,7 +74,8 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable { didSet { pumpManager?.pumpManagerDelegate = self pumpManager?.delegateQueue = processQueue - UserDefaults.standard.pumpManagerRawValue = pumpManager?.rawValue + rawPumpManager = pumpManager?.rawValue + UserDefaults.standard.clearLegacyPumpManagerRawValue() if let pumpManager = pumpManager { pumpDisplayState.value = PumpDisplayState(name: pumpManager.localizedTitle, image: pumpManager.smallImage) pumpName.send(pumpManager.localizedTitle) @@ -105,6 +102,8 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable { } } + @PersistedProperty(key: "PumpManagerState") var rawPumpManager: PumpManager.RawValue? + var bluetoothManager: BluetoothStateManager { bluetoothProvider } var hasBLEHeartbeat: Bool { @@ -123,7 +122,11 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable { } func setupPumpManager() { - pumpManager = UserDefaults.standard.pumpManagerRawValue.flatMap { pumpManagerFromRawValue($0) } + if let pumpManagerRawValue = rawPumpManager ?? UserDefaults.standard.legacyPumpManagerRawValue { + pumpManager = pumpManagerFromRawValue(pumpManagerRawValue) + } else { + pumpManager = nil + } } func createBolusProgressReporter() -> DoseProgressReporter? { @@ -163,20 +166,6 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable { self.updateUpdateFinished(true) } } - -// pumpUpdateCancellable = Future { [unowned self] promise in -// pumpUpdatePromise = promise -// debug(.deviceManager, "Waiting for pump update and loop recommendation") -// processQueue.safeSync { -// pumpManager.ensureCurrentPumpData { _ in -// debug(.deviceManager, "Pump data updated.") -// } -// } -// } -// .timeout(30, scheduler: processQueue) -// .replaceError(with: false) -// .replaceEmpty(with: false) -// .sink(receiveValue: updateUpdateFinished) } private func updateUpdateFinished(_ recommendsLoop: Bool) { @@ -186,11 +175,6 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable { warning(.deviceManager, "Loop recommendation time out or got error. Trying to loop right now.") } - // directly in loop() function -// guard !loopInProgress else { -// warning(.deviceManager, "Loop already in progress. Skip recommendation.") -// return -// } self.recommendsLoop.send() } @@ -319,7 +303,7 @@ extension BaseDeviceDataManager: PumpManagerDelegate { } func pumpManagerDidUpdateState(_ pumpManager: PumpManager) { - UserDefaults.standard.pumpManagerRawValue = pumpManager.rawValue + rawPumpManager = pumpManager.rawValue if self.pumpManager == nil, let newPumpManager = pumpManager as? PumpManagerUI { self.pumpManager = newPumpManager } @@ -540,29 +524,6 @@ extension BaseDeviceDataManager: DeviceManagerDelegate { func recordRetractedAlert(_: Alert, at _: Date) {} -// func scheduleNotification( -// for _: DeviceManager, -// identifier: String, -// content: UNNotificationContent, -// trigger: UNNotificationTrigger? -// ) { -// let request = UNNotificationRequest( -// identifier: identifier, -// content: content, -// trigger: trigger -// ) -// -// DispatchQueue.main.async { -// UNUserNotificationCenter.current().add(request) -// } -// } -// -// func clearNotification(for _: DeviceManager, identifier: String) { -// DispatchQueue.main.async { -// UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier]) -// } -// } - func removeNotificationRequests(for _: DeviceManager, identifiers: [String]) { DispatchQueue.main.async { UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers) diff --git a/FreeAPS/Sources/APS/Extensions/PumpManagerExtensions.swift b/FreeAPS/Sources/APS/Extensions/PumpManagerExtensions.swift index 237aaa8d8..db6a3c9e3 100644 --- a/FreeAPS/Sources/APS/Extensions/PumpManagerExtensions.swift +++ b/FreeAPS/Sources/APS/Extensions/PumpManagerExtensions.swift @@ -2,6 +2,8 @@ import LoopKit import LoopKitUI extension PumpManager { + typealias RawValue = [String: Any] + var rawValue: [String: Any] { [ "managerIdentifier": pluginIdentifier, // "managerIdentifier": type(of: self).managerIdentifier, @@ -11,14 +13,6 @@ extension PumpManager { } extension PumpManagerUI { -// static func setupViewController() -> PumpManagerSetupViewController & UIViewController & CompletionNotifying { -// setupViewController( -// insulinTintColor: .accentColor, -// guidanceColors: GuidanceColors(acceptable: .green, warning: .orange, critical: .red), -// allowedInsulinTypes: [.apidra, .humalog, .novolog, .fiasp, .lyumjev] -// ) -// } - func settingsViewController( bluetoothProvider: BluetoothProvider, pumpManagerOnboardingDelegate: PumpManagerOnboardingDelegate? @@ -32,14 +26,6 @@ extension PumpManagerUI { vc.pumpManagerOnboardingDelegate = pumpManagerOnboardingDelegate return vc } - -// func settingsViewController() -> UIViewController & CompletionNotifying { -// settingsViewController( -// insulinTintColor: .accentColor, -// guidanceColors: GuidanceColors(acceptable: .green, warning: .orange, critical: .red), -// allowedInsulinTypes: [.apidra, .humalog, .novolog, .fiasp, .lyumjev] -// ) -// } } protocol PumpSettingsBuilder { diff --git a/FreeAPS/Sources/APS/Extensions/UserDefaultsExtensions.swift b/FreeAPS/Sources/APS/Extensions/UserDefaultsExtensions.swift index 6c5428207..31d53c02d 100644 --- a/FreeAPS/Sources/APS/Extensions/UserDefaultsExtensions.swift +++ b/FreeAPS/Sources/APS/Extensions/UserDefaultsExtensions.swift @@ -5,17 +5,10 @@ import RileyLinkKit extension UserDefaults { private enum Key: String { - case pumpManagerRawValue = "com.rileylink.PumpManagerRawValue" + case legacyPumpManagerRawValue = "com.rileylink.PumpManagerRawValue" case rileyLinkConnectionManagerState = "com.rileylink.RileyLinkConnectionManagerState" - } - - var pumpManagerRawValue: PumpManager.RawStateValue? { - get { - dictionary(forKey: Key.pumpManagerRawValue.rawValue) - } - set { - set(newValue, forKey: Key.pumpManagerRawValue.rawValue) - } + case legacyPumpManagerState = "com.loopkit.Loop.PumpManagerState" + case legacyCGMManagerState = "com.loopkit.Loop.CGMManagerState" } var rileyLinkConnectionManagerState: RileyLinkConnectionState? { @@ -30,4 +23,20 @@ extension UserDefaults { set(newValue?.rawValue, forKey: Key.rileyLinkConnectionManagerState.rawValue) } } + + var legacyPumpManagerRawValue: PumpManager.RawValue? { + dictionary(forKey: Key.legacyPumpManagerRawValue.rawValue) + } + + func clearLegacyPumpManagerRawValue() { + set(nil, forKey: Key.legacyPumpManagerRawValue.rawValue) + } + + var legacyCGMManagerRawValue: CGMManager.RawValue? { + dictionary(forKey: Key.legacyCGMManagerState.rawValue) + } + + func clearLegacyCGMManagerRawValue() { + set(nil, forKey: Key.legacyCGMManagerState.rawValue) + } } diff --git a/FreeAPS/Sources/APS/FetchGlucoseManager.swift b/FreeAPS/Sources/APS/FetchGlucoseManager.swift index 95ae1bfc4..113de1eca 100644 --- a/FreeAPS/Sources/APS/FetchGlucoseManager.swift +++ b/FreeAPS/Sources/APS/FetchGlucoseManager.swift @@ -45,6 +45,7 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable { var cgmManager: CGMManagerUI? { didSet { rawCGMManager = cgmManager?.rawValue + UserDefaults.standard.clearLegacyCGMManagerRawValue() } } diff --git a/FreeAPS/Sources/APS/Storage/CarbsStorage.swift b/FreeAPS/Sources/APS/Storage/CarbsStorage.swift index 6d81e58b4..209405002 100644 --- a/FreeAPS/Sources/APS/Storage/CarbsStorage.swift +++ b/FreeAPS/Sources/APS/Storage/CarbsStorage.swift @@ -232,8 +232,8 @@ final class BaseCarbsStorage: CarbsStorage, Injectable { bolus: nil, insulin: nil, carbs: $0.carbs, - fat: nil, - protein: nil, + fat: $0.fat, + protein: $0.protein, foodType: $0.note, targetTop: nil, targetBottom: nil diff --git a/FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift b/FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift index 489220de7..5b094bdf3 100644 --- a/FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift +++ b/FreeAPS/Sources/APS/Storage/PumpHistoryStorage.swift @@ -332,8 +332,8 @@ extension NightscoutTreatment { insulin: nil, notes: nil, carbs: Decimal(event.carbInput ?? 0), - fat: nil, - protein: nil, + fat: Decimal(event.fatInput ?? 0), + protein: Decimal(event.proteinInput ?? 0), targetTop: nil, targetBottom: nil ) diff --git a/FreeAPS/Sources/Helpers/PropertyWrappers/PersistedProperty.swift b/FreeAPS/Sources/Helpers/PropertyWrappers/PersistedProperty.swift index 3e50baa15..46419be33 100644 --- a/FreeAPS/Sources/Helpers/PropertyWrappers/PersistedProperty.swift +++ b/FreeAPS/Sources/Helpers/PropertyWrappers/PersistedProperty.swift @@ -57,7 +57,6 @@ import Foundation self.key = key let documents: URL - guard let localDocuments = try? FileManager.default.url( for: .documentDirectory, in: .userDomainMask, diff --git a/FreeAPS/Sources/Models/FreeAPSSettings.swift b/FreeAPS/Sources/Models/FreeAPSSettings.swift index 018b4bd28..41ea5b9a1 100644 --- a/FreeAPS/Sources/Models/FreeAPSSettings.swift +++ b/FreeAPS/Sources/Models/FreeAPSSettings.swift @@ -45,6 +45,7 @@ struct FreeAPSSettings: JSON, Equatable { var maxFat: Decimal = 250 var maxProtein: Decimal = 250 var displayFatAndProteinOnWatch: Bool = false + var confirmBolusFaster: Bool = false var onlyAutotuneBasals: Bool = false var useLiveActivity: Bool = false var lockScreenView: LockScreenView = .simple @@ -237,6 +238,10 @@ extension FreeAPSSettings: Decodable { settings.displayFatAndProteinOnWatch = displayFatAndProteinOnWatch } + if let confirmBolusFaster = try? container.decode(Bool.self, forKey: .confirmBolusFaster) { + settings.confirmBolusFaster = confirmBolusFaster + } + if let onlyAutotuneBasals = try? container.decode(Bool.self, forKey: .onlyAutotuneBasals) { settings.onlyAutotuneBasals = onlyAutotuneBasals } diff --git a/FreeAPS/Sources/Models/PumpHistoryEvent.swift b/FreeAPS/Sources/Models/PumpHistoryEvent.swift index e38f2082a..bb7a097c0 100644 --- a/FreeAPS/Sources/Models/PumpHistoryEvent.swift +++ b/FreeAPS/Sources/Models/PumpHistoryEvent.swift @@ -11,6 +11,8 @@ struct PumpHistoryEvent: JSON, Equatable { let rate: Decimal? let temp: TempType? let carbInput: Int? + let fatInput: Int? + let proteinInput: Int? let note: String? let isSMB: Bool? let isExternalInsulin: Bool? @@ -25,6 +27,8 @@ struct PumpHistoryEvent: JSON, Equatable { rate: Decimal? = nil, temp: TempType? = nil, carbInput: Int? = nil, + fatInput: Int? = nil, + proteinInput: Int? = nil, note: String? = nil, isSMB: Bool? = nil, isExternalInsulin: Bool? = nil @@ -38,6 +42,8 @@ struct PumpHistoryEvent: JSON, Equatable { self.rate = rate self.temp = temp self.carbInput = carbInput + self.fatInput = fatInput + self.proteinInput = proteinInput self.note = note self.isSMB = isSMB self.isExternalInsulin = isExternalInsulin @@ -88,6 +94,8 @@ extension PumpHistoryEvent { case rate case temp case carbInput = "carb_input" + case fatInput + case proteinInput case note case isSMB case isExternalInsulin diff --git a/FreeAPS/Sources/Modules/PreferencesEditor/PreferencesEditorDataFlow.swift b/FreeAPS/Sources/Modules/PreferencesEditor/PreferencesEditorDataFlow.swift index a2ba65417..1bbd54d6c 100644 --- a/FreeAPS/Sources/Modules/PreferencesEditor/PreferencesEditorDataFlow.swift +++ b/FreeAPS/Sources/Modules/PreferencesEditor/PreferencesEditorDataFlow.swift @@ -11,7 +11,11 @@ enum PreferencesEditor { enum FieldType { case boolean(keypath: WritableKeyPath) - case decimal(keypath: WritableKeyPath) + case decimal( + keypath: WritableKeyPath, + minVal: WritableKeyPath? = nil, + maxVal: WritableKeyPath? = nil + ) case insulinCurve(keypath: WritableKeyPath) } @@ -34,7 +38,7 @@ enum PreferencesEditor { var decimalValue: Decimal { get { switch type { - case let .decimal(keypath): + case let .decimal(keypath, _, _): return settable?.get(keypath) ?? 0 default: return 0 } @@ -57,8 +61,20 @@ enum PreferencesEditor { switch (type, value) { case let (.boolean(keypath), value as Bool): settable?.set(keypath, value: value) - case let (.decimal(keypath), value as Decimal): - settable?.set(keypath, value: value) + case let (.decimal(keypath, minVal, maxVal), value as Decimal): + let constrainedValue: Decimal + if let minValue = minVal, let minValueDecimal: Decimal = settable?.get(minValue), let maxValue = maxVal, + let maxValueDecimal: Decimal = settable?.get(maxValue) + { + constrainedValue = min(max(value, minValueDecimal), maxValueDecimal) + } else if let minValue = minVal, let minValueDecimal: Decimal = settable?.get(minValue) { + constrainedValue = max(value, minValueDecimal) + } else if let maxValue = maxVal, let maxValueDecimal: Decimal = settable?.get(maxValue) { + constrainedValue = min(value, maxValueDecimal) + } else { + constrainedValue = value + } + settable?.set(keypath, value: constrainedValue) case let (.insulinCurve(keypath), value as InsulinCurve): settable?.set(keypath, value: value) default: break diff --git a/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorProvider.swift b/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorProvider.swift index 255ea46bd..eb19bf223 100644 --- a/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorProvider.swift +++ b/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorProvider.swift @@ -19,7 +19,7 @@ extension PumpSettingsEditor { } func save(settings: PumpSettings) -> AnyPublisher { - func save() { + func save(_ settings: PumpSettings) { storage.save(settings, as: OpenAPS.Settings.settings) processQueue.async { self.broadcaster.notify(PumpSettingsObserver.self, on: self.processQueue) { @@ -29,7 +29,7 @@ extension PumpSettingsEditor { } guard let pump = deviceManager?.pumpManager else { - save() + save(settings) return Just(()).setFailureType(to: Error.self).eraseToAnyPublisher() } // Don't ask why 🤦‍♂️ @@ -44,8 +44,21 @@ extension PumpSettingsEditor { self.processQueue.async { pump.syncDeliveryLimits(limits: limits) { result in switch result { - case .success: - save() + case let .success(actual): + // Store the limits from the pumpManager to ensure the correct values + // Example: Dana pumps don't allow to set these limits, only to fetch them + // This will ensure we always have the correct values stored + save(PumpSettings( + insulinActionCurve: settings.insulinActionCurve, + maxBolus: Decimal( + actual.maximumBolus? + .doubleValue(for: .internationalUnit()) ?? Double(settings.maxBolus) + ), + maxBasal: Decimal( + actual.maximumBasalRate? + .doubleValue(for: .internationalUnitsPerHour) ?? Double(settings.maxBasal) + ) + )) promise(.success(())) case let .failure(error): promise(.failure(error)) diff --git a/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorStateModel.swift b/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorStateModel.swift index 8d1e5397b..a81dee9d8 100644 --- a/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorStateModel.swift +++ b/FreeAPS/Sources/Modules/PumpSettingsEditor/PumpSettingsEditorStateModel.swift @@ -25,7 +25,10 @@ extension PumpSettingsEditor { provider.save(settings: settings) .receive(on: DispatchQueue.main) .sink { _ in + let settings = self.provider.settings() self.syncInProgress = false + self.maxBasal = settings.maxBasal + self.maxBolus = settings.maxBolus } receiveValue: {} .store(in: &lifetime) diff --git a/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift b/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift index a62aaa1bb..3910fb3a7 100644 --- a/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift +++ b/FreeAPS/Sources/Modules/Settings/SettingsStateModel.swift @@ -62,6 +62,23 @@ extension Settings { func hideSettingsModal() { hideModal() } + + // Commenting this out for now, as not needed and possibly dangerous for users to be able to nuke their pump pairing informations via the debug menu + // Leaving it in here, as it may be a handy functionality for further testing or developers. + // See https://github.com/nightscout/Trio/pull/277 for more information +// +// func resetLoopDocuments() { +// guard let localDocuments = try? FileManager.default.url( +// for: .documentDirectory, +// in: .userDomainMask, +// appropriateFor: nil, +// create: true +// ) else { +// preconditionFailure("Could not get a documents directory URL.") +// } +// let storageURL = localDocuments.appendingPathComponent("PumpManagerState" + ".plist") +// try? FileManager.default.removeItem(at: storageURL) +// } } } diff --git a/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift b/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift index b46e098e9..fa56f5823 100644 --- a/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift +++ b/FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift @@ -61,6 +61,16 @@ extension Settings { .frame(maxWidth: .infinity, alignment: .trailing) .buttonStyle(.borderedProminent) } + // Commenting this out for now, as not needed and possibly dangerous for users to be able to nuke their pump pairing informations via the debug menu + // Leaving it in here, as it may be a handy functionality for further testing or developers. + // See https://github.com/nightscout/Trio/pull/277 for more information +// +// HStack { +// Text("Delete Stored Pump State Binary Files") +// Button("Delete") { state.resetLoopDocuments() } +// .frame(maxWidth: .infinity, alignment: .trailing) +// .buttonStyle(.borderedProminent) +// } } Group { Text("Preferences") diff --git a/FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigRootView.swift b/FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigRootView.swift index 2c3bae1df..bff2fb330 100644 --- a/FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigRootView.swift +++ b/FreeAPS/Sources/Modules/WatchConfig/View/WatchConfigRootView.swift @@ -17,10 +17,10 @@ extension WatchConfig { Text(v.displayName).tag(v) } } + Toggle("Display Protein & Fat", isOn: $state.displayFatAndProteinOnWatch) + Toggle("Confirm Bolus Faster", isOn: $state.confirmBolusFaster) } - Toggle("Display Protein & Fat", isOn: $state.displayFatAndProteinOnWatch) - Section(header: Text("Garmin Watch")) { List { ForEach(state.devices, id: \.uuid) { device in diff --git a/FreeAPS/Sources/Modules/WatchConfig/WatchConfigStateModel.swift b/FreeAPS/Sources/Modules/WatchConfig/WatchConfigStateModel.swift index 825fe2002..a4f52b0a6 100644 --- a/FreeAPS/Sources/Modules/WatchConfig/WatchConfigStateModel.swift +++ b/FreeAPS/Sources/Modules/WatchConfig/WatchConfigStateModel.swift @@ -31,6 +31,7 @@ extension WatchConfig { @Published var devices: [IQDevice] = [] @Published var selectedAwConfig: AwConfig = .HR @Published var displayFatAndProteinOnWatch = false + @Published var confirmBolusFaster = false private(set) var preferences = Preferences() @@ -38,6 +39,7 @@ extension WatchConfig { preferences = provider.preferences subscribeSetting(\.displayFatAndProteinOnWatch, on: $displayFatAndProteinOnWatch) { displayFatAndProteinOnWatch = $0 } + subscribeSetting(\.confirmBolusFaster, on: $confirmBolusFaster) { confirmBolusFaster = $0 } subscribeSetting(\.displayOnWatch, on: $selectedAwConfig) { selectedAwConfig = $0 } didSet: { [weak self] value in // for compatibility with old displayHR diff --git a/FreeAPS/Sources/Services/WatchManager/WatchManager.swift b/FreeAPS/Sources/Services/WatchManager/WatchManager.swift index 7788689db..f28c44f4c 100644 --- a/FreeAPS/Sources/Services/WatchManager/WatchManager.swift +++ b/FreeAPS/Sources/Services/WatchManager/WatchManager.swift @@ -106,6 +106,7 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable { self.state.bolusAfterCarbs = !self.settingsManager.settings.skipBolusScreenAfterCarbs self.state.displayOnWatch = self.settingsManager.settings.displayOnWatch self.state.displayFatAndProteinOnWatch = self.settingsManager.settings.displayFatAndProteinOnWatch + self.state.confirmBolusFaster = self.settingsManager.settings.confirmBolusFaster let eBG = self.evetualBGStraing() self.state.eventualBG = eBG.map { "⇢ " + $0 } diff --git a/FreeAPSWatch WatchKit Extension/DataFlow.swift b/FreeAPSWatch WatchKit Extension/DataFlow.swift index cf4b81602..4037bf41c 100644 --- a/FreeAPSWatch WatchKit Extension/DataFlow.swift +++ b/FreeAPSWatch WatchKit Extension/DataFlow.swift @@ -22,6 +22,7 @@ struct WatchState: Codable { var eventualBGRaw: String? var displayOnWatch: AwConfig? var displayFatAndProteinOnWatch: Bool? + var confirmBolusFaster: Bool? var isf: Decimal? var override: String? } diff --git a/FreeAPSWatch WatchKit Extension/Views/BolusConfirmationView.swift b/FreeAPSWatch WatchKit Extension/Views/BolusConfirmationView.swift index c141bb508..02cef6e27 100644 --- a/FreeAPSWatch WatchKit Extension/Views/BolusConfirmationView.swift +++ b/FreeAPSWatch WatchKit Extension/Views/BolusConfirmationView.swift @@ -75,7 +75,7 @@ struct BolusConfirmationView: View { $crownProgress, from: 0.0, through: 100.0, - by: 0.5, + by: state.confirmBolusFaster ? 5 : 0.5, sensitivity: .high, isContinuous: false, isHapticFeedbackEnabled: true diff --git a/FreeAPSWatch WatchKit Extension/WatchStateModel.swift b/FreeAPSWatch WatchKit Extension/WatchStateModel.swift index 8d5a7b20b..0994564a8 100644 --- a/FreeAPSWatch WatchKit Extension/WatchStateModel.swift +++ b/FreeAPSWatch WatchKit Extension/WatchStateModel.swift @@ -34,6 +34,7 @@ class WatchStateModel: NSObject, ObservableObject { @Published var isBolusViewActive = false @Published var displayOnWatch: AwConfig = .BGTarget @Published var displayFatAndProteinOnWatch = false + @Published var confirmBolusFaster = false @Published var eventualBG = "" @Published var isConfirmationViewActive = false { didSet { @@ -174,6 +175,7 @@ class WatchStateModel: NSObject, ObservableObject { eventualBG = state.eventualBG ?? "" displayOnWatch = state.displayOnWatch ?? .BGTarget displayFatAndProteinOnWatch = state.displayFatAndProteinOnWatch ?? false + confirmBolusFaster = state.confirmBolusFaster ?? false isf = state.isf override = state.override }