LiveActivitySettingsRootView.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import ActivityKit
  2. import SwiftUI
  3. import Swinject
  4. extension LiveActivitySettings {
  5. struct RootView: BaseView {
  6. let resolver: Resolver
  7. @StateObject var state = StateModel()
  8. @State private var shouldDisplayHintLockScreen: Bool = false
  9. @State private var shouldDisplayHintSmartStack: Bool = false
  10. @State var hintDetent = PresentationDetent.large
  11. @State var selectedVerboseHint: AnyView?
  12. @State var hintLabel: String?
  13. @State private var decimalPlaceholder: Decimal = 0.0
  14. @State private var booleanPlaceholder: Bool = false
  15. @State private var systemLiveActivitySetting: Bool = {
  16. if #available(iOS 16.2, *) {
  17. ActivityAuthorizationInfo().areActivitiesEnabled
  18. } else {
  19. false
  20. }
  21. }()
  22. @Environment(\.colorScheme) var colorScheme
  23. @Environment(AppState.self) var appState
  24. var body: some View {
  25. List {
  26. if !systemLiveActivitySetting {
  27. Section(
  28. header: Text("Display Live Data From Trio"),
  29. content: {
  30. Text("Live Activities must be enabled under iOS Settings to allow Trio to display live data.")
  31. }
  32. ).listRowBackground(Color.chart)
  33. Section {
  34. Button {
  35. UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
  36. }
  37. label: { Label("Open iOS Settings", systemImage: "gear.circle").font(.title3).padding() }
  38. .frame(maxWidth: .infinity, alignment: .center)
  39. .buttonStyle(.bordered)
  40. }
  41. .listRowBackground(Color.clear)
  42. } else {
  43. SettingInputSection(
  44. decimalValue: $decimalPlaceholder,
  45. booleanValue: $state.useLiveActivity,
  46. shouldDisplayHint: $shouldDisplayHintLockScreen,
  47. selectedVerboseHint: Binding(
  48. get: { selectedVerboseHint },
  49. set: {
  50. selectedVerboseHint = $0.map { AnyView($0) }
  51. hintLabel = String(localized: "Enable Live Activity")
  52. }
  53. ),
  54. units: state.units,
  55. type: .boolean,
  56. label: String(localized: "Enable Live Activity"),
  57. miniHint: String(localized: "Display customizable data on Lock Screen and Dynamic Island."),
  58. verboseHint: VStack(alignment: .leading, spacing: 10) {
  59. Text("Default: OFF").bold()
  60. VStack(alignment: .leading, spacing: 10) {
  61. Text(
  62. "With Live Activities enabled, Trio displays your choice of the following current data on your iPhone's Lock Screen and in the Dynamic Island:"
  63. )
  64. VStack(alignment: .leading) {
  65. Text("• Current Glucose Reading")
  66. Text("• IOB: Insulin On Board")
  67. Text("• COB: Carbohydrates On Board")
  68. Text("• Last Updated: Time of Last Loop Cycle")
  69. Text("• Glucose Trend Chart")
  70. }.font(.footnote)
  71. Text(
  72. "It allows you to refer to live information at a glance and perform quick actions in your diabetes management."
  73. )
  74. }
  75. },
  76. headerText: String(localized: "Display Live Data From Trio")
  77. )
  78. if state.useLiveActivity {
  79. Section {
  80. VStack {
  81. Picker(
  82. selection: $state.lockScreenView,
  83. label: Text("Lock Screen Widget Style")
  84. ) {
  85. ForEach(LockScreenView.allCases) { selection in
  86. Text(selection.displayName).tag(selection)
  87. }
  88. }.padding(.top)
  89. HStack(alignment: .center) {
  90. Text(
  91. "Select simple or detailed style. See hint for more details."
  92. )
  93. .font(.footnote)
  94. .foregroundColor(.secondary)
  95. .lineLimit(nil)
  96. Spacer()
  97. Button(
  98. action: {
  99. hintLabel = String(localized: "Lock Screen Widget Style")
  100. selectedVerboseHint =
  101. AnyView(
  102. VStack(alignment: .leading, spacing: 10) {
  103. Text("Default: Simple").bold()
  104. VStack(alignment: .leading, spacing: 10) {
  105. Text("Simple:").bold()
  106. Text(
  107. "Trio's Simple Lock Screen Widget displays current glucose reading, trend arrow, delta and the timestamp of the current reading."
  108. )
  109. }
  110. VStack(alignment: .leading, spacing: 10) {
  111. Text("Detailed:").bold()
  112. Text(
  113. "The Detailed Lock Screen Widget offers users a glucose chart as well as the ability to customize the information provided in the Detailed Widget using the following options:"
  114. )
  115. }
  116. VStack(alignment: .leading) {
  117. Text("• Current Glucose Reading")
  118. Text("• IOB: Insulin On Board")
  119. Text("• COB: Carbohydrates On Board")
  120. Text("• Last Updated: Time of Last Loop Cycle")
  121. }.font(.footnote)
  122. }
  123. )
  124. shouldDisplayHintLockScreen.toggle()
  125. },
  126. label: {
  127. HStack {
  128. Image(systemName: "questionmark.circle")
  129. }
  130. }
  131. ).buttonStyle(BorderlessButtonStyle())
  132. }.padding(.top)
  133. }.padding(.bottom)
  134. if state.lockScreenView == .detailed {
  135. HStack {
  136. NavigationLink(
  137. "Widget Configuration",
  138. destination: LiveActivityWidgetConfiguration(
  139. resolver: resolver,
  140. state: state
  141. )
  142. ).foregroundStyle(Color.accentColor)
  143. }
  144. }
  145. }.listRowBackground(Color.chart)
  146. Section {
  147. VStack {
  148. Picker(
  149. selection: $state.smartStackView,
  150. label: Text("Watch/Carplay Widget Style")
  151. ) {
  152. ForEach(LockScreenView.allCases) { selection in
  153. Text(selection.displayName).tag(selection)
  154. }
  155. }.padding(.top)
  156. HStack(alignment: .center) {
  157. Text(
  158. "Select simple or detailed style. See hint for more details."
  159. )
  160. .font(.footnote)
  161. .foregroundColor(.secondary)
  162. .lineLimit(nil)
  163. Spacer()
  164. Button(
  165. action: {
  166. hintLabel = String(localized: "Watch/Carplay Widget Style")
  167. selectedVerboseHint =
  168. AnyView(
  169. VStack(alignment: .leading, spacing: 10) {
  170. Text("Default: Simple").bold()
  171. VStack(alignment: .leading, spacing: 10) {
  172. Text("Simple:").bold()
  173. Text(
  174. "Trio's Simple Watch/Carplay Widget displays current glucose reading, trend arrow, delta and the timestamp of the current reading."
  175. )
  176. }
  177. VStack(alignment: .leading, spacing: 10) {
  178. Text("Detailed:").bold()
  179. Text(
  180. "The Detailed Watch/Carplay Screen Widget offers users a glucose chart as well as the current glucose, delta and the timestamp of current reading."
  181. )
  182. }
  183. }
  184. )
  185. shouldDisplayHintSmartStack.toggle()
  186. },
  187. label: {
  188. HStack {
  189. Image(systemName: "questionmark.circle")
  190. }
  191. }
  192. ).buttonStyle(BorderlessButtonStyle())
  193. }.padding(.top)
  194. }.padding(.bottom)
  195. }.listRowBackground(Color.chart)
  196. }
  197. }
  198. }
  199. .listSectionSpacing(sectionSpacing)
  200. .onReceive(resolver.resolve(LiveActivityManager.self)!.$systemEnabled, perform: {
  201. self.systemLiveActivitySetting = $0
  202. })
  203. .sheet(isPresented: $shouldDisplayHintLockScreen) {
  204. SettingInputHintView(
  205. hintDetent: $hintDetent,
  206. shouldDisplayHint: $shouldDisplayHintLockScreen,
  207. hintLabel: hintLabel ?? "",
  208. hintText: selectedVerboseHint ?? AnyView(EmptyView()),
  209. sheetTitle: String(localized: "Help", comment: "Help sheet title")
  210. )
  211. }
  212. .sheet(isPresented: $shouldDisplayHintSmartStack) {
  213. SettingInputHintView(
  214. hintDetent: $hintDetent,
  215. shouldDisplayHint: $shouldDisplayHintSmartStack,
  216. hintLabel: hintLabel ?? "",
  217. hintText: selectedVerboseHint ?? AnyView(EmptyView()),
  218. sheetTitle: String(localized: "Help", comment: "Help sheet title")
  219. )
  220. }
  221. .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
  222. .onAppear(perform: configureView)
  223. .navigationTitle("Live Activity")
  224. .navigationBarTitleDisplayMode(.automatic)
  225. .settingsHighlightScroll()
  226. }
  227. }
  228. }