From a21c524589a626b6260b631ca3df87fef50fab99 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:33:30 +0200 Subject: [PATCH 01/11] Corrections to G6 sensorStartDate handling It could happen that an internal sensor session was manually started some time after the transmitter-based session was already running. This change allows both "before and after" start date variations from the transmitter to force a new sensor session to be started with the correct (transmitter-based) start date. --- .../BluetoothTransmitter/CGM/Dexcom/G5/CGMG5Transmitter.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xdrip/BluetoothTransmitter/CGM/Dexcom/G5/CGMG5Transmitter.swift b/xdrip/BluetoothTransmitter/CGM/Dexcom/G5/CGMG5Transmitter.swift index 07e79619f..c19df2a90 100644 --- a/xdrip/BluetoothTransmitter/CGM/Dexcom/G5/CGMG5Transmitter.swift +++ b/xdrip/BluetoothTransmitter/CGM/Dexcom/G5/CGMG5Transmitter.swift @@ -1287,7 +1287,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter { var forceNewSensor = false - if let sensorStartDate = self.sensorStartDate, let activeSensorStartDate = UserDefaults.standard.activeSensorStartDate, activeSensorStartDate < sensorStartDate.addingTimeInterval(-15.0) { + if let sensorStartDate = self.sensorStartDate, let activeSensorStartDate = UserDefaults.standard.activeSensorStartDate, activeSensorStartDate < sensorStartDate.addingTimeInterval(-15.0) || activeSensorStartDate > sensorStartDate.addingTimeInterval(15.0) { forceNewSensor = true } @@ -1327,7 +1327,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter { var forceNewSensor = false - if let sensorStartDate = self.sensorStartDate, let activeSensorStartDate = UserDefaults.standard.activeSensorStartDate, activeSensorStartDate < sensorStartDate.addingTimeInterval(-15.0) { + if let sensorStartDate = self.sensorStartDate, let activeSensorStartDate = UserDefaults.standard.activeSensorStartDate, activeSensorStartDate < sensorStartDate.addingTimeInterval(-15.0) || activeSensorStartDate > sensorStartDate.addingTimeInterval(15.0) { forceNewSensor = true } From 4f6f9dd34d3095506e6e021d9a7a8738666378c8 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:22:38 +0200 Subject: [PATCH 02/11] correction to AlertManager logging --- xdrip/Managers/Alerts/AlertManager.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xdrip/Managers/Alerts/AlertManager.swift b/xdrip/Managers/Alerts/AlertManager.swift index a00717691..14dc984c1 100644 --- a/xdrip/Managers/Alerts/AlertManager.swift +++ b/xdrip/Managers/Alerts/AlertManager.swift @@ -822,8 +822,8 @@ public class AlertManager:NSObject { return true } else { - if !UserDefaults.standard.isMaster && !UserDefaults.standard.followerBackgroundKeepAliveType.shouldKeepAlive { - trace("in checkAlert, there's no need to raise alert %{public}@ because we're in follower mode and keep-alive is: %{public}@", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging(), UserDefaults.standard.followerBackgroundKeepAliveType.description) + if !UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled { + trace("in checkAlert, there's no need to raise alert '%{public}@' because we're in follower mode and keep-alive is disabled", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging()) } else { trace("in checkAlert, there's no need to raise alert %{public}@", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging()) } From ba7495598f0cb3390fff69f05b1a2a295a346766 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:26:05 +0200 Subject: [PATCH 03/11] update to LiveActivity logging --- .../Managers/LiveActivity/LiveActivityManager.swift | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/xdrip/Managers/LiveActivity/LiveActivityManager.swift b/xdrip/Managers/LiveActivity/LiveActivityManager.swift index 5cb097e85..7869133fe 100644 --- a/xdrip/Managers/LiveActivity/LiveActivityManager.swift +++ b/xdrip/Managers/LiveActivity/LiveActivityManager.swift @@ -40,21 +40,18 @@ extension LiveActivityManager { /// - Parameter contentState: the contentState to show /// - Parameter forceRestart: will force the function to end and restart the live activity func runActivity(contentState: XDripWidgetAttributes.ContentState, forceRestart: Bool) { - - trace("in runActivity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) - // checking whether 'Live activities' is enabled for the app in settings if ActivityAuthorizationInfo().areActivitiesEnabled { // live activities are enabled. Now check if there is a currently // running activity (in which case update it) or if not, start a new one if eventActivity == nil { - trace(" starting new live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) + trace("in runActivity, starting new live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) startActivity(contentState: contentState) } else if forceRestart && eventStartDate < Date().addingTimeInterval(-ConstantsLiveActivity.allowLiveActivityRestartAfterMinutes) { // force an end/start cycle of the activity when the app comes to the foreground assuming at least 'x' hours have passed. This restarts the 8 hour limit. - trace(" restarting live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) + trace("in runActivity, restarting live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) Task { await endActivity() @@ -62,21 +59,21 @@ extension LiveActivityManager { } } else if eventStartDate < Date().addingTimeInterval(-ConstantsLiveActivity.endLiveActivityAfterMinutes) { // if the activity has been running for almost 8 hours, proactively end the activity before it goes stale - trace(" ending live activity on purpose to avoid staying on the screen when stale", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) + trace("in runActivity, ending live activity on purpose to avoid staying on the screen when stale", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) Task { await endActivity() } } else { // none of the above conditions are true so let's just update the activity - trace(" updating live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) + trace("in runActivity, updating live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) Task { await updateActivity(to: contentState) } } } else { - trace(" live activities are disabled in the iPhone Settings or permission has not been given.", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) + trace("in runActivity, live activities are disabled in the iPhone Settings or permission has not been given.", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info) } } From 7c1d9d51eeaa413bc19772b9b53840a1092ca935 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:38:33 +0200 Subject: [PATCH 04/11] Fix to allow Contact Image to work correctly for follower modes --- .../Root View Controller/RootViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xdrip/View Controllers/Root View Controller/RootViewController.swift b/xdrip/View Controllers/Root View Controller/RootViewController.swift index 0f72ca5b1..e0870abb8 100644 --- a/xdrip/View Controllers/Root View Controller/RootViewController.swift +++ b/xdrip/View Controllers/Root View Controller/RootViewController.swift @@ -3988,6 +3988,8 @@ extension RootViewController: FollowerDelegate { // ask calendarManager to process new reading, ignore last connection change timestamp because this is follower mode, there is no connection to a transmitter calendarManager?.processNewReading(lastConnectionStatusChangeTimeStamp: nil) + contactImageManager?.processNewReading() + loopManager?.share() watchManager?.updateWatchApp(forceComplicationUpdate: false) From d831908e5eb4ab06d8001a9f9066f42f5d2246d7 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:50:35 +0200 Subject: [PATCH 05/11] Rename "Transmitter Algorithm" to "Native Algorithm" This makes it clearer... the idea of a transmitter algorithm is confusing for Libre users and doesn't really explain what it is. At least for now, Native explains that the values will resemble (or be identical to) the factory algorithms in all cases. This may change in the future, but for now, it's accurate enough for the description. --- .../BluetoothPeripheral/AlgorithmType.swift | 12 ++++------ .../Texts/TextsBluetoothPeripheralView.swift | 6 ++--- .../BluetoothPeripheralViewController.swift | 22 +++++++++---------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/xdrip/Managers/BluetoothPeripheral/AlgorithmType.swift b/xdrip/Managers/BluetoothPeripheral/AlgorithmType.swift index 07e7b7f7f..efdae54ce 100644 --- a/xdrip/Managers/BluetoothPeripheral/AlgorithmType.swift +++ b/xdrip/Managers/BluetoothPeripheral/AlgorithmType.swift @@ -8,19 +8,15 @@ import Foundation -/// types of live activity, namely when we should show the live activities +/// types of algorithms available to use public enum AlgorithmType: Int, CaseIterable { - - // when adding to LiveActivityType, add new cases at the end (ie 3, ...) - // if this is done in the middle then a database migration would be required, because the rawvalue is stored as Int16 in the coredata - - case transmitterAlgorithm = 0 + case nativeAlgorithm = 0 case xDripAlgorithm = 1 var description: String { switch self { - case .transmitterAlgorithm: - return Texts_BluetoothPeripheralView.transmitterAlgorithm + case .nativeAlgorithm: + return Texts_BluetoothPeripheralView.nativeAlgorithm case .xDripAlgorithm: return Texts_BluetoothPeripheralView.xDripAlgorithm } diff --git a/xdrip/Texts/TextsBluetoothPeripheralView.swift b/xdrip/Texts/TextsBluetoothPeripheralView.swift index 2cec441c2..dce57c95b 100644 --- a/xdrip/Texts/TextsBluetoothPeripheralView.swift +++ b/xdrip/Texts/TextsBluetoothPeripheralView.swift @@ -148,12 +148,12 @@ class Texts_BluetoothPeripheralView { return NSLocalizedString("warmingUpUntil", tableName: filename, bundle: Bundle.main, value: "Warming up until", comment: "sensor warm-up text") }() - static let transmitterAlgorithm: String = { - return NSLocalizedString("transmitterAlgorithm", tableName: filename, bundle: Bundle.main, value: "Transmitter", comment: "transmitter algorithm type text") + static let nativeAlgorithm: String = { + return NSLocalizedString("nativeAlgorithm", tableName: filename, bundle: Bundle.main, value: "Native Algorithm", comment: "native or transmitter algorithm type text") }() static let xDripAlgorithm: String = { - return NSLocalizedString("xDripAlgorithm", tableName: filename, bundle: Bundle.main, value: "xDrip", comment: "xDrip algorithm type text") + return NSLocalizedString("xDripAlgorithm", tableName: filename, bundle: Bundle.main, value: "xDrip Algorithm", comment: "xDrip algorithm type text") }() static let confirmAlgorithmChangeToTransmitterMessage: String = { diff --git a/xdrip/View Controllers/BluetoothPeripheralsNavigationController/BluetoothPeripheralsViewController/BluetoothPeripheralViewController/BluetoothPeripheralViewController.swift b/xdrip/View Controllers/BluetoothPeripheralsNavigationController/BluetoothPeripheralsViewController/BluetoothPeripheralViewController/BluetoothPeripheralViewController.swift index 31571639b..87580ea3a 100644 --- a/xdrip/View Controllers/BluetoothPeripheralsNavigationController/BluetoothPeripheralsViewController/BluetoothPeripheralViewController/BluetoothPeripheralViewController.swift +++ b/xdrip/View Controllers/BluetoothPeripheralsNavigationController/BluetoothPeripheralsViewController/BluetoothPeripheralViewController/BluetoothPeripheralViewController.swift @@ -1343,7 +1343,7 @@ extension BluetoothPeripheralViewController: UITableViewDataSource, UITableViewD } cell.textLabel?.text = Texts_SettingsView.labelAlgorithmType - cell.detailTextLabel?.text = currentWebOOPEnabledValue ? Texts_BluetoothPeripheralView.transmitterAlgorithm : Texts_BluetoothPeripheralView.xDripAlgorithm + cell.detailTextLabel?.text = currentWebOOPEnabledValue ? Texts_BluetoothPeripheralView.nativeAlgorithm : Texts_BluetoothPeripheralView.xDripAlgorithm cell.accessoryType = .disclosureIndicator cell.accessoryView = disclosureAccessoryView @@ -1479,13 +1479,13 @@ extension BluetoothPeripheralViewController: UITableViewDataSource, UITableViewD // first off all check that BluetoothPeripheral already exists guard let bluetoothPeripheral = bluetoothPeripheral else {return} - // data to be displayed in list from which user needs to pick a live activity type + // data to be displayed in list from which user needs to pick an algorithm type var data = [String]() var selectedRow: Int? var index = 0 - let currentAlgorithmType = bluetoothPeripheral.blePeripheral.webOOPEnabled ? AlgorithmType.transmitterAlgorithm : AlgorithmType.xDripAlgorithm + let currentAlgorithmType = bluetoothPeripheral.blePeripheral.webOOPEnabled ? AlgorithmType.nativeAlgorithm : AlgorithmType.xDripAlgorithm - // get all data source types and add the description to data. Search for the type that matches the FollowerDataSourceType that is currently stored in userdefaults. + // get all data source types and add the description to data. Search for the type that matches the AlgorithmType that is currently stored in userdefaults. for algorithmType in AlgorithmType.allCases { data.append(algorithmType.description) @@ -1502,20 +1502,20 @@ extension BluetoothPeripheralViewController: UITableViewDataSource, UITableViewD let oldAlgorithmType = currentAlgorithmType if index != selectedRow { - let newAlgorithmType = AlgorithmType(rawValue: index) ?? .transmitterAlgorithm + let newAlgorithmType = AlgorithmType(rawValue: index) ?? .nativeAlgorithm // create uialertcontroller to ask the user if they really want to change algorithm - let confirmAlgorithmChangeAlertController = UIAlertController(title: Texts_SettingsView.labelAlgorithmType , message: newAlgorithmType == .transmitterAlgorithm ? Texts_BluetoothPeripheralView.confirmAlgorithmChangeToTransmitterMessage : Texts_BluetoothPeripheralView.confirmAlgorithmChangeToxDripMessage, preferredStyle: .alert) + let confirmAlgorithmChangeAlertController = UIAlertController(title: Texts_SettingsView.labelAlgorithmType , message: newAlgorithmType == .nativeAlgorithm ? Texts_BluetoothPeripheralView.confirmAlgorithmChangeToTransmitterMessage : Texts_BluetoothPeripheralView.confirmAlgorithmChangeToxDripMessage, preferredStyle: .alert) // create buttons for UIAlertController let OKAction = UIAlertAction(title: Texts_BluetoothPeripheralView.confirm, style: .default) { (action:UIAlertAction!) in - bluetoothPeripheral.blePeripheral.webOOPEnabled = (newAlgorithmType == .transmitterAlgorithm) ? true : false + bluetoothPeripheral.blePeripheral.webOOPEnabled = (newAlgorithmType == .nativeAlgorithm) ? true : false - bluetoothPeripheralManager.receivedNewValue(webOOPEnabled: (newAlgorithmType == .transmitterAlgorithm) ? true : false, for: bluetoothPeripheral) + bluetoothPeripheralManager.receivedNewValue(webOOPEnabled: (newAlgorithmType == .nativeAlgorithm) ? true : false, for: bluetoothPeripheral) - if newAlgorithmType == .transmitterAlgorithm { + if newAlgorithmType == .nativeAlgorithm { bluetoothPeripheral.blePeripheral.nonFixedSlopeEnabled = false bluetoothPeripheralManager.receivedNewValue(nonFixedSlopeEnabled: false, for: bluetoothPeripheral) } @@ -1564,7 +1564,7 @@ extension BluetoothPeripheralViewController: UITableViewDataSource, UITableViewD var index = 0 let currentCalibrationType = bluetoothPeripheral.blePeripheral.nonFixedSlopeEnabled ? CalibrationType.multiPoint : CalibrationType.singlePoint - // get all data source types and add the description to data. Search for the type that matches the FollowerDataSourceType that is currently stored in userdefaults. + // get all data source types and add the description to data. Search for the type that matches the CalibrationType that is currently stored in userdefaults. for calibrationType in CalibrationType.allCases { data.append(calibrationType.description) @@ -1583,7 +1583,7 @@ extension BluetoothPeripheralViewController: UITableViewDataSource, UITableViewD if index != selectedRow { let newCalibrationType = CalibrationType(rawValue: index) ?? .singlePoint - // create uialertcontroller to ask the user if they really want to change algorithm + // create uialertcontroller to ask the user if they really want to change calibration type let confirmCalibrationChangeAlertController = UIAlertController(title: Texts_SettingsView.labelCalibrationType , message: newCalibrationType == .singlePoint ? Texts_BluetoothPeripheralView.confirmCalibrationChangeToSinglePointMessage : Texts_BluetoothPeripheralView.confirmCalibrationChangeToMultiPointMessage, preferredStyle: .alert) // create buttons for UIAlertController From 048569e3bef84b8fd80b5bb20d06b3e143006662 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:00:22 +0200 Subject: [PATCH 06/11] increase maxSensorAgeInDays to 10.5 for G7/ONE+ - to allow for the 12 hour grace period --- .../BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift | 2 +- xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift | 4 ++-- xdrip/Constants/ConstantsDexcomG7.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift b/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift index 3b94a1755..db94e2a99 100644 --- a/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift +++ b/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift @@ -112,7 +112,7 @@ class CGMG7Transmitter: BluetoothTransmitter, CGMTransmitter { init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG7TransmitterDelegate: CGMG7TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) { // assign addressname and name or expected devicename - // For G7 we don't listen for a specific device name. Dexcom uses an advertising id, which already filters out all other devices (like tv's etc. We will verify in another way that we have the current active G7, and not an old one, which is still near + // For G7/ONE+ we don't listen for a specific device name. Dexcom uses an advertising id, which already filters out all other devices (like tv's etc. We will verify in another way that we have the current active G7/ONE+, and not an old one, which is still near var newAddressAndName: BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "DX") if let name = name { diff --git a/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift b/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift index 30f94cb5d..81e63da29 100644 --- a/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift +++ b/xdrip/BluetoothTransmitter/CGM/Generic/CGMTransmitter.swift @@ -82,10 +82,10 @@ enum CGMTransmitterType:String, CaseIterable { case dexcomG4 = "Dexcom G4" /// dexcom G5, G6 - case dexcom = "Dexcom" + case dexcom = "Dexcom G5/G6/ONE" /// dexcom G7 - case dexcomG7 = "Dexcom G7" + case dexcomG7 = "Dexcom G7/ONE+" /// miaomiao case miaomiao = "MiaoMiao" diff --git a/xdrip/Constants/ConstantsDexcomG7.swift b/xdrip/Constants/ConstantsDexcomG7.swift index 7d5ed1de1..82b6f1ccc 100644 --- a/xdrip/Constants/ConstantsDexcomG7.swift +++ b/xdrip/Constants/ConstantsDexcomG7.swift @@ -12,6 +12,6 @@ enum ConstantsDexcomG7 { static let minimumTimeBetweenTwoReadings = TimeInterval(minutes: 2.1) /// how many days the sensor session lasts - static let maxSensorAgeInDays: Double = 10.0 + static let maxSensorAgeInDays: Double = 10.5 } From bf7ba4add4e6686fae0267e7268ccb340777c4da Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Sat, 12 Oct 2024 12:34:08 +0200 Subject: [PATCH 07/11] change LibreLinkUpFollower to work with no active sensor data Since LLU 4.12.0, it seems that the server response can now sometimes return an empty activeSensor attribute. This caused xDrip4iOS to throw an error and not process downloaded data. This issue is known to affect just a handful of users and does not always happen. Sometimes the server responds correctly with all data. We'll now just treat this as optional and ignore it (and adapt/hide the UI as needed) if necessary. --- .../LibreLinkUp/LibreLinkUpFollowManager.swift | 13 +++++++------ xdrip/Storyboards/ar.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/da.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/de.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/el.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/en.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/es.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/fi.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/fr.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/it.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/nl.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/pl-PL.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/pt.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/ru.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/sl.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/sv.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/tr.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/uk.lproj/SettingsViews.strings | 2 +- xdrip/Storyboards/zh.lproj/SettingsViews.strings | 2 +- xdrip/Texts/TextsSettingsView.swift | 2 +- .../Root View Controller/RootViewController.swift | 5 ----- .../SettingsViewDataSourceSettingsViewModel.swift | 4 ++-- 22 files changed, 28 insertions(+), 32 deletions(-) diff --git a/xdrip/Managers/LibreLinkUp/LibreLinkUpFollowManager.swift b/xdrip/Managers/LibreLinkUp/LibreLinkUpFollowManager.swift index 7f32c4e0d..4ea946c60 100644 --- a/xdrip/Managers/LibreLinkUp/LibreLinkUpFollowManager.swift +++ b/xdrip/Managers/LibreLinkUp/LibreLinkUpFollowManager.swift @@ -253,6 +253,7 @@ class LibreLinkUpFollowManager: NSObject { let graphResponse = try await requestGraph(patientId: patientId) // before processing the glucoseMeasurement values, let's set up the sensor info in coredata so that we can show it to the user in the settings screen + // starting with LLU 4.12.0 this data sometimes isn't sent for some users so we'll try and use it if available and if not, just continue as normal without throwing an error if let startDate = graphResponse.data?.activeSensors?.first?.sensor?.a, let serialNumber = graphResponse.data?.activeSensors?.first?.sensor?.sn { @@ -266,12 +267,12 @@ class LibreLinkUpFollowManager: NSObject { if serialNumber.range(of: #"^MH"#, options: .regularExpression) != nil { // MHxxxxxxxx - // must be a L2 sensor + // must be a L2 (or Libre 2 Plus) sensor activeSensorDescription = "Libre 2" } else if serialNumber.range(of: #"^0D"#, options: .regularExpression) != nil || serialNumber.range(of: #"^0E"#, options: .regularExpression) != nil || serialNumber.range(of: #"^0F"#, options: .regularExpression) != nil{ - // must be a Libre 3 sensor + // must be a Libre 3 (or Libre 3 Plus) sensor activeSensorDescription = "Libre 3" } @@ -281,9 +282,12 @@ class LibreLinkUpFollowManager: NSObject { } else { // this will only happen if the account doesn't have an active sensor connected + // reset the data just in case it was previously stored resetActiveSensorData() - throw LibreLinkUpFollowError.generalError + // for some reason no active sensor data was sent by the server. This seems to sometimes happen since LLU v4.12.0 for some users and for some (unknown) reason. + // instead of throwing an error, we'll just continue as normal and hide later (in the UI) the sensor information + trace(" in download, no active sensor data was returned by the server so just process the values if any", log: self.log, category: ConstantsLog.categoryLibreLinkUpFollowManager, type: .info) } @@ -305,9 +309,6 @@ class LibreLinkUpFollowManager: NSObject { followerDelegate.followerInfoReceived(followGlucoseDataArray: &followGlucoseDataArray) } - // schedule new download - //self.scheduleNewDownload() - } } diff --git a/xdrip/Storyboards/ar.lproj/SettingsViews.strings b/xdrip/Storyboards/ar.lproj/SettingsViews.strings index 6aa1a2a42..da66744f1 100644 --- a/xdrip/Storyboards/ar.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/ar.lproj/SettingsViews.strings @@ -156,7 +156,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/da.lproj/SettingsViews.strings b/xdrip/Storyboards/da.lproj/SettingsViews.strings index 3522189e2..a56e062c8 100644 --- a/xdrip/Storyboards/da.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/da.lproj/SettingsViews.strings @@ -145,7 +145,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/de.lproj/SettingsViews.strings b/xdrip/Storyboards/de.lproj/SettingsViews.strings index ff64dd041..ea7416f75 100644 --- a/xdrip/Storyboards/de.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/de.lproj/SettingsViews.strings @@ -370,7 +370,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/el.lproj/SettingsViews.strings b/xdrip/Storyboards/el.lproj/SettingsViews.strings index fcbce97bf..1f5b97af5 100644 --- a/xdrip/Storyboards/el.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/el.lproj/SettingsViews.strings @@ -135,7 +135,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/en.lproj/SettingsViews.strings b/xdrip/Storyboards/en.lproj/SettingsViews.strings index 97f18be4f..483de526e 100644 --- a/xdrip/Storyboards/en.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/en.lproj/SettingsViews.strings @@ -29,7 +29,7 @@ "settingsviews_enterUsername" = "Enter your username (e-mail)"; "settingsviews_enterPassword" = "Enter your password"; "settingsviews_libreLinkUpReAcceptNeeded" = "Need to accept terms"; -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; "settingsviews_showReadingInNotification" = "Show BG in Notifications"; "settingsviews_labelShowReadingInAppBadge" = "Show BG in the App Badge"; "settingsviews_multipleAppBadgeValueWith10" = "Multiply App Badge Reading by 10"; diff --git a/xdrip/Storyboards/es.lproj/SettingsViews.strings b/xdrip/Storyboards/es.lproj/SettingsViews.strings index 4160c4dd1..24efe3328 100644 --- a/xdrip/Storyboards/es.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/es.lproj/SettingsViews.strings @@ -24,7 +24,7 @@ "settingsviews_enterUsername" = "Entrar tu usuario (e-mail)"; "settingsviews_enterPassword" = "Entrar tu contraseña"; "settingsviews_libreLinkUpReAcceptNeeded" = "Aceptar terminos"; -"settingsviews_libreLinkUpNoActiveSensor" = "Sin sensor activo"; +"settingsviews_libreLinkUpNoActiveSensor" = "Sin datos de sensor activo"; "settingsviews_translateOnlineHelp" = "Traducir Documentación"; "settingsviews_showHelpIcon" = "Mostrar icono"; "settingsviews_restartNeeded" = "(Pendiente reiniciar)"; diff --git a/xdrip/Storyboards/fi.lproj/SettingsViews.strings b/xdrip/Storyboards/fi.lproj/SettingsViews.strings index 5461653e3..c68da7b58 100644 --- a/xdrip/Storyboards/fi.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/fi.lproj/SettingsViews.strings @@ -186,7 +186,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/fr.lproj/SettingsViews.strings b/xdrip/Storyboards/fr.lproj/SettingsViews.strings index e8b7a5c31..4228888d8 100644 --- a/xdrip/Storyboards/fr.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/fr.lproj/SettingsViews.strings @@ -211,7 +211,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/it.lproj/SettingsViews.strings b/xdrip/Storyboards/it.lproj/SettingsViews.strings index fd5eca5c3..2ae7d44c2 100644 --- a/xdrip/Storyboards/it.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/it.lproj/SettingsViews.strings @@ -408,7 +408,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/nl.lproj/SettingsViews.strings b/xdrip/Storyboards/nl.lproj/SettingsViews.strings index 857f66af9..f98946671 100644 --- a/xdrip/Storyboards/nl.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/nl.lproj/SettingsViews.strings @@ -204,7 +204,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/pl-PL.lproj/SettingsViews.strings b/xdrip/Storyboards/pl-PL.lproj/SettingsViews.strings index fd5eca5c3..2ae7d44c2 100644 --- a/xdrip/Storyboards/pl-PL.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/pl-PL.lproj/SettingsViews.strings @@ -408,7 +408,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/pt.lproj/SettingsViews.strings b/xdrip/Storyboards/pt.lproj/SettingsViews.strings index f8725d93b..28c7fccf0 100644 --- a/xdrip/Storyboards/pt.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/pt.lproj/SettingsViews.strings @@ -158,7 +158,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/ru.lproj/SettingsViews.strings b/xdrip/Storyboards/ru.lproj/SettingsViews.strings index 971ca16ef..64a9bbe68 100644 --- a/xdrip/Storyboards/ru.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/ru.lproj/SettingsViews.strings @@ -135,7 +135,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/sl.lproj/SettingsViews.strings b/xdrip/Storyboards/sl.lproj/SettingsViews.strings index 0be28e44d..7f53bc2d2 100644 --- a/xdrip/Storyboards/sl.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/sl.lproj/SettingsViews.strings @@ -408,7 +408,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/sv.lproj/SettingsViews.strings b/xdrip/Storyboards/sv.lproj/SettingsViews.strings index 8ef5552f4..df03e9377 100644 --- a/xdrip/Storyboards/sv.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/sv.lproj/SettingsViews.strings @@ -167,7 +167,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/tr.lproj/SettingsViews.strings b/xdrip/Storyboards/tr.lproj/SettingsViews.strings index a09673eb2..50d954daf 100644 --- a/xdrip/Storyboards/tr.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/tr.lproj/SettingsViews.strings @@ -121,7 +121,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/uk.lproj/SettingsViews.strings b/xdrip/Storyboards/uk.lproj/SettingsViews.strings index f273fae33..57f1fe78f 100644 --- a/xdrip/Storyboards/uk.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/uk.lproj/SettingsViews.strings @@ -368,7 +368,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Storyboards/zh.lproj/SettingsViews.strings b/xdrip/Storyboards/zh.lproj/SettingsViews.strings index 74aba4c2c..628f26360 100644 --- a/xdrip/Storyboards/zh.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/zh.lproj/SettingsViews.strings @@ -333,7 +333,7 @@ "settingsviews_followerKeepAliveTypeAggressiveMessage" = "Background keep-alive is set to aggressive.\n\nWhen the app is not on screen, we will aggressively attempt to keep it running for you in the background so that BG updates are received and alarms can be triggered.\n\nThis mode has a very noticeable impact on the battery of your device and should only be used if absolutely necessary."; /// libre link up follower settings, no active sensor -"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor"; +"settingsviews_libreLinkUpNoActiveSensor" = "No active sensor data"; /// data source settings, keep-alive mode is set to disabled "settingsviews_followerKeepAliveTypeDisabledMessage" = "Background keep-alive is disabled.\n\nWhen the app is not on screen, no alarms, app badges, notifications or BG updates will take place.\n\nThe app will remain sleeping until you open it again.\n\nThis mode has very little impact on the battery of your device."; diff --git a/xdrip/Texts/TextsSettingsView.swift b/xdrip/Texts/TextsSettingsView.swift index 7d473430f..2ee651104 100644 --- a/xdrip/Texts/TextsSettingsView.swift +++ b/xdrip/Texts/TextsSettingsView.swift @@ -157,7 +157,7 @@ class Texts_SettingsView { }() static let libreLinkUpNoActiveSensor = { - return NSLocalizedString("settingsviews_libreLinkUpNoActiveSensor", tableName: filename, bundle: Bundle.main, value: "No active sensor", comment: "libre link up follower settings, no active sensor") + return NSLocalizedString("settingsviews_libreLinkUpNoActiveSensor", tableName: filename, bundle: Bundle.main, value: "No active sensor data", comment: "libre link up follower settings, no active sensor") }() // MARK: - Section Notifications diff --git a/xdrip/View Controllers/Root View Controller/RootViewController.swift b/xdrip/View Controllers/Root View Controller/RootViewController.swift index e0870abb8..016da0869 100644 --- a/xdrip/View Controllers/Root View Controller/RootViewController.swift +++ b/xdrip/View Controllers/Root View Controller/RootViewController.swift @@ -3305,11 +3305,6 @@ final class RootViewController: UIViewController, ObservableObject { dataSourceSensorMaxAgeOutlet.textColor = .systemRed dataSourceSensorMaxAgeOutlet.text = Texts_HomeView.libreLinkUpAccountCredentialsMissing - } else if sensorStartDate == nil || sensorMaxAgeInMinutes == 0 { - - dataSourceSensorMaxAgeOutlet.textColor = .systemRed - dataSourceSensorMaxAgeOutlet.text = Texts_HomeView.noSensorData - } } diff --git a/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewDataSourceSettingsViewModel.swift b/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewDataSourceSettingsViewModel.swift index 82de275ee..0af768d93 100644 --- a/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewDataSourceSettingsViewModel.swift +++ b/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewDataSourceSettingsViewModel.swift @@ -525,7 +525,7 @@ class SettingsViewDataSourceSettingsViewModel: NSObject, SettingsViewModelProtoc } else { - return "" + return "-" } default: return "" @@ -546,7 +546,7 @@ class SettingsViewDataSourceSettingsViewModel: NSObject, SettingsViewModelProtoc return returnString } else { - return "" + return "-" } default: From 0986d7eba17629f07e23506aecc7b29fcf4e91a0 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:17:46 +0200 Subject: [PATCH 08/11] avoid G7/ONE+ values after sensor expiry G7/ONE+ has the peculiarity that it will keep sending/repeating the same BG value (without ever changing) via BLE even after the session officially ends. This change just stops processing received values after maxSensorAgeInDays is reached (10.5 days for G7/ONE+) Also updated the sensor progress colours from (gray/yellow/red and purple for expired) to (gray/yellow/orange and red for expired). This is because purple is pretty impossible to read clearly against a black background. --- .../CGM/Dexcom/G7/CGMG7Transmitter.swift | 18 +++++++++++++++--- xdrip/Constants/ConstantsDexcomG7.swift | 2 +- xdrip/Constants/ConstantsHomeView.swift | 8 ++++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift b/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift index db94e2a99..b682342ed 100644 --- a/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift +++ b/xdrip/BluetoothTransmitter/CGM/Dexcom/G7/CGMG7Transmitter.swift @@ -209,8 +209,20 @@ class CGMG7Transmitter: BluetoothTransmitter, CGMTransmitter { trace(" failed to create G7GlucoseMessage", log: log, category: ConstantsLog.categoryCGMG7, type: .error ) return } - - trace(" received g7GlucoseMessage mesage, calculatedValue = %{public}@, timeStamp = %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, g7GlucoseMessage.calculatedValue.description, g7GlucoseMessage.timeStamp.description(with: .current)) + + let maxSensorAgeInDays = ConstantsDexcomG7.maxSensorAgeInDays + let sensorAgeInDays = Double(round((g7GlucoseMessage.sensorAge / 3600 / 24) * 10) / 10) + + // G7/ONE+ has the peculiarity that it will keep sending/repeating the same BG value (without ever changing) via BLE even after the session officially ends. + // to avoid this, let's check if the sensor is still within maxSensorAge before we continue + guard sensorAgeInDays < maxSensorAgeInDays else { + trace(" G7 is expired so will not process reading. sensorAge: %{public}@ / maxSensorAgeInDays: %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .error, sensorAgeInDays.description, maxSensorAgeInDays.description) + return + } + + trace(" received g7GlucoseMessage mesage, calculatedValue = %{public}@, timeStamp = %{public}@, sensorAge = %{public}@ / %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, g7GlucoseMessage.calculatedValue.description, g7GlucoseMessage.timeStamp.description(with: .current)) + + trace(" received g7GlucoseMessage mesage, sensorAge = %{public}@ / %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, sensorAgeInDays.description, maxSensorAgeInDays.description) sensorAge = g7GlucoseMessage.sensorAge @@ -253,7 +265,7 @@ class CGMG7Transmitter: BluetoothTransmitter, CGMTransmitter { return } - if let sensorAge = sensorAge, let dexcomG7BackfillMessage = DexcomG7BackfillMessage(data: value, sensorAge: sensorAge) { + if let sensorAge = sensorAge, sensorAge < (ConstantsDexcomG7.maxSensorAgeInDays * 24 * 3600), let dexcomG7BackfillMessage = DexcomG7BackfillMessage(data: value, sensorAge: sensorAge) { trace(" received backfill mesage, calculatedValue = %{public}@, timeStamp = %{public}@", log: log, category: ConstantsLog.categoryCGMG7, type: .info, dexcomG7BackfillMessage.calculatedValue.description, dexcomG7BackfillMessage.timeStamp.description(with: .current)) backfill.append(GlucoseData(timeStamp: dexcomG7BackfillMessage.timeStamp, glucoseLevelRaw: dexcomG7BackfillMessage.calculatedValue)) diff --git a/xdrip/Constants/ConstantsDexcomG7.swift b/xdrip/Constants/ConstantsDexcomG7.swift index 82b6f1ccc..e2e0f6566 100644 --- a/xdrip/Constants/ConstantsDexcomG7.swift +++ b/xdrip/Constants/ConstantsDexcomG7.swift @@ -11,7 +11,7 @@ enum ConstantsDexcomG7 { /// if there's a new connect within this period, but latest reading was less than this interval ago, then no need to request new reading static let minimumTimeBetweenTwoReadings = TimeInterval(minutes: 2.1) - /// how many days the sensor session lasts + /// how many days the sensor session lasts. In the case of G7/ONE+ it is 10 days + a 12 hour grace period = 10.5 days static let maxSensorAgeInDays: Double = 10.5 } diff --git a/xdrip/Constants/ConstantsHomeView.swift b/xdrip/Constants/ConstantsHomeView.swift index f8d77ce0c..f477b72b9 100644 --- a/xdrip/Constants/ConstantsHomeView.swift +++ b/xdrip/Constants/ConstantsHomeView.swift @@ -51,12 +51,12 @@ enum ConstantsHomeView { /// urgent time left / colour static let sensorProgressViewUrgentInMinutes: Double = 60 * 12.0 // 12 hours before the sensor reaches max age - static let sensorProgressViewProgressColorUrgent: UIColor = .red - static let sensorProgressViewProgressColorUrgentSwiftUI: Color = .red + static let sensorProgressViewProgressColorUrgent: UIColor = .orange + static let sensorProgressViewProgressColorUrgentSwiftUI: Color = .orange /// colour for an expired sensor - static let sensorProgressExpired: UIColor = .purple - static let sensorProgressExpiredSwiftUI: Color = .purple + static let sensorProgressExpired: UIColor = .red + static let sensorProgressExpiredSwiftUI: Color = .red /// colour for an normal text static let sensorProgressNormalTextColor: UIColor = .lightGray From 1f7a3cce835b1e7d1c133b6bc1fa42adda972fd4 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:01:13 +0200 Subject: [PATCH 09/11] correct mmol/L readings for slope view in BgReadingsDetailView --- xdrip/SwiftUIViews/BgReadingsDetailView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xdrip/SwiftUIViews/BgReadingsDetailView.swift b/xdrip/SwiftUIViews/BgReadingsDetailView.swift index 8b18dd1e7..2a9c74fb3 100644 --- a/xdrip/SwiftUIViews/BgReadingsDetailView.swift +++ b/xdrip/SwiftUIViews/BgReadingsDetailView.swift @@ -30,8 +30,8 @@ struct BgReadingsDetailView: View { Section(header: Text(Texts_BgReadings.slopeSectionHeader)) { row(title: Texts_BgReadings.slopeArrow, data: bgReading.slopeArrow()) - row(title: Texts_BgReadings.slopePerMinute, data: (bgReading.calculatedValueSlope * 60000).formatted(.number.rounded(increment: isMgDl ? 0.01 : 0.001)) + " " + String(isMgDl ? Texts_Common.mgdl : Texts_Common.mmol)) - row(title: Texts_BgReadings.slopePer5Minutes, data: (bgReading.calculatedValueSlope * 60000 * 5).formatted(.number.rounded(increment: isMgDl ? 0.01 : 0.001)) + " " + String(isMgDl ? Texts_Common.mgdl : Texts_Common.mmol)) + row(title: Texts_BgReadings.slopePerMinute, data: (bgReading.calculatedValueSlope.mgDlToMmol(mgDl: isMgDl) * 60000).formatted(.number.rounded(increment: isMgDl ? 0.01 : 0.001)) + " " + String(isMgDl ? Texts_Common.mgdl : Texts_Common.mmol)) + row(title: Texts_BgReadings.slopePer5Minutes, data: (bgReading.calculatedValueSlope.mgDlToMmol(mgDl: isMgDl) * 60000 * 5).formatted(.number.rounded(increment: isMgDl ? 0.01 : 0.001)) + " " + String(isMgDl ? Texts_Common.mgdl : Texts_Common.mmol)) } if let calibration = bgReading.calibration { From e44eccbdb1f50aaa531d3b85bbb608373c521900 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Sun, 13 Oct 2024 20:38:51 +0200 Subject: [PATCH 10/11] add check for keep-alive to Contact Image This will display "OFF" in the contact image if the user is in follower mode with background keep-alive disabled, or if they disable the contact image function. Also change settings text from "create contact" to "enable contact image" Add warning text to "Enable Contact Image" UISwitch if the user is in follower mode with keep-alive disabled. --- .../ContactImage/ContactImageManager.swift | 31 +++----- .../en.lproj/SettingsViews.strings | 2 +- .../es.lproj/SettingsViews.strings | 2 +- xdrip/SwiftUIViews/ContactImageView.swift | 76 +++++++++---------- xdrip/Texts/TextsSettingsView.swift | 2 +- ...ngsViewContactImageSettingsViewModel.swift | 34 +++++---- 6 files changed, 67 insertions(+), 80 deletions(-) diff --git a/xdrip/Managers/ContactImage/ContactImageManager.swift b/xdrip/Managers/ContactImage/ContactImageManager.swift index 77c4af63a..0d32400c8 100644 --- a/xdrip/Managers/ContactImage/ContactImageManager.swift +++ b/xdrip/Managers/ContactImage/ContactImageManager.swift @@ -36,6 +36,8 @@ class ContactImageManager: NSObject { UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.displayTrendInContactImage.rawValue, options: .new, context: nil) UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.useHighContrastContactImage.rawValue, options: .new, context: nil) UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.bloodGlucoseUnitIsMgDl.rawValue, options: .new, context: nil) + UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.isMaster.rawValue, options: .new, context: nil) + UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.followerBackgroundKeepAliveType.rawValue, options: .new, context: nil) } @@ -63,24 +65,7 @@ class ContactImageManager: NSObject { /// used by observevalue for UserDefaults.Key private func evaluateUserDefaultsChange(keyPathEnum: UserDefaults.Key) { - switch keyPathEnum { - - case UserDefaults.Key.enableContactImage: - // if the user has enabled the option, then update the existing contact or add a new one if it doesn't exist - // this isn't really the best way to do it as we should delete the contact if - // not required to "clean up", but too many users didn't re-select the new contact after - // re-enabling in the Watch complication and assumed that the app wasn't working - if UserDefaults.standard.enableContactImage { - updateContact() - } - - case UserDefaults.Key.displayTrendInContactImage, UserDefaults.Key.useHighContrastContactImage, UserDefaults.Key.bloodGlucoseUnitIsMgDl: - updateContact() - - default: - break - - } + updateContact() } /// this function will perform the following actions: @@ -94,8 +79,6 @@ class ContactImageManager: NSObject { self.workItem?.cancel() self.workItem = nil - guard UserDefaults.standard.enableContactImage else { return } - // check that access to contacts is authorized by the user guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else { trace("in updateContact, access to contacts is not authorized, setting enableContactImage to false", log: self.log, category: ConstantsLog.categoryContactImageManager, type: .info) @@ -109,10 +92,14 @@ class ContactImageManager: NSObject { let lastReading = self.bgReadingsAccessor.get2LatestBgReadings(minimumTimeIntervalInMinutes: 4.0) var contactImageView: ContactImageView + // disable the image (show "OFF") if the function is disabled or if the user is in follower mode with background keep-alive disabled + // as otherwise it would always be out of date + let disableContactImage: Bool = !UserDefaults.standard.enableContactImage || (!UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled) + if lastReading.count > 0 { let valueIsUpToDate = abs(lastReading[0].timeStamp.timeIntervalSinceNow) < 7 * 60 - contactImageView = ContactImageView(bgValue: lastReading[0].calculatedValue, isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl, slopeArrow: UserDefaults.standard.displayTrendInContactImage ? lastReading[0].slopeArrow() : "", bgRangeDescription: lastReading[0].bgRangeDescription(), valueIsUpToDate: valueIsUpToDate, useHighContrastContactImage: UserDefaults.standard.useHighContrastContactImage) + contactImageView = ContactImageView(bgValue: lastReading[0].calculatedValue, isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl, slopeArrow: UserDefaults.standard.displayTrendInContactImage ? lastReading[0].slopeArrow() : "", bgRangeDescription: lastReading[0].bgRangeDescription(), valueIsUpToDate: valueIsUpToDate, useHighContrastContactImage: UserDefaults.standard.useHighContrastContactImage, disableContactImage: disableContactImage) // schedule an update in 5 min 15 seconds - if no new data is received until then, the empty value will get rendered into the contact (this update will be canceled if new data is received) self.workItem = DispatchWorkItem(block: { @@ -123,7 +110,7 @@ class ContactImageManager: NSObject { DispatchQueue.main.asyncAfter(deadline: .now() + (5 * 60) + 15, execute: self.workItem!) } else { // create an 'empty' image view if there is no BG data to show - contactImageView = ContactImageView(bgValue: 0, isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl, slopeArrow: "", bgRangeDescription: .inRange, valueIsUpToDate: false, useHighContrastContactImage: false) + contactImageView = ContactImageView(bgValue: 0, isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl, slopeArrow: "", bgRangeDescription: .inRange, valueIsUpToDate: false, useHighContrastContactImage: false, disableContactImage: disableContactImage) } // we're going to use the app name as the given name of the contact we want to use/create/update diff --git a/xdrip/Storyboards/en.lproj/SettingsViews.strings b/xdrip/Storyboards/en.lproj/SettingsViews.strings index 483de526e..bf56f54cf 100644 --- a/xdrip/Storyboards/en.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/en.lproj/SettingsViews.strings @@ -134,7 +134,7 @@ "settingsviews_CalenderIntervalMessage" = "Minimum interval between two calender events (mins)"; "settingsviews_infoContactsAccessRestricted" = "You cannot give authorization to %@ to access your contacts. This is possibly due to active restrictions such as parental controls being in place."; "settingsviews_contactImageSectionTitle" = "Contact Image"; -"settingsviews_enableContactImage" = "Create Contact"; +"settingsviews_enableContactImage" = "Enable Contact Image"; "settingsviews_displayTrendInContactImage" = "Show Trend"; "settingsviews_contactImageCreatedByString" = "Contact automatically created by"; "sectionTitleTrace" = "Issue Reporting"; diff --git a/xdrip/Storyboards/es.lproj/SettingsViews.strings b/xdrip/Storyboards/es.lproj/SettingsViews.strings index 24efe3328..93833c6e4 100644 --- a/xdrip/Storyboards/es.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/es.lproj/SettingsViews.strings @@ -143,7 +143,7 @@ "settingsviews_sectiontitlehomescreen" = "Inicio"; "settingsviews_infoContactsAccessRestricted" = "No has podido dar permiso a %@ para accesar a tus contactos. Esto es probablemente debido a restriciones como el control parental o similar."; "settingsviews_contactImageSectionTitle" = "Imagen de Contacto"; -"settingsviews_enableContactImage" = "Crear Contacto"; +"settingsviews_enableContactImage" = "Habilitar Contacto"; "settingsviews_displayTrendInContactImage" = "Mostrar Tendencia"; "settingsviews_contactImageCreatedByString" = "Contacto creado automáticamente por"; diff --git a/xdrip/SwiftUIViews/ContactImageView.swift b/xdrip/SwiftUIViews/ContactImageView.swift index 9885f33e5..39e687daa 100644 --- a/xdrip/SwiftUIViews/ContactImageView.swift +++ b/xdrip/SwiftUIViews/ContactImageView.swift @@ -10,6 +10,7 @@ struct ContactImageView: View { var bgRangeDescription: BgRangeDescription var valueIsUpToDate: Bool var useHighContrastContactImage: Bool + var disableContactImage: Bool var uiImage: UIImage { return getImage() @@ -21,6 +22,10 @@ struct ContactImageView: View { } var bgColor: UIColor { + if disableContactImage { + return useHighContrastContactImage ? .white : .systemCyan + } + guard bgValue > 0, valueIsUpToDate else { return ConstantsContactImage.unknownColor } // if the user isn't requesting a high contrast image, then return the correct bg color @@ -64,43 +69,28 @@ struct ContactImageView: View { } } + if disableContactImage { + fontSize = 100 + } + return UIFont.systemFont(ofSize: fontSize, weight: .bold) } -// var slopeArrowFont: UIFont { -// var fontSize: CGFloat = 100 -// -// if isMgDl { -// switch bgValue { -// case 1..<100: -// fontSize = 90 -// case 100..<200: -// fontSize = 90 -// default: -// fontSize = 100 -// } -// } else { -// switch bgValue.mgDlToMmol() { -// case 0.1..<10.0: -// fontSize = 100 -// case 10.0..<20.0: -// fontSize = 120 -// default: -// fontSize = 120 -// } -// } -// -// return UIFont.systemFont(ofSize: 80, weight: .bold) -// } - func getImage() -> UIImage { let width = 256.0 let height = 256.0 let rect = CGRect(x: 0, y: 0, width: width, height: height) // if there is no current value, 0 will be received so show this as a relevant "---" string - let bgValueString: String = bgValue > 0 ? bgValue.mgDlToMmolAndToString(mgDl: isMgDl) : isMgDl ? "---" : "-.-" - let showSlopeArrow: Bool = (valueIsUpToDate && slopeArrow != "") ? true : false + var bgValueString: String = bgValue > 0 ? bgValue.mgDlToMmolAndToString(mgDl: isMgDl) : isMgDl ? "---" : "-.-" + + var showSlopeArrow: Bool = (valueIsUpToDate && slopeArrow != "") ? true : false + + // override the value and slope if the user is in follower mode and has disabled the keep-alive (to prevent showing an almost always out of date value) + if disableContactImage { + bgValueString = "OFF" + showSlopeArrow = false + } UIGraphicsBeginImageContext(rect.size) @@ -157,10 +147,11 @@ struct ContactImageViewPreview: View { var bgRangeDescription: BgRangeDescription var valueIsUpToDate: Bool var useHighContrastContactImage: Bool + var disableContactImage: Bool var body: some View { ZStack { - ContactImageView(bgValue: bgValue, isMgDl: isMgDl, slopeArrow: slopeArrow, bgRangeDescription: bgRangeDescription, valueIsUpToDate: valueIsUpToDate, useHighContrastContactImage: useHighContrastContactImage) + ContactImageView(bgValue: bgValue, isMgDl: isMgDl, slopeArrow: slopeArrow, bgRangeDescription: bgRangeDescription, valueIsUpToDate: valueIsUpToDate, useHighContrastContactImage: useHighContrastContactImage, disableContactImage: disableContactImage) Circle() .stroke(lineWidth: 20) .foregroundColor(.white) @@ -174,22 +165,23 @@ struct ContactImageViewPreview: View { struct ContactImageView_Previews: PreviewProvider { struct Preview: View { var body: some View { + ContactImageViewPreview(bgValue: 88, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.notUrgent, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: true).previewDisplayName("OFF") - ContactImageViewPreview(bgValue: 88, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.notUrgent, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("88") - ContactImageViewPreview(bgValue: 88, isMgDl: true, slopeArrow: "\u{2192}" /* → */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: true).previewDisplayName("88 →") - ContactImageViewPreview(bgValue: 188, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("188") - ContactImageViewPreview(bgValue: 188, isMgDl: true, slopeArrow: "\u{2198}" /* ↘ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("188 ↘") - ContactImageViewPreview(bgValue: 388, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("388") - ContactImageViewPreview(bgValue: 388, isMgDl: true, slopeArrow: "\u{2191}\u{2191}" /* ↑↑ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("388 ↑↑") + ContactImageViewPreview(bgValue: 88, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.notUrgent, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("88") + ContactImageViewPreview(bgValue: 88, isMgDl: true, slopeArrow: "\u{2192}" /* → */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: true, disableContactImage: false).previewDisplayName("88 →") + ContactImageViewPreview(bgValue: 188, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("188") + ContactImageViewPreview(bgValue: 188, isMgDl: true, slopeArrow: "\u{2198}" /* ↘ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("188 ↘") + ContactImageViewPreview(bgValue: 388, isMgDl: true, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("388") + ContactImageViewPreview(bgValue: 388, isMgDl: true, slopeArrow: "\u{2191}\u{2191}" /* ↑↑ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("388 ↑↑") - ContactImageViewPreview(bgValue: 160, isMgDl: false, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("8.9") /* → */ - ContactImageViewPreview(bgValue: 160, isMgDl: false, slopeArrow: "\u{2198}" /* ↘ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("8.9 ↘") /* → */ - ContactImageViewPreview(bgValue: 188, isMgDl: false, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("10.4") - ContactImageViewPreview(bgValue: 188, isMgDl: false, slopeArrow: "\u{2198}" /* ↘ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("10.4 ↘") - ContactImageViewPreview(bgValue: 400, isMgDl: false, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("22.2") - ContactImageViewPreview(bgValue: 400, isMgDl: false, slopeArrow: "\u{2191}\u{2191}" /* ↑↑ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false).previewDisplayName("22.2 ↑↑") + ContactImageViewPreview(bgValue: 160, isMgDl: false, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("8.9") /* → */ + ContactImageViewPreview(bgValue: 160, isMgDl: false, slopeArrow: "\u{2198}" /* ↘ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("8.9 ↘") /* → */ + ContactImageViewPreview(bgValue: 188, isMgDl: false, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("10.4") + ContactImageViewPreview(bgValue: 188, isMgDl: false, slopeArrow: "\u{2198}" /* ↘ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("10.4 ↘") + ContactImageViewPreview(bgValue: 400, isMgDl: false, slopeArrow: "", bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("22.2") + ContactImageViewPreview(bgValue: 400, isMgDl: false, slopeArrow: "\u{2191}\u{2191}" /* ↑↑ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: true, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("22.2 ↑↑") - ContactImageViewPreview(bgValue: 120, isMgDl: true, slopeArrow: "\u{2191}" /* ↑ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: false, useHighContrastContactImage: false).previewDisplayName("120, not current") + ContactImageViewPreview(bgValue: 120, isMgDl: true, slopeArrow: "\u{2191}" /* ↑ */, bgRangeDescription: BgRangeDescription.inRange, valueIsUpToDate: false, useHighContrastContactImage: false, disableContactImage: false).previewDisplayName("120, not current") } } static var previews: some View { diff --git a/xdrip/Texts/TextsSettingsView.swift b/xdrip/Texts/TextsSettingsView.swift index 2ee651104..bf4a361f6 100644 --- a/xdrip/Texts/TextsSettingsView.swift +++ b/xdrip/Texts/TextsSettingsView.swift @@ -709,7 +709,7 @@ class Texts_SettingsView { }() static let enableContactImage: String = { - return NSLocalizedString("settingsviews_enableContactImage", tableName: filename, bundle: Bundle.main, value: "Create Contact", comment: "Contact Image Settings - text in row where contact image is enabled or disabled ") + return NSLocalizedString("settingsviews_enableContactImage", tableName: filename, bundle: Bundle.main, value: "Enable Contact Image", comment: "Contact Image Settings - text in row where contact image is enabled or disabled ") }() static let displayTrendInContactImage: String = { diff --git a/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewContactImageSettingsViewModel.swift b/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewContactImageSettingsViewModel.swift index d2dcc5dcf..5d899487e 100644 --- a/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewContactImageSettingsViewModel.swift +++ b/xdrip/View Controllers/SettingsNavigationController/SettingsViewController/SettingsViewModels/SettingsViewContactImageSettingsViewModel.swift @@ -29,7 +29,7 @@ class SettingsViewContactImageSettingsViewModel: SettingsViewModelProtocol { func storeMessageHandler(messageHandler: ((String, String) -> Void)) { // this ViewModel does need to send back messages to the viewcontroller asynchronously } - + func storeRowReloadClosure(rowReloadClosure: ((Int) -> Void)) {} func sectionTitle() -> String? { @@ -50,9 +50,9 @@ class SettingsViewContactImageSettingsViewModel: SettingsViewModelProtocol { case .useHighContrastContactImage: return Texts_SettingsView.useHighContrastContactImage - + } - + } func accessoryType(index: Int) -> UITableViewCell.AccessoryType { @@ -62,42 +62,50 @@ class SettingsViewContactImageSettingsViewModel: SettingsViewModelProtocol { switch setting { case .enableContactImage: + // check if in follower with keep-alive disabled. If so, disable this option + if !UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled { + return .detailButton + } + // if access to Contacts was previously denied by user, then show disclosure indicator, clicking the row will give info how user should authorize access // also if access is restricted switch CNContactStore.authorizationStatus(for: .contacts) { case .denied: // by clicking row, show info how to authorized - return UITableViewCell.AccessoryType.disclosureIndicator + return .disclosureIndicator case .notDetermined: - return UITableViewCell.AccessoryType.none + return .none case .restricted, .limited: // by clicking row, show what it means to be restricted, according to Apple doc - return UITableViewCell.AccessoryType.disclosureIndicator + return .disclosureIndicator case .authorized: - return UITableViewCell.AccessoryType.none + return .none @unknown default: trace("in SettingsViewContactImageSettingsViewModel, unknown case returned when authorizing EKEventStore ", log: self.log, category: ConstantsLog.categoryRootView, type: .error) - return UITableViewCell.AccessoryType.none + return .none } case .displayTrend, .useHighContrastContactImage: return UITableViewCell.AccessoryType.none - + } } - + func detailedText(index: Int) -> String? { guard let setting = Setting(rawValue: index) else { fatalError("Unexpected Section") } switch setting { - case .enableContactImage, .displayTrend, .useHighContrastContactImage: + case .enableContactImage: + // check if in follower with keep-alive disabled. If so, disable this option + return (UserDefaults.standard.enableContactImage && !UserDefaults.standard.isMaster && UserDefaults.standard.followerBackgroundKeepAliveType == .disabled) ? "⚠️ No keep-alive" : nil + case .displayTrend, .useHighContrastContactImage: return nil } } @@ -152,7 +160,7 @@ class SettingsViewContactImageSettingsViewModel: SettingsViewModelProtocol { case .denied: trace("in SettingsViewContactImageSettingsViewModel, CNContactStore access denied by user", log: self.log, category: ConstantsLog.categoryRootView, type: .error) UserDefaults.standard.enableContactImage = false - + case .authorized: trace("in SettingsViewContactImageSettingsViewModel, CNContactStore access authorized", log: self.log, category: ConstantsLog.categoryRootView, type: .error) UserDefaults.standard.enableContactImage = true @@ -169,7 +177,7 @@ class SettingsViewContactImageSettingsViewModel: SettingsViewModelProtocol { case .useHighContrastContactImage: return UISwitch(isOn: UserDefaults.standard.useHighContrastContactImage, action: {(isOn:Bool) in UserDefaults.standard.useHighContrastContactImage = isOn}) - + } } From 8c0e7b72b40e4c64d1cdbe3e2aaa4fe6f23db957 Mon Sep 17 00:00:00 2001 From: Paul Plant <37302780+paulplant@users.noreply.github.com> Date: Sun, 13 Oct 2024 20:45:00 +0200 Subject: [PATCH 11/11] translations added for Algorithm + Calibration Types initial translations of main titles/rows/messages: - en, es, nl, de, fr (no messages), sv (no messages) --- .../Storyboards/de.lproj/BluetoothPeripheralView.strings | 7 +++++++ xdrip/Storyboards/de.lproj/CalibrationRequest.strings | 3 +++ xdrip/Storyboards/de.lproj/SettingsViews.strings | 4 ++++ .../Storyboards/en.lproj/BluetoothPeripheralView.strings | 8 ++++++++ xdrip/Storyboards/en.lproj/CalibrationRequest.strings | 2 ++ xdrip/Storyboards/en.lproj/Common.strings | 1 + xdrip/Storyboards/en.lproj/SettingsViews.strings | 3 +++ .../Storyboards/es.lproj/BluetoothPeripheralView.strings | 9 +++++++++ xdrip/Storyboards/es.lproj/CalibrationRequest.strings | 2 ++ xdrip/Storyboards/es.lproj/Common.strings | 1 + xdrip/Storyboards/es.lproj/SettingsViews.strings | 3 +++ .../Storyboards/fr.lproj/BluetoothPeripheralView.strings | 3 +++ xdrip/Storyboards/fr.lproj/CalibrationRequest.strings | 2 ++ xdrip/Storyboards/fr.lproj/SettingsViews.strings | 3 +++ .../Storyboards/nl.lproj/BluetoothPeripheralView.strings | 7 +++++++ xdrip/Storyboards/nl.lproj/CalibrationRequest.strings | 2 ++ xdrip/Storyboards/nl.lproj/SettingsViews.strings | 3 +++ .../Storyboards/sv.lproj/BluetoothPeripheralView.strings | 3 +++ xdrip/Storyboards/sv.lproj/CalibrationRequest.strings | 2 ++ xdrip/Storyboards/sv.lproj/SettingsViews.strings | 5 +++++ xdrip/Texts/TextsBluetoothPeripheralView.swift | 8 ++++---- xdrip/Texts/TextsCalibration.swift | 4 ++-- xdrip/Texts/TextsCommon.swift | 2 +- 23 files changed, 80 insertions(+), 7 deletions(-) diff --git a/xdrip/Storyboards/de.lproj/BluetoothPeripheralView.strings b/xdrip/Storyboards/de.lproj/BluetoothPeripheralView.strings index 2a2334f3e..1d837dae0 100644 --- a/xdrip/Storyboards/de.lproj/BluetoothPeripheralView.strings +++ b/xdrip/Storyboards/de.lproj/BluetoothPeripheralView.strings @@ -128,3 +128,10 @@ /// sensor warm-up text "warmingUpUntil" = "Warming up until"; + +"nativeAlgorithm" = "Nativer Algorithmus"; +"xDripAlgorithm" = "xDrip Algorithmus"; +"confirmAlgorithmChangeToTransmitterMessage" = "Bitte um Bestätigung, dass zum nativen/transmitter Algorithmus gewechselt werden soll"; +"confirmAlgorithmChangeToxDripMessage" = "itte um Bestätigung, dass zum xDrip Algorithmus gewechselt werden soll.\n\nDies stoppt für kurze Zeit die Datenübermittlung und Du wirst um einen initialen Kalibrierungswert (Blut) gebeten."; +"confirmCalibrationChangeToSinglePointMessage" = "Bitte um Bestätigung, dass zur Standard Kalibrierung gewechselt werden soll.\n\nDies stoppt für kurze Zeit die Datenübermittlung und Du wirst um einen initialen Kalibrierungswert (Blut) gebeten."; +"confirmCalibrationChangeToMultiPointMessage" = "Bitte um Bestätigung, dass zur Mehrpunkt Kalibrierung gewechselt werden soll.\n\n⚠️ Diese Methode ist nur für erfahrene Benutzer, es könnte ein falscher und damit gefährlicher Wert angezeigt werden, wenn die Kalibrierung nicht korrekt durchgeführt wurde.\n\nWenn Du unsicher bist, bitte drücke Abbruch/Cancel."; diff --git a/xdrip/Storyboards/de.lproj/CalibrationRequest.strings b/xdrip/Storyboards/de.lproj/CalibrationRequest.strings index 4945ea0b0..0c6780e27 100644 --- a/xdrip/Storyboards/de.lproj/CalibrationRequest.strings +++ b/xdrip/Storyboards/de.lproj/CalibrationRequest.strings @@ -10,3 +10,6 @@ /// When calibration alert goess off, user clicks the notification, app opens, dialog pops up, this is the text in the dialog "enter_calibration_value" = "Eingabe Kalibrierungswert"; + +"singlePointCalibration" = "Standard"; +"multiPointCalibration" = "Multi-Punkt"; diff --git a/xdrip/Storyboards/de.lproj/SettingsViews.strings b/xdrip/Storyboards/de.lproj/SettingsViews.strings index ea7416f75..e96476799 100644 --- a/xdrip/Storyboards/de.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/de.lproj/SettingsViews.strings @@ -92,6 +92,10 @@ /// non fixed settings, title of the section "settingsviews_labelNonFixed" = "Mehrpunkt-Kalibrierung"; +"settingsviews_labelAlgorithmType" = "Algorithmus Typ"; +"settingsviews_labelCalibrationTitle" = "Sensor Kalibrierung"; +"settingsviews_labelCalibrationType" = "Kalibrierungs Typ"; + /// healthkit settings, literally 'healthkit' "settingsviews_healthkit" = "Apple Health nutzen"; diff --git a/xdrip/Storyboards/en.lproj/BluetoothPeripheralView.strings b/xdrip/Storyboards/en.lproj/BluetoothPeripheralView.strings index 58912dad8..7f5e64037 100644 --- a/xdrip/Storyboards/en.lproj/BluetoothPeripheralView.strings +++ b/xdrip/Storyboards/en.lproj/BluetoothPeripheralView.strings @@ -42,3 +42,11 @@ "nfcErrorMessageScanFailed" = "Sensor scan has failed"; "nonFixedSlopeWarning" = "Multi-point calibration is an advanced feature.\n\nPlease do not use this feature until you have read the calibration section of the online help and understand how it works."; "warmingUpUntil" = "Warming up until"; + +"nativeAlgorithm" = "Native algorithm"; +"xDripAlgorithm" = "xDrip algorithm"; +"confirmAlgorithmChangeToTransmitterMessage" = "Please confirm that you want to change back to the native/transmitter algorithm"; +"confirmAlgorithmChangeToxDripMessage" = "Please confirm that you want to change the the xDrip algorithm.\n\nThis will stop readings for a short time and ask you for a initial calibration value when ready."; +"confirmCalibrationChangeToSinglePointMessage" = "Please confirm that you want to change the calibration type to the standard calibration\n\nThis will stop readings for a short time and ask you for a initial calibration value when ready."; +"confirmCalibrationChangeToMultiPointMessage" = "Please confirm that you want to change the calibration type to multi-point\n\n⚠️ Please note that this method is only for advanced users and could potentially give dangerous results if not correctly calibrated.\n\nIf you are unsure how to use this method, please press Cancel."; +"confirm" = "Confirm"; diff --git a/xdrip/Storyboards/en.lproj/CalibrationRequest.strings b/xdrip/Storyboards/en.lproj/CalibrationRequest.strings index 55fbd6673..4bab5e3e6 100644 --- a/xdrip/Storyboards/en.lproj/CalibrationRequest.strings +++ b/xdrip/Storyboards/en.lproj/CalibrationRequest.strings @@ -2,3 +2,5 @@ "calibration_title" = "Calibration"; "calibration_notification_title" = "Calibration"; "calibration_notification_body" = "Click the Notification to Calibrate"; +"singlePointCalibration" = "Standard"; +"multiPointCalibration" = "Multi-point"; diff --git a/xdrip/Storyboards/en.lproj/Common.strings b/xdrip/Storyboards/en.lproj/Common.strings index ad71c209f..9705cc446 100644 --- a/xdrip/Storyboards/en.lproj/Common.strings +++ b/xdrip/Storyboards/en.lproj/Common.strings @@ -50,3 +50,4 @@ "common_dontshowagain" = "Don't Show Again"; "common_enabled" = "Enabled"; "common_disabled" = "Disabled"; +"common_notRequired" = "Not required"; diff --git a/xdrip/Storyboards/en.lproj/SettingsViews.strings b/xdrip/Storyboards/en.lproj/SettingsViews.strings index bf56f54cf..f73d523e5 100644 --- a/xdrip/Storyboards/en.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/en.lproj/SettingsViews.strings @@ -76,6 +76,9 @@ "settingsviews_webooptransmitter" = "Use Transmitter Algorithm"; "settingsviews_nonfixedtransmitter" = "Enable Multi-point Calibration"; "settingsviews_labelNonFixed" = "Multi-point Calibration"; +"settingsviews_labelAlgorithmType" = "Algorithm Type"; +"settingsviews_labelCalibrationTitle" = "Sensor Calibration"; +"settingsviews_labelCalibrationType" = "Calibration Type"; "settingsviews_labelWebOOP" = "xDrip or Transmitter Algorithm"; "settingsviews_sectiontitlealerting" = "Alarms"; "settingsviews_row_alert_types" = "Alarm Types"; diff --git a/xdrip/Storyboards/es.lproj/BluetoothPeripheralView.strings b/xdrip/Storyboards/es.lproj/BluetoothPeripheralView.strings index 833ad088c..ce1d4dd3f 100644 --- a/xdrip/Storyboards/es.lproj/BluetoothPeripheralView.strings +++ b/xdrip/Storyboards/es.lproj/BluetoothPeripheralView.strings @@ -64,3 +64,12 @@ /// Tell the user the scan was successful and to just wait now for connection "nfcScanSuccessfulMessage" = "\n✅ Scan successful ✅\n\nClick OK and just wait to allow the sensor to finish connecting via bluetooth.\n\nIn a short while the status should change to 'Connected'."; + + +"nativeAlgorithm" = "Algoritmo nativo"; +"xDripAlgorithm" = "Algoritmo xDrip"; +"confirmAlgorithmChangeToTransmitterMessage" = "Por favor, confirmar que deseas cambiar al algoritmo nativo"; +"confirmAlgorithmChangeToxDripMessage" = "Por favor, confirmar que deseas cambiar al algoritmo de xDrip.\n\nEsto hará que dejes de recibir lecturas durante un breve tiempo y la app te pedirá introducir una calibración inicial en cuanto sea necesario."; +"confirmCalibrationChangeToSinglePointMessage" = "Por favor, confirmar que deseas usar la calibración estándar.\n\nEsto hará que dejes de recibir lecturas durante un breve tiempo y la app te pedirá introducir una calibración inicial en cuanto sea necesario."; +"confirmCalibrationChangeToMultiPointMessage" = "Por favor, confirmar que deseas usar la calibración multi-puntos.\n\n⚠️ Ten en cuenta que este método de calibración es únicamente para usuarios avanzados y podría ser incluso peligroso si no se hace correctamente.\n\nSi tienes claro cómo funciona esta opción, por favor, apreta Cancelar"; +"confirm" = "Confirmar"; diff --git a/xdrip/Storyboards/es.lproj/CalibrationRequest.strings b/xdrip/Storyboards/es.lproj/CalibrationRequest.strings index c9bd89a72..e547c97d6 100644 --- a/xdrip/Storyboards/es.lproj/CalibrationRequest.strings +++ b/xdrip/Storyboards/es.lproj/CalibrationRequest.strings @@ -2,3 +2,5 @@ "calibration_title" = "Calibración"; "calibration_notification_title" = "Calibración"; "calibration_notification_body" = "Haz click en la notificación para calibrar"; +"singlePointCalibration" = "Estándar"; +"multiPointCalibration" = "Multi-punto"; diff --git a/xdrip/Storyboards/es.lproj/Common.strings b/xdrip/Storyboards/es.lproj/Common.strings index fb2af5bff..07b2f1a95 100644 --- a/xdrip/Storyboards/es.lproj/Common.strings +++ b/xdrip/Storyboards/es.lproj/Common.strings @@ -50,3 +50,4 @@ "common_dontshowagain" = "No Volver a Mostrar"; "common_enabled" = "Habilitado"; "common_disabled" = "Deshabilitado"; +"common_notRequired" = "No requerido"; diff --git a/xdrip/Storyboards/es.lproj/SettingsViews.strings b/xdrip/Storyboards/es.lproj/SettingsViews.strings index 93833c6e4..09a9ed6ca 100644 --- a/xdrip/Storyboards/es.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/es.lproj/SettingsViews.strings @@ -69,6 +69,9 @@ "settingsviews_resetDexcomTransmitterMessage" = "\nEsta opción intentará resetear el transmisor durante la próxima conexión.\n\nEsto solo puede funcionar con transmisores G5 y transmisores G6 Anubis.\n\nNo funciona para transmisores normales tipo G6 y One."; "settingsviews_nonfixedtransmitter" = "Habilitar Calibración Multi-punto"; "settingsviews_labelNonFixed" = "Calibración Multi-punto"; +"settingsviews_labelAlgorithmType" = "Tipo de Algoritmo"; +"settingsviews_labelCalibrationTitle" = "Calibración de Sensor"; +"settingsviews_labelCalibrationType" = "Tipo de Calibración"; "settingsviews_sectiontitlealerting" = "Alarmas"; "settingsviews_row_alert_types" = "Tipos de Alarmas"; "settingsviews_row_alerts" = "Alarmas"; diff --git a/xdrip/Storyboards/fr.lproj/BluetoothPeripheralView.strings b/xdrip/Storyboards/fr.lproj/BluetoothPeripheralView.strings index 73d1f0fa1..04c8b79b5 100644 --- a/xdrip/Storyboards/fr.lproj/BluetoothPeripheralView.strings +++ b/xdrip/Storyboards/fr.lproj/BluetoothPeripheralView.strings @@ -70,3 +70,6 @@ /// sensor warm-up text "warmingUpUntil" = "Warming up until"; + +"nativeAlgorithm" = "Algorithme natif"; +"xDripAlgorithm" = "Algorithme xDrip"; diff --git a/xdrip/Storyboards/fr.lproj/CalibrationRequest.strings b/xdrip/Storyboards/fr.lproj/CalibrationRequest.strings index 1add3a00b..ec299cc0f 100644 --- a/xdrip/Storyboards/fr.lproj/CalibrationRequest.strings +++ b/xdrip/Storyboards/fr.lproj/CalibrationRequest.strings @@ -2,3 +2,5 @@ "calibration_title" = "Calibration"; "calibration_notification_title" = "Calibration"; "calibration_notification_body" = "Cliquez la notification pour calibrer"; +"singlePointCalibration" = "Standard"; +"multiPointCalibration" = "Multi-points"; diff --git a/xdrip/Storyboards/fr.lproj/SettingsViews.strings b/xdrip/Storyboards/fr.lproj/SettingsViews.strings index 4228888d8..446e0d092 100644 --- a/xdrip/Storyboards/fr.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/fr.lproj/SettingsViews.strings @@ -113,6 +113,9 @@ /// non fixed settings, title of the section "settingsviews_labelNonFixed" = "Calibration Multi-point"; +"settingsviews_labelAlgorithmType" = "Type d'algorithme"; +"settingsviews_labelCalibrationType" = "Type de calibration"; + /// In Settings, Alerts section, there's an option to test the volume of the sound player, this is the title of the row "volumeTestSoundPlayer" = "Test Volume (Si Ignorer Mode silencieux)"; diff --git a/xdrip/Storyboards/nl.lproj/BluetoothPeripheralView.strings b/xdrip/Storyboards/nl.lproj/BluetoothPeripheralView.strings index 463a2c4be..495e03c70 100644 --- a/xdrip/Storyboards/nl.lproj/BluetoothPeripheralView.strings +++ b/xdrip/Storyboards/nl.lproj/BluetoothPeripheralView.strings @@ -67,3 +67,10 @@ /// sensor warm-up text "warmingUpUntil" = "Warming up until"; + +"nativeAlgorithm" = "Native algoritme"; +"xDripAlgorithm" = "xDrip algoritme"; +"confirmAlgorithmChangeToTransmitterMessage" = "Je wil dus terug naar het native algoritme?"; +"confirmAlgorithmChangeToxDripMessage" = "Je wil dus naar het xDrip algoritme?\n\nJe zult na de aanpassing gedurende korte tijd geen metingen krijgen en er zal je gevraagd worden om te kalibreren."; +"confirmCalibrationChangeToSinglePointMessage" = "Je wil dus het kalibratie type veranderen naar standaard kalibratie?\n\nJe zult na de aanpassing gedurende korte tijd geen metingen krijgen en er zal je gevraagd worden om te kalibreren."; +"confirmCalibrationChangeToMultiPointMessage" = "Je wil dus het kalibratie type veranderen naar meerpunts kalibratie?\n\n⚠️ Dit kalibratietype is voor ervaren gebruikers en kan bij foute kalibratie gevaarlijke resultaten geven.\n\nAls je niet zeker bent dat je deze methode goed kunt gebruiken, kies dan Annuleer."; diff --git a/xdrip/Storyboards/nl.lproj/CalibrationRequest.strings b/xdrip/Storyboards/nl.lproj/CalibrationRequest.strings index 7062350ba..9c21c38ba 100644 --- a/xdrip/Storyboards/nl.lproj/CalibrationRequest.strings +++ b/xdrip/Storyboards/nl.lproj/CalibrationRequest.strings @@ -2,3 +2,5 @@ "calibration_title" = "Kalibratie"; "calibration_notification_title" = "Kalibratie"; "calibration_notification_body" = "Klik op de Notificatie om te Kalibreren"; +"singlePointCalibration" = "Standaard"; +"multiPointCalibration" = "Meerpunts"; diff --git a/xdrip/Storyboards/nl.lproj/SettingsViews.strings b/xdrip/Storyboards/nl.lproj/SettingsViews.strings index f98946671..2897961f5 100644 --- a/xdrip/Storyboards/nl.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/nl.lproj/SettingsViews.strings @@ -30,6 +30,9 @@ "settingsviews_resettransmitter" = "Reset Transmitter (Anubis)"; "settingsviews_nonfixedtransmitter" = "Schakel Meerpuntskalibratie In"; "settingsviews_labelNonFixed" = "Meerpuntskalibratie"; +"settingsviews_labelAlgorithmType" = "Type algoritme"; +"settingsviews_labelCalibrationTitle" = "Sensor Kalibratie"; +"settingsviews_labelCalibrationType" = "Type kalibratie"; "settingsviews_sectiontitlealerting" = "Alarmen"; "settingsviews_row_alert_types" = "Alarm Types"; "settingsviews_row_alerts" = "Alarmen"; diff --git a/xdrip/Storyboards/sv.lproj/BluetoothPeripheralView.strings b/xdrip/Storyboards/sv.lproj/BluetoothPeripheralView.strings index 13023ff86..c87d27173 100644 --- a/xdrip/Storyboards/sv.lproj/BluetoothPeripheralView.strings +++ b/xdrip/Storyboards/sv.lproj/BluetoothPeripheralView.strings @@ -69,3 +69,6 @@ /// sensor warm-up text "warmingUpUntil" = "Warming up until"; + +"nativeAlgorithm" = "Inbyggd Algoritm"; +"xDripAlgorithm" = "xDrip Algoritm"; diff --git a/xdrip/Storyboards/sv.lproj/CalibrationRequest.strings b/xdrip/Storyboards/sv.lproj/CalibrationRequest.strings index c8b2b1215..50a2299da 100644 --- a/xdrip/Storyboards/sv.lproj/CalibrationRequest.strings +++ b/xdrip/Storyboards/sv.lproj/CalibrationRequest.strings @@ -2,3 +2,5 @@ "calibration_title" = "Kalibrering"; "calibration_notification_title" = "Kalibrering"; "calibration_notification_body" = "Klicka på notis för att kalibrera"; +"singlePointCalibration" = "Standard"; +"multiPointCalibration" = "Flerpunkts"; diff --git a/xdrip/Storyboards/sv.lproj/SettingsViews.strings b/xdrip/Storyboards/sv.lproj/SettingsViews.strings index df03e9377..5f6ac3a93 100644 --- a/xdrip/Storyboards/sv.lproj/SettingsViews.strings +++ b/xdrip/Storyboards/sv.lproj/SettingsViews.strings @@ -32,6 +32,11 @@ "settingsviews_resettransmitter" = "Återställ sändare (Anubis)"; "settingsviews_nonfixedtransmitter" = "Använd flerpunktskalibrering"; "settingsviews_labelNonFixed" = "Flerpunktskalibrering"; + +"settingsviews_labelAlgorithmType" = "Algoritm typ"; +"settingsviews_labelCalibrationTitle" = "Sensor Kalibrering"; +"settingsviews_labelCalibrationType" = "Kalibreringstyp"; + "settingsviews_sectiontitlealerting" = "Larm"; "settingsviews_row_alert_types" = "Typ av larm"; "settingsviews_row_alerts" = "Larm"; diff --git a/xdrip/Texts/TextsBluetoothPeripheralView.swift b/xdrip/Texts/TextsBluetoothPeripheralView.swift index dce57c95b..43aeadfd4 100644 --- a/xdrip/Texts/TextsBluetoothPeripheralView.swift +++ b/xdrip/Texts/TextsBluetoothPeripheralView.swift @@ -157,19 +157,19 @@ class Texts_BluetoothPeripheralView { }() static let confirmAlgorithmChangeToTransmitterMessage: String = { - return NSLocalizedString("confirmAlgorithmChangeToTransmitterMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change back to the standard/transmitter algorithm.", comment: "Confirm that the user wants to really change the transmitter or native algorithm type, message") + return NSLocalizedString("confirmAlgorithmChangeToTransmitterMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change back to the native/transmitter algorithm.", comment: "Confirm that the user wants to really change the transmitter or native algorithm type, message") }() static let confirmAlgorithmChangeToxDripMessage: String = { - return NSLocalizedString("confirmAlgorithmChangeToxDripMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change the the xDrip algorithm.\n\nThis will stop readings for a short time and ask you for a initial calibration value when ready", comment: "Confirm that the user wants to really change the xDrip algorithm type, message") + return NSLocalizedString("confirmAlgorithmChangeToxDripMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change the the xDrip algorithm.\n\nThis will stop readings for a short time and ask you for a initial calibration value when ready.", comment: "Confirm that the user wants to really change the xDrip algorithm type, message") }() static let confirmCalibrationChangeToSinglePointMessage: String = { - return NSLocalizedString("confirmCalibrationChangeToSinglePointMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change the calibration type to the standard calibration\n\nThis will stop readings for a short time and ask you for a initial calibration value when ready", comment: "Confirm that the user wants to really change the calibration type to multi-point, message") + return NSLocalizedString("confirmCalibrationChangeToSinglePointMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change the calibration type to the standard calibration\n\nThis will stop readings for a short time and ask you for a initial calibration value when ready.", comment: "Confirm that the user wants to really change the calibration type to multi-point, message") }() static let confirmCalibrationChangeToMultiPointMessage: String = { - return NSLocalizedString("confirmCalibrationChangeToMultiPointMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change the calibration type to multi-point\n\n⚠️ Please note that this method is only for advanced users and could potentially give dangerous results if not correctly calibrated.\n\nIf you are unsure how to use this method, please press Cancel", comment: "Confirm that the user wants to really change the calibration type to multi-point, message") + return NSLocalizedString("confirmCalibrationChangeToMultiPointMessage", tableName: filename, bundle: Bundle.main, value: "Please confirm that you want to change the calibration type to multi-point\n\n⚠️ Please note that this method is only for advanced users and could potentially give dangerous results if not correctly calibrated.\n\nIf you are unsure how to use this method, please press Cancel.", comment: "Confirm that the user wants to really change the calibration type to multi-point, message") }() static let confirm: String = { diff --git a/xdrip/Texts/TextsCalibration.swift b/xdrip/Texts/TextsCalibration.swift index b9df6c587..e7e395688 100644 --- a/xdrip/Texts/TextsCalibration.swift +++ b/xdrip/Texts/TextsCalibration.swift @@ -17,11 +17,11 @@ enum Texts_Calibrations { }() static let singlePointCalibration:String = { - return NSLocalizedString("singlePointCalibration", tableName: filename, bundle: Bundle.main, value: "Standard Calibration", comment: "text for standard/single-point calibration") + return NSLocalizedString("singlePointCalibration", tableName: filename, bundle: Bundle.main, value: "Standard", comment: "text for standard/single-point calibration") }() static let multiPointCalibration:String = { - return NSLocalizedString("multiPointCalibration", tableName: filename, bundle: Bundle.main, value: "Multi-point Calibration", comment: "text for multi-point/non-fixed slope calibration") + return NSLocalizedString("multiPointCalibration", tableName: filename, bundle: Bundle.main, value: "Multi-point", comment: "text for multi-point/non-fixed slope calibration") }() } diff --git a/xdrip/Texts/TextsCommon.swift b/xdrip/Texts/TextsCommon.swift index 2473f626a..ad32f8568 100644 --- a/xdrip/Texts/TextsCommon.swift +++ b/xdrip/Texts/TextsCommon.swift @@ -227,6 +227,6 @@ class Texts_Common { }() static let notRequired = { - return NSLocalizedString("common_notRequired", tableName: filename, bundle: Bundle.main, value: "Not Required", comment: "not required") + return NSLocalizedString("common_notRequired", tableName: filename, bundle: Bundle.main, value: "Not required", comment: "not required") }() }