LiveActivityAttributes+Helper.swift 4.8 KB

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