ContactTrickEntry.swift 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import CoreData
  2. import SwiftUI
  3. struct ContactImageEntry: Hashable, Equatable, Sendable {
  4. var id = UUID()
  5. var name: String = ""
  6. var layout: ContactImageLayout = .default
  7. var ring: ContactImageLargeRing = .none
  8. var primary: ContactImageValue = .glucose
  9. var top: ContactImageValue = .none
  10. var bottom: ContactImageValue = .none
  11. var contactId: String? = nil
  12. var hasHighContrast: Bool = true
  13. var ringWidth: RingWidth = .regular
  14. var ringGap: RingGap = .small
  15. var colorMode: ColorMode = .color
  16. var fontSize: FontSize = .regular
  17. var secondaryFontSize: FontSize = .small
  18. var fontWeight: Font.Weight = .medium
  19. var fontWidth: Font.Width = .standard
  20. var managedObjectID: NSManagedObjectID?
  21. static func == (lhs: ContactImageEntry, rhs: ContactImageEntry) -> Bool {
  22. lhs.id == rhs.id &&
  23. lhs.name == rhs.name &&
  24. lhs.layout == rhs.layout &&
  25. lhs.ring == rhs.ring &&
  26. lhs.primary == rhs.primary &&
  27. lhs.top == rhs.top &&
  28. lhs.bottom == rhs.bottom &&
  29. lhs.contactId == rhs.contactId &&
  30. lhs.hasHighContrast == rhs.hasHighContrast &&
  31. lhs.ringWidth == rhs.ringWidth &&
  32. lhs.ringGap == rhs.ringGap &&
  33. lhs.colorMode == rhs.colorMode &&
  34. lhs.fontSize == rhs.fontSize &&
  35. lhs.secondaryFontSize == rhs.secondaryFontSize &&
  36. lhs.fontWeight == rhs.fontWeight &&
  37. lhs.fontWidth == rhs.fontWidth
  38. }
  39. // Convert `fontWeight` to a String for Core Data storage
  40. var fontWeightString: String {
  41. fontWeight.asString
  42. }
  43. // Initialize `fontWeight` from a String
  44. static func fontWeight(from string: String) -> Font.Weight {
  45. Font.Weight.fromString(string)
  46. }
  47. // Convert `fontWidth` to a String for Core Data storage
  48. var fontWidthString: String {
  49. fontWidth.asString
  50. }
  51. // Initialize `fontWidth` from a String
  52. static func fontWidth(from string: String) -> Font.Width {
  53. Font.Width.fromString(string)
  54. }
  55. enum ColorMode: String, JSON, CaseIterable, Identifiable, Codable {
  56. var id: String { rawValue }
  57. case color
  58. case monochrome
  59. var displayName: String {
  60. switch self {
  61. case .color:
  62. return String(localized: "Color", comment: "")
  63. case .monochrome:
  64. return String(localized: "Monochrome", comment: "")
  65. }
  66. }
  67. }
  68. enum FontSize: Int, Codable, Sendable, CaseIterable {
  69. case tiny = 200
  70. case small = 250
  71. case regular = 300
  72. case large = 400
  73. var displayName: String {
  74. switch self {
  75. case .tiny: return "Tiny"
  76. case .small: return "Small"
  77. case .regular: return "Regular"
  78. case .large: return "Large"
  79. }
  80. }
  81. }
  82. enum RingWidth: Int, Codable, Sendable, CaseIterable {
  83. case tiny = 3
  84. case small = 5
  85. case regular = 7
  86. case medium = 10
  87. case large = 15
  88. var displayName: String {
  89. switch self {
  90. case .tiny: return "Tiny"
  91. case .small: return "Small"
  92. case .regular: return "Regular"
  93. case .medium: return "Medium"
  94. case .large: return "Large"
  95. }
  96. }
  97. }
  98. enum RingGap: Int, Codable, Sendable, CaseIterable {
  99. case tiny = 1
  100. case small = 2
  101. case regular = 3
  102. case medium = 4
  103. case large = 5
  104. var displayName: String {
  105. switch self {
  106. case .tiny: return "Tiny"
  107. case .small: return "Small"
  108. case .regular: return "Regular"
  109. case .medium: return "Medium"
  110. case .large: return "Large"
  111. }
  112. }
  113. }
  114. }
  115. protocol ContactImageObserver: Sendable {
  116. // TODO: is this required?
  117. // func basalProfileDidChange(_ entry: [ContactImageEntry])
  118. }
  119. enum ContactImageValue: String, JSON, CaseIterable, Identifiable, Codable {
  120. var id: String { rawValue }
  121. case none
  122. case glucose
  123. case eventualBG
  124. case delta
  125. case trend
  126. case lastLoopDate
  127. case cob
  128. case iob
  129. case ring
  130. var displayName: String {
  131. switch self {
  132. case .none:
  133. return String(localized: "None", comment: "")
  134. case .glucose:
  135. return String(localized: "Glucose Reading", comment: "")
  136. case .eventualBG:
  137. return String(localized: "Eventual Glucose", comment: "")
  138. case .delta:
  139. return String(localized: "Glucose Delta", comment: "")
  140. case .trend:
  141. return String(localized: "Glucose Trend", comment: "")
  142. case .lastLoopDate:
  143. return String(localized: "Last Loop Time", comment: "")
  144. case .cob:
  145. return String(localized: "COB", comment: "")
  146. case .iob:
  147. return String(localized: "IOB", comment: "")
  148. case .ring:
  149. return String(localized: "Loop Status", comment: "")
  150. }
  151. }
  152. }
  153. enum ContactImageLayout: String, JSON, CaseIterable, Identifiable, Codable {
  154. var id: String { rawValue }
  155. case `default`
  156. case split
  157. var displayName: String {
  158. switch self {
  159. case .default:
  160. return String(localized: "Default", comment: "")
  161. case .split:
  162. return String(localized: "Split", comment: "")
  163. }
  164. }
  165. }
  166. enum ContactImageLargeRing: String, JSON, CaseIterable, Identifiable, Codable {
  167. // TODO: revisit rings for iob, cob and combined iob+cob with more user feedback
  168. var id: String { rawValue }
  169. case none
  170. case loop
  171. // case iob
  172. // case cob
  173. // case iobcob
  174. var displayName: String {
  175. switch self {
  176. case .none:
  177. return String(localized: "Hidden", comment: "")
  178. case .loop:
  179. return String(localized: "Loop Status", comment: "")
  180. // case .iob:
  181. // return String(localized: "Insulin on Board (IOB)", comment: "")
  182. // case .cob:
  183. // return String(localized: "Carbs on Board (COB)", comment: "")
  184. // case .iobcob:
  185. // return String(localized: "IOB + COB", comment: "")
  186. }
  187. }
  188. }