GraphSettingsView.swift 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // LoopFollow
  2. // GraphSettingsView.swift
  3. import SwiftUI
  4. struct GraphSettingsView: View {
  5. @ObservedObject private var showDots = Storage.shared.showDots
  6. @ObservedObject private var showLines = Storage.shared.showLines
  7. @ObservedObject private var showValues = Storage.shared.showValues
  8. @ObservedObject private var showAbsorption = Storage.shared.showAbsorption
  9. @ObservedObject private var showDIALines = Storage.shared.showDIALines
  10. @ObservedObject private var show30MinLine = Storage.shared.show30MinLine
  11. @ObservedObject private var show90MinLine = Storage.shared.show90MinLine
  12. @ObservedObject private var showMidnightLines = Storage.shared.showMidnightLines
  13. @ObservedObject private var smallGraphTreatments = Storage.shared.smallGraphTreatments
  14. @ObservedObject private var smallGraphHeight = Storage.shared.smallGraphHeight
  15. @ObservedObject private var predictionToLoad = Storage.shared.predictionToLoad
  16. @ObservedObject private var predictionDisplayType = Storage.shared.predictionDisplayType
  17. @ObservedObject private var minBasalScale = Storage.shared.minBasalScale
  18. @ObservedObject private var minBGScale = Storage.shared.minBGScale
  19. @ObservedObject private var downloadDays = Storage.shared.downloadDays
  20. private var nightscoutEnabled: Bool { IsNightscoutEnabled() }
  21. var body: some View {
  22. NavigationView {
  23. Form {
  24. // ── Graph Display ────────────────────────────────────────────
  25. Section("Graph Display") {
  26. Toggle("Display Dots", isOn: $showDots.value)
  27. .onChange(of: showDots.value) { _ in markDirty() }
  28. Toggle("Display Lines", isOn: $showLines.value)
  29. .onChange(of: showLines.value) { _ in markDirty() }
  30. if nightscoutEnabled {
  31. Toggle("Show DIA Lines", isOn: $showDIALines.value)
  32. .onChange(of: showDIALines.value) { _ in markDirty() }
  33. Toggle("Show −30 min Line", isOn: $show30MinLine.value)
  34. .onChange(of: show30MinLine.value) { _ in markDirty() }
  35. Toggle("Show −90 min Line", isOn: $show90MinLine.value)
  36. .onChange(of: show90MinLine.value) { _ in markDirty() }
  37. }
  38. Toggle("Show Midnight Lines", isOn: $showMidnightLines.value)
  39. .onChange(of: showMidnightLines.value) { _ in markDirty() }
  40. }
  41. // ── Treatments ───────────────────────────────────────────────
  42. if nightscoutEnabled {
  43. Section("Treatments") {
  44. Toggle("Show Carb/Bolus Values", isOn: $showValues.value)
  45. Toggle("Show Carb Absorption", isOn: $showAbsorption.value)
  46. Toggle("Treatments on Small Graph",
  47. isOn: $smallGraphTreatments.value)
  48. }
  49. }
  50. // ── Small Graph ──────────────────────────────────────────────
  51. Section("Small Graph") {
  52. SettingsStepperRow(
  53. title: "Height",
  54. range: 40 ... 80,
  55. step: 5,
  56. value: $smallGraphHeight.value,
  57. format: { "\(Int($0)) pt" }
  58. )
  59. .onChange(of: smallGraphHeight.value) { _ in markDirty() }
  60. }
  61. // ── Prediction ───────────────────────────────────────────────
  62. if nightscoutEnabled {
  63. Section("Prediction") {
  64. SettingsStepperRow(
  65. title: "Hours of Prediction",
  66. range: 0 ... 6,
  67. step: 0.25,
  68. value: $predictionToLoad.value,
  69. format: { "\($0.localized(maxFractionDigits: 2)) h" }
  70. )
  71. if Storage.shared.device.value != "Loop" {
  72. Picker("Prediction Style", selection: $predictionDisplayType.value) {
  73. ForEach(PredictionDisplayType.allCases, id: \.self) { type in
  74. Text(type.displayName).tag(type)
  75. }
  76. }
  77. .onChange(of: predictionDisplayType.value) { _ in markDirty() }
  78. }
  79. }
  80. }
  81. // ── Basal / BG scale ─────────────────────────────────────────
  82. if nightscoutEnabled {
  83. Section("Basal / BG Scale") {
  84. SettingsStepperRow(
  85. title: "Min Basal",
  86. range: 0.5 ... 20,
  87. step: 0.5,
  88. value: $minBasalScale.value,
  89. format: { "\($0.localized(maxFractionDigits: 1)) U/h" }
  90. )
  91. BGPicker(
  92. title: "Min BG Scale",
  93. range: 40 ... 400,
  94. value: $minBGScale.value
  95. )
  96. .onChange(of: minBGScale.value) { _ in markDirty() }
  97. }
  98. }
  99. // ── History window ───────────────────────────────────────────
  100. if nightscoutEnabled {
  101. Section("History") {
  102. SettingsStepperRow(
  103. title: "Show Days Back",
  104. range: 1 ... 4,
  105. step: 1,
  106. value: $downloadDays.value,
  107. format: { "\(Int($0)) d" }
  108. )
  109. }
  110. }
  111. }
  112. }
  113. .preferredColorScheme(Storage.shared.appearanceMode.value.colorScheme)
  114. .navigationBarTitle("Graph Settings", displayMode: .inline)
  115. }
  116. /// Marks the chart as needing a redraw
  117. private func markDirty() {
  118. Observable.shared.chartSettingsChanged.value = true
  119. }
  120. }