initial heartbeat UI implementation for data source
This commit is contained in:
parent
4f0b9589e6
commit
ecb3539645
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"originHash" : "20a19467224593c1dcb0789843c73f4580a23d8227b26f5a2c54d6c62c75927e",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "actionclosurable",
|
||||
|
@ -37,5 +38,5 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
"version" : 3
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ class DexcomG7HeartbeatBluetoothTransmitter: BluetoothTransmitter {
|
|||
self.bluetoothTransmitterDelegate?.heartBeat()
|
||||
|
||||
lastHeartBeatTimeStamp = Date()
|
||||
|
||||
UserDefaults.standard.lastHeartBeatTimeStamp = lastHeartBeatTimeStamp
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ class Libre3HeartBeatBluetoothTransmitter: BluetoothTransmitter {
|
|||
|
||||
lastHeartBeatTimeStamp = Date()
|
||||
|
||||
UserDefaults.standard.lastHeartBeatTimeStamp = lastHeartBeatTimeStamp
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,6 +87,9 @@ class Libre3HeartBeatBluetoothTransmitter: BluetoothTransmitter {
|
|||
|
||||
lastHeartBeatTimeStamp = Date()
|
||||
|
||||
UserDefaults.standard.lastHeartBeatTimeStamp = lastHeartBeatTimeStamp
|
||||
|
||||
print("heatbeat timestamp: \(lastHeartBeatTimeStamp)")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ class OmniPodHeartBeatTransmitter: BluetoothTransmitter {
|
|||
|
||||
lastHeartBeatTimeStamp = Date()
|
||||
|
||||
UserDefaults.standard.lastHeartBeatTimeStamp = lastHeartBeatTimeStamp
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,6 +87,8 @@ class OmniPodHeartBeatTransmitter: BluetoothTransmitter {
|
|||
|
||||
lastHeartBeatTimeStamp = Date()
|
||||
|
||||
UserDefaults.standard.lastHeartBeatTimeStamp = lastHeartBeatTimeStamp
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -394,6 +394,10 @@ extension UserDefaults {
|
|||
/// - stored as data as read from transmitter
|
||||
case librePatchInfo = "librePatchInfo"
|
||||
|
||||
// heartbeat
|
||||
/// the last heartbeat connection timestamp
|
||||
case lastHeartBeatTimeStamp = "lastHeartBeatTimeStamp"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2191,6 +2195,19 @@ extension UserDefaults {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Heartbeat
|
||||
|
||||
/// timestamp of last successful connection to follower service
|
||||
@objc dynamic var lastHeartBeatTimeStamp: Date? {
|
||||
get {
|
||||
return object(forKey: Key.lastHeartBeatTimeStamp.rawValue) as? Date
|
||||
}
|
||||
set {
|
||||
set(newValue, forKey: Key.lastHeartBeatTimeStamp.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -719,8 +719,8 @@ public class AlertManager:NSObject {
|
|||
return true
|
||||
|
||||
} else {
|
||||
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())
|
||||
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)
|
||||
} else {
|
||||
trace("in checkAlert, there's no need to raise alert %{public}@", log: self.log, category: ConstantsLog.categoryAlertManager, type: .info, alertKind.descriptionForLogging())
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ public enum FollowerBackgroundKeepAliveType: Int, CaseIterable {
|
|||
case disabled = 0
|
||||
case normal = 1
|
||||
case aggressive = 2
|
||||
case heartbeat = 3
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
|
@ -29,6 +30,8 @@ public enum FollowerBackgroundKeepAliveType: Int, CaseIterable {
|
|||
return Texts_SettingsView.followerKeepAliveTypeNormal
|
||||
case .aggressive:
|
||||
return Texts_SettingsView.followerKeepAliveTypeAggressive
|
||||
case .heartbeat:
|
||||
return Texts_SettingsView.followerKeepAliveTypeHeartbeat
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +43,19 @@ public enum FollowerBackgroundKeepAliveType: Int, CaseIterable {
|
|||
return 1
|
||||
case .aggressive:
|
||||
return 2
|
||||
case .heartbeat:
|
||||
return 3
|
||||
}
|
||||
}
|
||||
|
||||
// return true if in follower mode and if the keep-alive type should provoke a background keep-alive action
|
||||
// basically if not .disabled and if not .heartbeat
|
||||
var shouldKeepAlive: Bool {
|
||||
switch self {
|
||||
case .disabled, .heartbeat:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +68,8 @@ public enum FollowerBackgroundKeepAliveType: Int, CaseIterable {
|
|||
return UIImage(systemName: "n.circle") ?? UIImage()
|
||||
case .aggressive:
|
||||
return UIImage(systemName: "a.circle") ?? UIImage()
|
||||
case .heartbeat:
|
||||
return UIImage(systemName: "heart.circle") ?? UIImage()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +82,8 @@ public enum FollowerBackgroundKeepAliveType: Int, CaseIterable {
|
|||
return Image(systemName: "n.circle")
|
||||
case .aggressive:
|
||||
return Image(systemName: "a.circle")
|
||||
case .heartbeat:
|
||||
return Image(systemName: "heart.circle")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -758,9 +758,9 @@ class LibreLinkUpFollowManager: NSObject {
|
|||
private func enableSuspensionPrevention() {
|
||||
|
||||
// if keep-alive is disabled or if using a heartbeat, then just return and do nothing
|
||||
if UserDefaults.standard.followerBackgroundKeepAliveType == .disabled || UserDefaults.standard.followerBackgroundKeepAliveType == {
|
||||
if !UserDefaults.standard.followerBackgroundKeepAliveType.shouldKeepAlive {
|
||||
|
||||
print("not enabling suspension prevention as keep-alive is disabled")
|
||||
print("not enabling suspension prevention as keep-alive type is: \(UserDefaults.standard.followerBackgroundKeepAliveType.description)")
|
||||
|
||||
return
|
||||
|
||||
|
@ -803,7 +803,8 @@ class LibreLinkUpFollowManager: NSObject {
|
|||
if !UserDefaults.standard.isMaster && UserDefaults.standard.followerDataSourceType == .libreLinkUp && UserDefaults.standard.libreLinkUpEmail != nil && UserDefaults.standard.libreLinkUpPassword != nil {
|
||||
|
||||
// this will enable the suspension prevention sound playing if background keep-alive is enabled
|
||||
if UserDefaults.standard.followerBackgroundKeepAliveType != .disabled {
|
||||
// (i.e. not disabled and not using a heartbeat)
|
||||
if UserDefaults.standard.followerBackgroundKeepAliveType.shouldKeepAlive {
|
||||
enableSuspensionPrevention()
|
||||
} else {
|
||||
disableSuspensionPrevention()
|
||||
|
|
|
@ -365,8 +365,8 @@ class NightScoutFollowManager: NSObject {
|
|||
/// launches timer that will regular play sound - this will be played only when app goes to background and only if the user wants to keep the app alive
|
||||
private func enableSuspensionPrevention() {
|
||||
|
||||
// if keep-alive is disabled, then just return and do nothing
|
||||
if UserDefaults.standard.followerBackgroundKeepAliveType == .disabled {
|
||||
// if keep-alive is not needed, then just return and do nothing
|
||||
if !UserDefaults.standard.followerBackgroundKeepAliveType.shouldKeepAlive {
|
||||
|
||||
print("not enabling suspension prevention as keep-alive is disabled")
|
||||
|
||||
|
|
|
@ -128,6 +128,10 @@ class Texts_SettingsView {
|
|||
return NSLocalizedString("settingsviews_followerKeepAliveTypeAggressive", tableName: filename, bundle: Bundle.main, value: "Aggressive", comment: "data source settings, keep-alive mode is set to aggressive")
|
||||
}()
|
||||
|
||||
static let followerKeepAliveTypeHeartbeat: String = {
|
||||
return NSLocalizedString("settingsviews_followerKeepAliveTypeHeartbeat", tableName: filename, bundle: Bundle.main, value: "Heartbeat ♥", comment: "data source settings, keep-alive mode is set to use an external heartbeat")
|
||||
}()
|
||||
|
||||
static let followerKeepAliveTypeDisabledMessage: String = {
|
||||
return NSLocalizedString("settingsviews_followerKeepAliveTypeDisabledMessage", tableName: filename, bundle: Bundle.main, value: "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.", comment: "data source settings, keep-alive mode is set to disabled")
|
||||
}()
|
||||
|
@ -140,6 +144,10 @@ class Texts_SettingsView {
|
|||
return NSLocalizedString("settingsviews_followerKeepAliveTypeAggressiveMessage", tableName: filename, bundle: Bundle.main, value: "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.", comment: "data source settings, keep-alive mode is set to aggressive")
|
||||
}()
|
||||
|
||||
static let followerKeepAliveTypeHeartbeatMessage: String = {
|
||||
return NSLocalizedString("settingsviews_followerKeepAliveTypeHeartbeatMessage", tableName: filename, bundle: Bundle.main, value: "Background keep-alive is set to use an external heartbeat. ❤️\n\nWhen the app is not on screen, the external heartbeat will wake it up in the background so that BG updates are received and alarms can be triggered.\n\nMake sure you add a heartbeat device in the Bluetooth screen.\n\nThis mode has very little impact on the battery of your device but will only work if a valid heartbeat is running.", comment: "data source settings, keep-alive mode is set to use an external heartbeat")
|
||||
}()
|
||||
|
||||
static let followerPatientName: String = {
|
||||
return NSLocalizedString("settingsviews_followerPatientName", tableName: filename, bundle: Bundle.main, value: "Patient Name", comment: "data source settings, the name of the person we are following")
|
||||
}()
|
||||
|
|
|
@ -919,6 +919,9 @@ final class RootViewController: UIViewController, ObservableObject {
|
|||
|
||||
// add observer for showAppleWatchDebug, to reload the watch app view if the value changes
|
||||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.showAppleWatchDebug.rawValue, options: .new, context: nil)
|
||||
|
||||
// add observer for the last heartbeat timestamp in order to update the UI
|
||||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.lastHeartBeatTimeStamp.rawValue, options: .new, context: nil)
|
||||
|
||||
// setup delegate for UNUserNotificationCenter
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
|
@ -1692,8 +1695,10 @@ final class RootViewController: UIViewController, ObservableObject {
|
|||
}
|
||||
|
||||
case UserDefaults.Key.showAppleWatchDebug:
|
||||
|
||||
watchManager?.updateWatchApp()
|
||||
|
||||
case UserDefaults.Key.lastHeartBeatTimeStamp:
|
||||
updateDataSourceInfo(animate: false)
|
||||
|
||||
default:
|
||||
break
|
||||
|
@ -3237,6 +3242,15 @@ final class RootViewController: UIViewController, ObservableObject {
|
|||
// let's go through the specific cases for follower modes
|
||||
if !isMaster {
|
||||
|
||||
// first set the heartbeat icon color depending on when the last heartbeat was received
|
||||
if UserDefaults.standard.followerBackgroundKeepAliveType == .heartbeat {
|
||||
if let lastHeartBeatTimeStamp = UserDefaults.standard.lastHeartBeatTimeStamp, lastHeartBeatTimeStamp < Date().addingTimeInterval(-30) {
|
||||
dataSourceKeepAliveImageOutlet.tintColor = .systemRed
|
||||
} else {
|
||||
dataSourceKeepAliveImageOutlet.tintColor = .systemGreen
|
||||
}
|
||||
}
|
||||
|
||||
dataSourceLabelOutlet.text = UserDefaults.standard.followerDataSourceType.fullDescription
|
||||
|
||||
switch UserDefaults.standard.followerDataSourceType {
|
||||
|
|
|
@ -249,6 +249,8 @@ class SettingsViewDataSourceSettingsViewModel: NSObject, SettingsViewModelProtoc
|
|||
message += Texts_SettingsView.followerKeepAliveTypeNormalMessage
|
||||
case .aggressive:
|
||||
message += Texts_SettingsView.followerKeepAliveTypeAggressiveMessage
|
||||
case .heartbeat:
|
||||
message += Texts_SettingsView.followerKeepAliveTypeHeartbeatMessage
|
||||
}
|
||||
|
||||
self.callMessageHandlerInMainThread(title: Texts_SettingsView.labelfollowerKeepAliveType, message: message)
|
||||
|
|
Loading…
Reference in New Issue