LiveActivityAttributes+Helper.swift 4.9 KB

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