GlucoseNotificationSettingsRootView.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. import ActivityKit
  2. import Combine
  3. import SwiftUI
  4. import Swinject
  5. extension GlucoseNotificationSettings {
  6. struct RootView: BaseView {
  7. let resolver: Resolver
  8. @StateObject var state = StateModel()
  9. @State private var shouldDisplayHint: Bool = false
  10. @State var hintDetent = PresentationDetent.large
  11. @State var selectedVerboseHint: String?
  12. @State var hintLabel: String?
  13. @State private var decimalPlaceholder: Decimal = 0.0
  14. @State private var booleanPlaceholder: Bool = false
  15. @State var notificationsDisabled = false
  16. private var glucoseFormatter: NumberFormatter {
  17. let formatter = NumberFormatter()
  18. formatter.numberStyle = .decimal
  19. formatter.maximumFractionDigits = 0
  20. if state.units == .mmolL {
  21. formatter.maximumFractionDigits = 1
  22. }
  23. formatter.roundingMode = .halfUp
  24. return formatter
  25. }
  26. private var carbsFormatter: NumberFormatter {
  27. let formatter = NumberFormatter()
  28. formatter.numberStyle = .decimal
  29. formatter.maximumFractionDigits = 0
  30. return formatter
  31. }
  32. @Environment(\.colorScheme) var colorScheme
  33. var color: LinearGradient {
  34. colorScheme == .dark ? LinearGradient(
  35. gradient: Gradient(colors: [
  36. Color.bgDarkBlue,
  37. Color.bgDarkerDarkBlue
  38. ]),
  39. startPoint: .top,
  40. endPoint: .bottom
  41. )
  42. :
  43. LinearGradient(
  44. gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
  45. startPoint: .top,
  46. endPoint: .bottom
  47. )
  48. }
  49. var body: some View {
  50. Form {
  51. SettingInputSection(
  52. decimalValue: $decimalPlaceholder,
  53. booleanValue: $state.notificationsPump,
  54. shouldDisplayHint: $shouldDisplayHint,
  55. selectedVerboseHint: Binding(
  56. get: { selectedVerboseHint },
  57. set: {
  58. selectedVerboseHint = $0
  59. hintLabel = "Always Notify Pump"
  60. }
  61. ),
  62. units: state.units,
  63. type: .boolean,
  64. label: "Always Notify Pump",
  65. miniHint: "Always Notify Pump Warnings",
  66. verboseHint: "With iOS Trio Notifications enabled, you can let Trio display most Pump Notifications in iOS Notification Center as a Banner, List and on the Lock Screen. It allows you to refer to Trio Information at a glance and troubleshoot any informational issue.\n\nIf iOS Trio Notifications is disabled, Trio will display these messages in-app as a banner only.\n\nAn example of a Pump Warning is 'Pod Expiration Reminder'",
  67. headerText: "Trio Information Notifications"
  68. )
  69. SettingInputSection(
  70. decimalValue: $decimalPlaceholder,
  71. booleanValue: $state.notificationsCgm,
  72. shouldDisplayHint: $shouldDisplayHint,
  73. selectedVerboseHint: Binding(
  74. get: { selectedVerboseHint },
  75. set: {
  76. selectedVerboseHint = $0
  77. hintLabel = "Always Notify CGM"
  78. }
  79. ),
  80. units: state.units,
  81. type: .boolean,
  82. label: "Always Notify CGM",
  83. miniHint: "Always Notify CGM Warnings",
  84. verboseHint: "With iOS Trio Notifications enabled, you can let Trio display most CGM Notifications in iOS Notification Center as a Banner, List and on the Lock Screen. It allows you to refer to Trio Information at a glance and troubleshoot any informational issue.\n\nIf iOS Trio Notifications is disabled, Trio will display these messages in-app as a banner only.\n\nAn example of a CGM Warning is 'Unable to open the app'"
  85. )
  86. SettingInputSection(
  87. decimalValue: $decimalPlaceholder,
  88. booleanValue: $state.notificationsCarb,
  89. shouldDisplayHint: $shouldDisplayHint,
  90. selectedVerboseHint: Binding(
  91. get: { selectedVerboseHint },
  92. set: {
  93. selectedVerboseHint = $0
  94. hintLabel = "Always Notify Carb"
  95. }
  96. ),
  97. units: state.units,
  98. type: .boolean,
  99. label: "Always Notify Carb",
  100. miniHint: "Always Notify Carb Warnings",
  101. verboseHint: "With iOS Trio Notifications enabled, you can let Trio display most Carb Notifications in iOS Notification Center as a Banner, List and on the Lock Screen. It allows you to refer to Trio Information at a glance and troubleshoot any informational issue.\n\nIf iOS Trio Notifications is disabled, Trio will display these messages in-app as a banner only.\n\nAn example of a Carb Warning is 'Carbs required: 30 g'"
  102. )
  103. SettingInputSection(
  104. decimalValue: $decimalPlaceholder,
  105. booleanValue: $state.notificationsAlgorithm,
  106. shouldDisplayHint: $shouldDisplayHint,
  107. selectedVerboseHint: Binding(
  108. get: { selectedVerboseHint },
  109. set: {
  110. selectedVerboseHint = $0
  111. hintLabel = "Always Notify Algorithm"
  112. }
  113. ),
  114. units: state.units,
  115. type: .boolean,
  116. label: "Always Notify Algorithm",
  117. miniHint: "Always Notify Algorithm Warnings",
  118. verboseHint: "With iOS Trio Notifications enabled, you can let Trio display most Algorithm Notifications in iOS Notification Center as a Banner, List and on the Lock Screen. It allows you to refer to Trio Information at a glance and troubleshoot any informational issue.\n\nIf iOS Trio Notifications is disabled, Trio will display these messages in-app as a banner only.\n\nAn example of a Algorithm Warning is 'Error: Invalid glucose: Not enough glucose data'"
  119. )
  120. SettingInputSection(
  121. decimalValue: $decimalPlaceholder,
  122. booleanValue: $state.glucoseBadge,
  123. shouldDisplayHint: $shouldDisplayHint,
  124. selectedVerboseHint: Binding(
  125. get: { selectedVerboseHint },
  126. set: {
  127. selectedVerboseHint = $0
  128. hintLabel = "Show Glucose App Badge"
  129. }
  130. ),
  131. units: state.units,
  132. type: .boolean,
  133. label: "Show Glucose App Badge",
  134. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  135. verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  136. headerText: "Various Glucose Notifications"
  137. )
  138. SettingInputSection(
  139. decimalValue: $decimalPlaceholder,
  140. booleanValue: $state.glucoseNotificationsAlways,
  141. shouldDisplayHint: $shouldDisplayHint,
  142. selectedVerboseHint: Binding(
  143. get: { selectedVerboseHint },
  144. set: {
  145. selectedVerboseHint = $0
  146. hintLabel = "e"
  147. }
  148. ),
  149. units: state.units,
  150. type: .boolean,
  151. label: "Always Notify Glucose",
  152. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  153. verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
  154. )
  155. SettingInputSection(
  156. decimalValue: $decimalPlaceholder,
  157. booleanValue: $state.useAlarmSound,
  158. shouldDisplayHint: $shouldDisplayHint,
  159. selectedVerboseHint: Binding(
  160. get: { selectedVerboseHint },
  161. set: {
  162. selectedVerboseHint = $0
  163. hintLabel = "Play Alarm Sound"
  164. }
  165. ),
  166. units: state.units,
  167. type: .boolean,
  168. label: "Play Alarm Sound",
  169. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  170. verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
  171. )
  172. SettingInputSection(
  173. decimalValue: $decimalPlaceholder,
  174. booleanValue: $state.addSourceInfoToGlucoseNotifications,
  175. shouldDisplayHint: $shouldDisplayHint,
  176. selectedVerboseHint: Binding(
  177. get: { selectedVerboseHint },
  178. set: {
  179. selectedVerboseHint = $0
  180. hintLabel = "Add Glucose Source to Alarm"
  181. }
  182. ),
  183. units: state.units,
  184. type: .boolean,
  185. label: "Add Glucose Source to Alarm",
  186. miniHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
  187. verboseHint: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr."
  188. )
  189. Section {
  190. HStack {
  191. Text("Low Glucose Alarm Limit")
  192. Spacer()
  193. TextFieldWithToolBar(text: $state.lowGlucose, placeholder: "0", numberFormatter: glucoseFormatter)
  194. Text(state.units.rawValue).foregroundColor(.secondary)
  195. }.padding(.top)
  196. HStack {
  197. Text("High Glucose Alarm Limit")
  198. Spacer()
  199. TextFieldWithToolBar(text: $state.highGlucose, placeholder: "0", numberFormatter: glucoseFormatter)
  200. Text(state.units.rawValue).foregroundColor(.secondary)
  201. }
  202. HStack(alignment: .top) {
  203. Text(
  204. "Set the lower and upper limit for glucose alarms. See hint for more details."
  205. )
  206. .font(.footnote)
  207. .foregroundColor(.secondary)
  208. .lineLimit(nil)
  209. Spacer()
  210. Button(
  211. action: {
  212. hintLabel = "Low and High Glucose Alarm Limits"
  213. selectedVerboseHint =
  214. "These two settings limit the range outside of which you will be notified via push notifications. If your CGM readings are below 'Low' or above 'High', you will receive a glucose alarm."
  215. shouldDisplayHint.toggle()
  216. },
  217. label: {
  218. HStack {
  219. Image(systemName: "questionmark.circle")
  220. }
  221. }
  222. ).buttonStyle(BorderlessButtonStyle())
  223. }.padding(.vertical)
  224. // }
  225. .listRowBackground(Color.chart)
  226. }
  227. }
  228. .sheet(isPresented: $shouldDisplayHint) {
  229. SettingInputHintView(
  230. hintDetent: $hintDetent,
  231. shouldDisplayHint: $shouldDisplayHint,
  232. hintLabel: hintLabel ?? "",
  233. hintText: selectedVerboseHint ?? "",
  234. sheetTitle: "Help"
  235. )
  236. }
  237. .onReceive(
  238. resolver.resolve(AlertPermissionsChecker.self)!.$notificationsDisabled,
  239. perform: {
  240. notificationsDisabled = $0
  241. }
  242. )
  243. .scrollContentBackground(.hidden).background(color)
  244. // .onAppear(perform: configureView)
  245. .onAppear {
  246. configureView {}
  247. }
  248. .navigationBarTitle("Trio Notifications")
  249. .navigationBarTitleDisplayMode(.automatic)
  250. }
  251. }
  252. }