PreferencesEditorRootView.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import SwiftUI
  2. import Swinject
  3. struct InfoText: Identifiable {
  4. var id: String { description }
  5. let description: String
  6. let oref0Variable: String
  7. }
  8. extension PreferencesEditor {
  9. struct RootView: BaseView {
  10. let resolver: Resolver
  11. @StateObject var state = StateModel()
  12. private var formatter: NumberFormatter {
  13. let formatter = NumberFormatter()
  14. formatter.numberStyle = .decimal
  15. return formatter
  16. }
  17. @State private var infoButtonPressed: InfoText?
  18. var body: some View {
  19. Form {
  20. Section(header: Text("iAPS").textCase(nil)) {
  21. Picker("Glucose units", selection: $state.unitsIndex) {
  22. Text("mg/dL").tag(0)
  23. Text("mmol/L").tag(1)
  24. }
  25. Toggle("Remote control", isOn: $state.allowAnnouncements)
  26. HStack {
  27. Text("Recommended Bolus Percentage")
  28. DecimalTextField("", value: $state.insulinReqPercentage, formatter: formatter)
  29. }
  30. Toggle("Skip Bolus screen after carbs", isOn: $state.skipBolusScreenAfterCarbs)
  31. Toggle("Allow Upload of Statistics to NS", isOn: $state.displayStatistics)
  32. }
  33. ForEach(state.sections.indexed(), id: \.1.id) { sectionIndex, section in
  34. Section(header: Text(section.displayName)) {
  35. ForEach(section.fields.indexed(), id: \.1.id) { fieldIndex, field in
  36. HStack {
  37. switch field.type {
  38. case .boolean:
  39. ZStack {
  40. Button("", action: {
  41. infoButtonPressed = InfoText(
  42. description: field.infoText,
  43. oref0Variable: field.displayName
  44. )
  45. })
  46. Toggle(isOn: self.$state.sections[sectionIndex].fields[fieldIndex].boolValue) {
  47. Text(field.displayName)
  48. }
  49. }
  50. case .decimal:
  51. ZStack {
  52. Button("", action: {
  53. infoButtonPressed = InfoText(
  54. description: field.infoText,
  55. oref0Variable: field.displayName
  56. )
  57. })
  58. Text(field.displayName)
  59. }
  60. DecimalTextField(
  61. "0",
  62. value: self.$state.sections[sectionIndex].fields[fieldIndex].decimalValue,
  63. formatter: formatter
  64. )
  65. case .insulinCurve:
  66. Picker(
  67. selection: $state.sections[sectionIndex].fields[fieldIndex].insulinCurveValue,
  68. label: Text(field.displayName)
  69. ) {
  70. ForEach(InsulinCurve.allCases) { v in
  71. Text(v.rawValue).tag(v)
  72. }
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. }
  80. .onAppear(perform: configureView)
  81. .navigationTitle("Preferences")
  82. .navigationBarTitleDisplayMode(.automatic)
  83. .navigationBarItems(
  84. trailing:
  85. Button {
  86. let lang = Locale.current.languageCode ?? "en"
  87. if lang == "en" {
  88. UIApplication.shared.open(
  89. URL(
  90. string: "https://openaps.readthedocs.io/en/latest/docs/While%20You%20Wait%20For%20Gear/preferences-and-safety-settings.html"
  91. )!,
  92. options: [:],
  93. completionHandler: nil
  94. )
  95. } else {
  96. UIApplication.shared.open(
  97. URL(
  98. string: "https://openaps-readthedocs-io.translate.goog/en/latest/docs/While%20You%20Wait%20For%20Gear/preferences-and-safety-settings.html?_x_tr_sl=en&_x_tr_tl=\(lang)&_x_tr_hl=\(lang)"
  99. )!,
  100. options: [:],
  101. completionHandler: nil
  102. )
  103. }
  104. }
  105. label: { Image(systemName: "questionmark.circle") }
  106. )
  107. .alert(item: $infoButtonPressed) { infoButton in
  108. Alert(
  109. title: Text("\(infoButton.oref0Variable)"),
  110. message: Text("\(infoButton.description)"),
  111. dismissButton: .default(Text("OK"))
  112. )
  113. }
  114. }
  115. }
  116. }