SettingsRootView.swift 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import HealthKit
  2. import LoopKit
  3. import LoopKitUI
  4. import SwiftUI
  5. import Swinject
  6. extension Settings {
  7. struct RootView: BaseView {
  8. let resolver: Resolver
  9. @StateObject var state = StateModel()
  10. @State private var showShareSheet = false
  11. @StateObject private var viewModel = SettingsRootViewModel()
  12. @Environment(\.colorScheme) var colorScheme
  13. private var color: LinearGradient {
  14. colorScheme == .dark ? LinearGradient(
  15. gradient: Gradient(colors: [
  16. Color.bgDarkBlue,
  17. Color.bgDarkerDarkBlue
  18. ]),
  19. startPoint: .top,
  20. endPoint: .bottom
  21. )
  22. :
  23. LinearGradient(
  24. gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
  25. startPoint: .top,
  26. endPoint: .bottom
  27. )
  28. }
  29. var body: some View {
  30. Form {
  31. Section {
  32. Toggle("Closed loop", isOn: $state.closedLoop)
  33. }
  34. header: {
  35. Text(viewModel.headerText).textCase(nil)
  36. }.listRowBackground(Color.chart)
  37. Section {
  38. SettingsRowView(imageName: "chart.xyaxis.line", title: "Statistics", tint: Color.green, spacing: 10)
  39. .navigationLink(to: .statistics, from: self)
  40. } header: { Text("Statistics") }.listRowBackground(Color.chart)
  41. Section {
  42. Text("Pump").navigationLink(to: .pumpConfig, from: self)
  43. Text("CGM").navigationLink(to: .cgm, from: self)
  44. Text("Watch").navigationLink(to: .watch, from: self)
  45. } header: { Text("Devices") }.listRowBackground(Color.chart)
  46. Section {
  47. Text("Nightscout").navigationLink(to: .nighscoutConfig, from: self)
  48. NavigationLink(destination: TidepoolStartView(state: state)) {
  49. Text("Tidepool")
  50. }
  51. if HKHealthStore.isHealthDataAvailable() {
  52. Text("Apple Health").navigationLink(to: .healthkit, from: self)
  53. }
  54. Text("Shortcuts", tableName: "ShortcutsDetail").navigationLink(to: .shortcutsConfig, from: self)
  55. Text("Notifications").navigationLink(to: .notificationsConfig, from: self)
  56. Text("Bolus Calculator").navigationLink(to: .bolusCalculatorConfig, from: self)
  57. Text("App Icons").navigationLink(to: .iconConfig, from: self)
  58. Text("Statistics and Home View").navigationLink(to: .statisticsConfig, from: self)
  59. } header: { Text("Services") }.listRowBackground(Color.chart)
  60. Section {
  61. Text("Preferences").navigationLink(to: .preferencesEditor, from: self)
  62. Text("Dynamic ISF").navigationLink(to: .dynamicISF, from: self)
  63. Text("Pump Settings").navigationLink(to: .pumpSettingsEditor, from: self)
  64. Text("Meal Settings").navigationLink(to: .fpuConfig, from: self)
  65. Text("Basal Profile").navigationLink(to: .basalProfileEditor, from: self)
  66. Text("Insulin Sensitivities").navigationLink(to: .isfEditor, from: self)
  67. Text("Carb Ratios").navigationLink(to: .crEditor, from: self)
  68. Text("Target Glucose").navigationLink(to: .targetsEditor, from: self)
  69. Text("Autotune").navigationLink(to: .autotuneConfig, from: self)
  70. } header: { Text("Configuration") }.listRowBackground(Color.chart)
  71. Section {
  72. Toggle("Debug options", isOn: $state.debugOptions)
  73. if state.debugOptions {
  74. Group {
  75. HStack {
  76. Text("NS Upload Profile and Settings")
  77. Button("Upload") { state.uploadProfileAndSettings(true) }
  78. .frame(maxWidth: .infinity, alignment: .trailing)
  79. .buttonStyle(.borderedProminent)
  80. }
  81. // Commenting this out for now, as not needed and possibly dangerous for users to be able to nuke their pump pairing informations via the debug menu
  82. // Leaving it in here, as it may be a handy functionality for further testing or developers.
  83. // See https://github.com/nightscout/Trio/pull/277 for more information
  84. //
  85. // HStack {
  86. // Text("Delete Stored Pump State Binary Files")
  87. // Button("Delete") { state.resetLoopDocuments() }
  88. // .frame(maxWidth: .infinity, alignment: .trailing)
  89. // .buttonStyle(.borderedProminent)
  90. // }
  91. }
  92. Group {
  93. Text("Preferences")
  94. .navigationLink(to: .configEditor(file: OpenAPS.Settings.preferences), from: self)
  95. Text("Pump Settings")
  96. .navigationLink(to: .configEditor(file: OpenAPS.Settings.settings), from: self)
  97. Text("Autosense")
  98. .navigationLink(to: .configEditor(file: OpenAPS.Settings.autosense), from: self)
  99. Text("Pump History")
  100. .navigationLink(to: .configEditor(file: OpenAPS.Monitor.pumpHistory), from: self)
  101. Text("Basal profile")
  102. .navigationLink(to: .configEditor(file: OpenAPS.Settings.basalProfile), from: self)
  103. Text("Targets ranges")
  104. .navigationLink(to: .configEditor(file: OpenAPS.Settings.bgTargets), from: self)
  105. Text("Temp targets")
  106. .navigationLink(to: .configEditor(file: OpenAPS.Settings.tempTargets), from: self)
  107. }
  108. Group {
  109. Text("Pump profile")
  110. .navigationLink(to: .configEditor(file: OpenAPS.Settings.pumpProfile), from: self)
  111. Text("Profile")
  112. .navigationLink(to: .configEditor(file: OpenAPS.Settings.profile), from: self)
  113. Text("Carbs")
  114. .navigationLink(to: .configEditor(file: OpenAPS.Monitor.carbHistory), from: self)
  115. Text("Announcements")
  116. .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.announcements), from: self)
  117. Text("Enacted announcements")
  118. .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.announcementsEnacted), from: self)
  119. Text("Autotune")
  120. .navigationLink(to: .configEditor(file: OpenAPS.Settings.autotune), from: self)
  121. }
  122. Group {
  123. Text("Target presets")
  124. .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.tempTargetsPresets), from: self)
  125. Text("Calibrations")
  126. .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.calibrations), from: self)
  127. Text("Middleware")
  128. .navigationLink(to: .configEditor(file: OpenAPS.Middleware.determineBasal), from: self)
  129. Text("Statistics")
  130. .navigationLink(to: .configEditor(file: OpenAPS.Monitor.statistics), from: self)
  131. Text("Edit settings json")
  132. .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.settings), from: self)
  133. }
  134. }
  135. } header: { Text("Developer") }.listRowBackground(Color.chart)
  136. Section {
  137. Toggle("Animated Background", isOn: $state.animatedBackground)
  138. }.listRowBackground(Color.chart)
  139. Section {
  140. Text("Share logs")
  141. .onTapGesture {
  142. showShareSheet = true
  143. }
  144. }.listRowBackground(Color.chart)
  145. }.scrollContentBackground(.hidden).background(color)
  146. .sheet(isPresented: $showShareSheet) {
  147. ShareSheet(activityItems: state.logItems())
  148. }
  149. .onAppear(perform: configureView)
  150. .navigationTitle("Settings")
  151. .navigationBarTitleDisplayMode(.large)
  152. .onDisappear(perform: { state.uploadProfileAndSettings(false) })
  153. .screenNavigation(self)
  154. }
  155. }
  156. }