FastDropAlarmEditor.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // FastDropAlarmEditor.swift
  3. // LoopFollow
  4. //
  5. // Created by Jonas Björkert on 2025-05-10.
  6. // Copyright © 2025 Jon Fawcett. All rights reserved.
  7. //
  8. import SwiftUI
  9. struct FastDropAlarmEditor: View {
  10. @Binding var alarm: Alarm
  11. @State private var useLimit: Bool = false
  12. var body: some View {
  13. Form {
  14. InfoBanner(
  15. text: "Alerts when glucose readings drop rapidly. For example, three straight readings each falling by at least the amount you set. Optionally limit alerts to only fire below a certain BG level."
  16. )
  17. AlarmGeneralSection(alarm: $alarm)
  18. AlarmBGSection(
  19. header: "Rate of Fall",
  20. footer: "How much the bg must fall to count as a “fast” drop.",
  21. title: "Drop per reading",
  22. range: 3...20,
  23. value: Binding(
  24. get: { alarm.delta ?? 18 },
  25. set: { alarm.delta = $0 }
  26. )
  27. )
  28. //TODO: In the migration script, use 1 value less than stored since we are switching from readings to drops
  29. AlarmStepperSection(
  30. header: "Consecutive Drops",
  31. footer: "Number of back-to-back drops—each meeting the rate above—required before an alert fires.",
  32. title: "Drops in a row",
  33. range: 1...3,
  34. step: 1,
  35. value: Binding(
  36. get: { Double(alarm.monitoringWindow ?? 2) },
  37. set: { alarm.monitoringWindow = Int($0) }
  38. )
  39. )
  40. Section {
  41. Toggle("Only alert when below BG limit", isOn: $useLimit)
  42. .onAppear {
  43. useLimit = (alarm.threshold != nil)
  44. }
  45. .onChange(of: useLimit) { newValue in
  46. if !newValue { alarm.threshold = nil }
  47. }
  48. AlarmBGSection(
  49. header: nil,
  50. footer: "Ignored unless the toggle above is enabled.",
  51. title: "Dropping below",
  52. range: 40...300,
  53. value: Binding(
  54. get: { alarm.threshold ?? 70 },
  55. set: { alarm.threshold = $0 }
  56. )
  57. )
  58. .disabled(!useLimit)
  59. .opacity(useLimit ? 1 : 0.35)
  60. }
  61. AlarmAudioSection(alarm: $alarm)
  62. AlarmActiveSection(alarm: $alarm)
  63. AlarmSnoozeSection(
  64. alarm: $alarm,
  65. range: 5...60,
  66. step: 5
  67. )
  68. }
  69. .navigationTitle(alarm.type.rawValue)
  70. }
  71. }