AppDiagnosticsRootView.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import SwiftUI
  2. import Swinject
  3. extension AppDiagnostics {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @State var state = StateModel()
  7. @Environment(\.colorScheme) var colorScheme
  8. @Environment(AppState.self) var appState
  9. @Environment(\.openURL) var openURL
  10. var body: some View {
  11. List {
  12. Section(
  13. header: Text("Anonymized Data Sharing"),
  14. content: {
  15. VStack(alignment: .leading) {
  16. ForEach(DiagnosticsSharingOption.allCases, id: \.self) { option in
  17. Button(action: {
  18. state.diagnosticsSharingOption = option
  19. }) {
  20. HStack(alignment: .top, spacing: 12) {
  21. Image(
  22. systemName: state
  23. .diagnosticsSharingOption == option ? "largecircle.fill.circle" : "circle"
  24. )
  25. .foregroundColor(state.diagnosticsSharingOption == option ? .accentColor : .secondary)
  26. .imageScale(.large)
  27. VStack(alignment: .leading, spacing: 4) {
  28. Text(option.displayName)
  29. .foregroundColor(.primary)
  30. .bold()
  31. Text(option.caption)
  32. .font(.footnote)
  33. .foregroundColor(.secondary)
  34. }
  35. Spacer()
  36. }
  37. .background(Color.chart.opacity(0.65))
  38. .cornerRadius(10)
  39. }
  40. .buttonStyle(.plain)
  41. }
  42. .padding()
  43. }
  44. .onChange(of: state.diagnosticsSharingOption) {
  45. state.applyDiagnostics()
  46. }
  47. }
  48. ).listRowBackground(Color.chart)
  49. Section {
  50. NavigationLink("What's sent") { TelemetryPreviewView() }
  51. NavigationLink("Privacy details") { TelemetryPrivacyView() }
  52. }.listRowBackground(Color.chart)
  53. Section {
  54. VStack(alignment: .leading, spacing: 8) {
  55. Text("Why does Trio collect this data?").bold()
  56. VStack(alignment: .leading, spacing: 4) {
  57. BulletPoint(
  58. String(
  59. localized: "App diagnostic insights — based on crash reports only — help us enhance app stability, ensure safety for all users, and quickly identify and resolve critical issues."
  60. )
  61. )
  62. BulletPoint(
  63. String(
  64. localized: "Crash reports include the app's state on crash, device, iOS and general system info, and a stack trace. They are sent to a Google Firebase Crashlytics project maintained by the Trio team."
  65. )
  66. )
  67. BulletPoint(
  68. String(
  69. localized: "Anonymous usage statistics include the app version and build, device and iOS version, which pump and CGM you have paired, and whether Nightscout, Tidepool, and Apple Health are configured (yes/no — no URLs or credentials). They are sent to a self-hosted Trio telemetry endpoint."
  70. )
  71. )
  72. BulletPoint(
  73. String(
  74. localized: "Trio does not collect any health related data, e.g. glucose readings, insulin rates or doses, meal data, therapy setting values, or similar."
  75. )
  76. )
  77. }
  78. Text(
  79. "Use \"What's sent\" above to inspect the exact JSON payload before deciding."
  80. )
  81. }
  82. .font(.footnote)
  83. .multilineTextAlignment(.leading)
  84. .foregroundStyle(Color.secondary)
  85. }.listRowBackground(Color.clear)
  86. }
  87. .listSectionSpacing(sectionSpacing)
  88. .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
  89. .onAppear(perform: configureView)
  90. .navigationBarTitle("App Diagnostics")
  91. .navigationBarTitleDisplayMode(.automatic)
  92. .toolbar {
  93. ToolbarItem(placement: .topBarTrailing) {
  94. Button("Privacy Policy") {
  95. if let url = URL(string: "https://github.com/nightscout/Trio/blob/dev/PRIVACY_POLICY.md") {
  96. openURL(url)
  97. } else {
  98. debug(.default, "Invalid URL! Could not gracefully unwrap privacy policy link!")
  99. }
  100. }
  101. }
  102. }
  103. }
  104. }
  105. }