CGMRootView.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import LoopKitUI
  2. import SwiftUI
  3. import Swinject
  4. extension CGM {
  5. struct RootView: BaseView {
  6. let resolver: Resolver
  7. @StateObject var state = StateModel()
  8. @State private var setupCGM = false
  9. @Environment(\.colorScheme) var colorScheme
  10. var color: LinearGradient {
  11. colorScheme == .dark ? LinearGradient(
  12. gradient: Gradient(colors: [
  13. Color("Background_1"),
  14. Color("Background_1"),
  15. Color("Background_2")
  16. // Color("Background_1")
  17. ]),
  18. startPoint: .top,
  19. endPoint: .bottom
  20. )
  21. :
  22. LinearGradient(
  23. gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
  24. startPoint: .top,
  25. endPoint: .bottom
  26. )
  27. }
  28. // @AppStorage(UserDefaults.BTKey.cgmTransmitterDeviceAddress.rawValue) private var cgmTransmitterDeviceAddress: String? = nil
  29. var body: some View {
  30. NavigationView {
  31. Form {
  32. Section(header: Text("CGM")) {
  33. Picker("Type", selection: $state.cgm) {
  34. ForEach(CGMType.allCases) { type in
  35. VStack(alignment: .leading) {
  36. Text(type.displayName)
  37. Text(type.subtitle).font(.caption).foregroundColor(.secondary)
  38. }.tag(type)
  39. }
  40. }
  41. if let link = state.cgm.externalLink {
  42. Button("About this source") {
  43. UIApplication.shared.open(link, options: [:], completionHandler: nil)
  44. }
  45. }
  46. }
  47. if [.dexcomG5, .dexcomG6, .dexcomG7].contains(state.cgm) {
  48. Section {
  49. Button("CGM Configuration") {
  50. setupCGM.toggle()
  51. }
  52. }
  53. }
  54. if state.cgm == .xdrip {
  55. Section(header: Text("Heartbeat")) {
  56. VStack(alignment: .leading) {
  57. if let cgmTransmitterDeviceAddress = state.cgmTransmitterDeviceAddress {
  58. Text("CGM address :")
  59. Text(cgmTransmitterDeviceAddress)
  60. } else {
  61. Text("CGM is not used as heartbeat.")
  62. }
  63. }
  64. }
  65. }
  66. if state.cgm == .libreTransmitter {
  67. Button("Configure Libre Transmitter") {
  68. state.showModal(for: .libreConfig)
  69. }
  70. Text("Calibrations").navigationLink(to: .calibrations, from: self)
  71. }
  72. Section(header: Text("Calendar")) {
  73. Toggle("Create Events in Calendar", isOn: $state.createCalendarEvents)
  74. if state.calendarIDs.isNotEmpty {
  75. Picker("Calendar", selection: $state.currentCalendarID) {
  76. ForEach(state.calendarIDs, id: \.self) {
  77. Text($0).tag($0)
  78. }
  79. }
  80. Toggle("Display Emojis as Labels", isOn: $state.displayCalendarEmojis)
  81. Toggle("Display IOB and COB", isOn: $state.displayCalendarIOBandCOB)
  82. } else if state.createCalendarEvents {
  83. if #available(iOS 17.0, *) {
  84. Text(
  85. "If you are not seeing calendars to choose here, please go to Settings -> iAPS -> Calendars and change permissions to \"Full Access\""
  86. ).font(.footnote)
  87. Button("Open Settings") {
  88. // Get the settings URL and open it
  89. if let url = URL(string: UIApplication.openSettingsURLString) {
  90. UIApplication.shared.open(url)
  91. }
  92. }
  93. }
  94. }
  95. }
  96. Section(header: Text("Experimental")) {
  97. Toggle("Smooth Glucose Value", isOn: $state.smoothGlucose)
  98. }
  99. }
  100. .scrollContentBackground(.hidden).background(color)
  101. .onAppear(perform: configureView)
  102. .navigationTitle("CGM")
  103. .navigationBarTitleDisplayMode(.automatic)
  104. .sheet(isPresented: $setupCGM) {
  105. if let cgmFetchManager = state.cgmManager, cgmFetchManager.glucoseSource.cgmType == state.cgm {
  106. CGMSettingsView(
  107. cgmManager: cgmFetchManager.glucoseSource.cgmManager!,
  108. bluetoothManager: state.provider.apsManager.bluetoothManager!,
  109. unit: state.settingsManager.settings.units,
  110. completionDelegate: state
  111. )
  112. } else {
  113. CGMSetupView(
  114. CGMType: state.cgm,
  115. bluetoothManager: state.provider.apsManager.bluetoothManager!,
  116. unit: state.settingsManager.settings.units,
  117. completionDelegate: state,
  118. setupDelegate: state
  119. )
  120. }
  121. }
  122. .onChange(of: setupCGM) { setupCGM in
  123. state.setupCGM = setupCGM
  124. }
  125. .onChange(of: state.setupCGM) { setupCGM in
  126. self.setupCGM = setupCGM
  127. }
  128. }
  129. }
  130. }
  131. }