GraphSettingsView.swift 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // LoopFollow
  2. // GraphSettingsView.swift
  3. // Created by Jonas Björkert on 2025-05-26.
  4. import SwiftUI
  5. struct GraphSettingsView: View {
  6. @Environment(\.presentationMode) private var presentationMode
  7. // ── Stored settings ──────────────────────────────────────────────────────
  8. @ObservedObject private var showDots = Storage.shared.showDots
  9. @ObservedObject private var showLines = Storage.shared.showLines
  10. @ObservedObject private var showValues = Storage.shared.showValues
  11. @ObservedObject private var showAbsorption = Storage.shared.showAbsorption
  12. @ObservedObject private var showDIALines = Storage.shared.showDIALines
  13. @ObservedObject private var show30MinLine = Storage.shared.show30MinLine
  14. @ObservedObject private var show90MinLine = Storage.shared.show90MinLine
  15. @ObservedObject private var showMidnightLines = Storage.shared.showMidnightLines
  16. @ObservedObject private var smallGraphTreatments = Storage.shared.smallGraphTreatments
  17. @ObservedObject private var smallGraphHeight = Storage.shared.smallGraphHeight
  18. @ObservedObject private var predictionToLoad = Storage.shared.predictionToLoad
  19. @ObservedObject private var minBasalScale = Storage.shared.minBasalScale
  20. @ObservedObject private var minBGScale = Storage.shared.minBGScale
  21. @ObservedObject private var lowLine = Storage.shared.lowLine
  22. @ObservedObject private var highLine = Storage.shared.highLine
  23. @ObservedObject private var downloadDays = Storage.shared.downloadDays
  24. // ─────────────────────────────────────────────────────────────────────────
  25. private var nightscoutEnabled: Bool { IsNightscoutEnabled() }
  26. var body: some View {
  27. NavigationStack {
  28. Form {
  29. // ── Graph Display ────────────────────────────────────────────
  30. Section("Graph Display") {
  31. Toggle("Display Dots", isOn: $showDots.value)
  32. .onChange(of: showDots.value) { _ in markDirty() }
  33. Toggle("Display Lines", isOn: $showLines.value)
  34. .onChange(of: showLines.value) { _ in markDirty() }
  35. if nightscoutEnabled {
  36. Toggle("Show DIA Lines", isOn: $showDIALines.value)
  37. .onChange(of: showDIALines.value) { _ in markDirty() }
  38. Toggle("Show −30 min Line", isOn: $show30MinLine.value)
  39. .onChange(of: show30MinLine.value) { _ in markDirty() }
  40. Toggle("Show −90 min Line", isOn: $show90MinLine.value)
  41. .onChange(of: show90MinLine.value) { _ in markDirty() }
  42. }
  43. Toggle("Show Midnight Lines", isOn: $showMidnightLines.value)
  44. .onChange(of: showMidnightLines.value) { _ in markDirty() }
  45. }
  46. // ── Treatments ───────────────────────────────────────────────
  47. if nightscoutEnabled {
  48. Section("Treatments") {
  49. Toggle("Show Carb/Bolus Values", isOn: $showValues.value)
  50. Toggle("Show Carb Absorption", isOn: $showAbsorption.value)
  51. Toggle("Treatments on Small Graph",
  52. isOn: $smallGraphTreatments.value)
  53. }
  54. }
  55. // ── Small Graph ──────────────────────────────────────────────
  56. Section("Small Graph") {
  57. SettingsStepperRow(
  58. title: "Height",
  59. range: 40 ... 80,
  60. step: 5,
  61. value: $smallGraphHeight.value,
  62. format: { "\(Int($0)) pt" }
  63. )
  64. .onChange(of: smallGraphHeight.value) { _ in markDirty() }
  65. }
  66. // ── Prediction ───────────────────────────────────────────────
  67. if nightscoutEnabled {
  68. Section("Prediction") {
  69. SettingsStepperRow(
  70. title: "Hours of Prediction",
  71. range: 0 ... 6,
  72. step: 0.25,
  73. value: $predictionToLoad.value,
  74. format: { "\($0.localized(maxFractionDigits: 2)) h" }
  75. )
  76. }
  77. }
  78. // ── Basal / BG scale ─────────────────────────────────────────
  79. if nightscoutEnabled {
  80. Section("Basal / BG Scale") {
  81. SettingsStepperRow(
  82. title: "Min Basal",
  83. range: 0.5 ... 20,
  84. step: 0.5,
  85. value: $minBasalScale.value,
  86. format: { "\($0.localized(maxFractionDigits: 1)) U/h" }
  87. )
  88. BGPicker(
  89. title: "Min BG Scale",
  90. range: 40 ... 400,
  91. value: $minBGScale.value
  92. )
  93. .onChange(of: minBGScale.value) { _ in markDirty() }
  94. }
  95. }
  96. // ── Target lines ─────────────────────────────────────────────
  97. Section("Target Lines") {
  98. BGPicker(title: "Low BG Line",
  99. range: 40 ... 120,
  100. value: $lowLine.value)
  101. .onChange(of: lowLine.value) { _ in markDirty() }
  102. BGPicker(title: "High BG Line",
  103. range: 120 ... 400,
  104. value: $highLine.value)
  105. .onChange(of: highLine.value) { _ in markDirty() }
  106. }
  107. // ── History window ───────────────────────────────────────────
  108. if nightscoutEnabled {
  109. Section("History") {
  110. SettingsStepperRow(
  111. title: "Show Days Back",
  112. range: 1 ... 4,
  113. step: 1,
  114. value: $downloadDays.value,
  115. format: { "\(Int($0)) d" }
  116. )
  117. }
  118. }
  119. }
  120. .navigationTitle("Graph Settings")
  121. .toolbar {
  122. ToolbarItem(placement: .confirmationAction) {
  123. Button("Done") { presentationMode.wrappedValue.dismiss() }
  124. }
  125. }
  126. }
  127. }
  128. /// Marks the chart as needing a redraw
  129. private func markDirty() {
  130. Observable.shared.chartSettingsChanged.value = true
  131. }
  132. }