LiveActivityAttributes+Helper.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import Foundation
  2. extension UserDefaults {
  3. private enum Keys {
  4. static let liveActivityOrder = "liveActivityOrder"
  5. }
  6. func loadLiveActivityOrderFromUserDefaults() -> [String]? {
  7. array(forKey: Keys.liveActivityOrder) as? [String]
  8. }
  9. }
  10. extension LiveActivityAttributes.ContentState {
  11. static func formatGlucose(_ value: Int, units: GlucoseUnits, forceSign: Bool) -> String {
  12. let formatter = NumberFormatter()
  13. formatter.numberStyle = .decimal
  14. formatter.maximumFractionDigits = 0
  15. if units == .mmolL {
  16. formatter.minimumFractionDigits = 1
  17. formatter.maximumFractionDigits = 1
  18. }
  19. if forceSign {
  20. formatter.positivePrefix = formatter.plusSign
  21. }
  22. formatter.roundingMode = .halfUp
  23. return formatter
  24. .string(from: units == .mmolL ? value.asMmolL as NSNumber : NSNumber(value: value))!
  25. }
  26. static func calculateChange(chart: [GlucoseData], units: GlucoseUnits) -> String {
  27. guard chart.count > 2 else { return "" }
  28. let lastGlucose = chart.first?.glucose ?? 0
  29. let secondLastGlucose = chart.dropFirst().first?.glucose ?? 0
  30. let delta = lastGlucose - secondLastGlucose
  31. let deltaAsDecimal = units == .mmolL ? Decimal(delta).asMmolL : Decimal(delta)
  32. let formatter = NumberFormatter()
  33. formatter.numberStyle = .decimal
  34. formatter.maximumFractionDigits = 1
  35. if units == .mmolL {
  36. formatter.minimumFractionDigits = 1
  37. formatter.maximumFractionDigits = 1
  38. }
  39. formatter.positivePrefix = " +"
  40. formatter.negativePrefix = " -"
  41. return formatter.string(from: deltaAsDecimal as NSNumber) ?? "--"
  42. }
  43. init?(
  44. new bg: GlucoseData,
  45. prev _: GlucoseData?,
  46. units: GlucoseUnits,
  47. chart: [GlucoseData],
  48. settings: FreeAPSSettings,
  49. determination: DeterminationData?,
  50. override: OverrideData?
  51. ) {
  52. let glucose = bg.glucose
  53. let formattedBG = Self.formatGlucose(Int(glucose), units: units, forceSign: false)
  54. var rotationDegrees: Double = 0.0
  55. switch bg.direction {
  56. case .doubleUp,
  57. .singleUp,
  58. .tripleUp:
  59. rotationDegrees = -90
  60. case .fortyFiveUp:
  61. rotationDegrees = -45
  62. case .flat:
  63. rotationDegrees = 0
  64. case .fortyFiveDown:
  65. rotationDegrees = 45
  66. case .doubleDown,
  67. .singleDown,
  68. .tripleDown:
  69. rotationDegrees = 90
  70. case nil,
  71. .notComputable,
  72. .rateOutOfRange:
  73. rotationDegrees = 0
  74. default:
  75. rotationDegrees = 0
  76. }
  77. let trendString = bg.direction?.symbol as? String
  78. let change = Self.calculateChange(chart: chart, units: units)
  79. let detailedState: LiveActivityAttributes.ContentAdditionalState?
  80. switch settings.lockScreenView {
  81. case .detailed:
  82. let chartBG = chart.map { Decimal($0.glucose) }
  83. let chartDate = chart.map(\.date)
  84. /// glucose limits from UI settings, not from notifications settings
  85. detailedState = LiveActivityAttributes.ContentAdditionalState(
  86. chart: chartBG,
  87. chartDate: chartDate,
  88. rotationDegrees: rotationDegrees,
  89. highGlucose: settings.high,
  90. lowGlucose: settings.low,
  91. target: determination?.target ?? 0 as Decimal,
  92. cob: Decimal(determination?.cob ?? 0),
  93. iob: determination?.iob ?? 0 as Decimal,
  94. unit: settings.units.rawValue,
  95. isOverrideActive: override?.isActive ?? false,
  96. overrideName: override?.overrideName ?? "Override"
  97. )
  98. case .simple:
  99. detailedState = nil
  100. }
  101. let itemOrder = UserDefaults.standard
  102. .loadLiveActivityOrderFromUserDefaults() ?? ["currentGlucose", "iob", "cob", "updatedLabel"]
  103. self.init(
  104. bg: formattedBG,
  105. direction: trendString,
  106. change: change,
  107. date: bg.date,
  108. detailedViewState: detailedState,
  109. showCOB: settings.showCOB,
  110. showIOB: settings.showIOB,
  111. showCurrentGlucose: settings.showCurrentGlucose,
  112. showUpdatedLabel: settings.showUpdatedLabel,
  113. itemOrder: itemOrder,
  114. isInitialState: false
  115. )
  116. }
  117. }