AutotuneConfigRootView.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import SwiftUI
  2. import Swinject
  3. extension AutotuneConfig {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @StateObject var state = StateModel()
  7. @State var replaceAlert = false
  8. @Environment(\.colorScheme) var colorScheme
  9. var color: LinearGradient {
  10. colorScheme == .dark ? LinearGradient(
  11. gradient: Gradient(colors: [
  12. Color("Background_1"),
  13. Color("Background_1"),
  14. Color("Background_2")
  15. // Color("Background_1")
  16. ]),
  17. startPoint: .top,
  18. endPoint: .bottom
  19. )
  20. :
  21. LinearGradient(
  22. gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
  23. startPoint: .top,
  24. endPoint: .bottom
  25. )
  26. }
  27. private var isfFormatter: NumberFormatter {
  28. let formatter = NumberFormatter()
  29. formatter.numberStyle = .decimal
  30. formatter.maximumFractionDigits = 2
  31. return formatter
  32. }
  33. private var rateFormatter: NumberFormatter {
  34. let formatter = NumberFormatter()
  35. formatter.numberStyle = .decimal
  36. formatter.maximumFractionDigits = 2
  37. return formatter
  38. }
  39. private var dateFormatter: DateFormatter {
  40. let formatter = DateFormatter()
  41. formatter.dateStyle = .medium
  42. formatter.timeStyle = .short
  43. return formatter
  44. }
  45. var body: some View {
  46. Form {
  47. Section {
  48. Toggle("Use Autotune", isOn: $state.useAutotune)
  49. if state.useAutotune {
  50. Toggle("Only Autotune Basal Insulin", isOn: $state.onlyAutotuneBasals)
  51. }
  52. }
  53. Section {
  54. HStack {
  55. Text("Last run")
  56. Spacer()
  57. Text(dateFormatter.string(from: state.publishedDate))
  58. }
  59. Button { state.run() }
  60. label: { Text("Run now") }
  61. }
  62. if let autotune = state.autotune {
  63. if !state.onlyAutotuneBasals {
  64. Section {
  65. HStack {
  66. Text("Carb ratio")
  67. Spacer()
  68. Text(isfFormatter.string(from: autotune.carbRatio as NSNumber) ?? "0")
  69. Text("g/U").foregroundColor(.secondary)
  70. }
  71. HStack {
  72. Text("Sensitivity")
  73. Spacer()
  74. if state.units == .mmolL {
  75. Text(isfFormatter.string(from: autotune.sensitivity.asMmolL as NSNumber) ?? "0")
  76. } else {
  77. Text(isfFormatter.string(from: autotune.sensitivity as NSNumber) ?? "0")
  78. }
  79. Text(state.units.rawValue + "/U").foregroundColor(.secondary)
  80. }
  81. }
  82. }
  83. Section(header: Text("Basal profile")) {
  84. ForEach(0 ..< autotune.basalProfile.count, id: \.self) { index in
  85. HStack {
  86. Text(autotune.basalProfile[index].start).foregroundColor(.secondary)
  87. Spacer()
  88. Text(rateFormatter.string(from: autotune.basalProfile[index].rate as NSNumber) ?? "0")
  89. Text("U/hr").foregroundColor(.secondary)
  90. }
  91. }
  92. HStack {
  93. Text("Total")
  94. .bold()
  95. .foregroundColor(.primary)
  96. Spacer()
  97. Text(rateFormatter.string(from: autotune.basalProfile.reduce(0) { $0 + $1.rate } as NSNumber) ?? "0")
  98. .foregroundColor(.primary) +
  99. Text(" U/day")
  100. .foregroundColor(.secondary)
  101. }
  102. }
  103. Section {
  104. Button { state.delete() }
  105. label: { Text("Delete autotune data") }
  106. .foregroundColor(.red)
  107. }
  108. Section {
  109. Button {
  110. replaceAlert = true
  111. }
  112. label: { Text("Save as your Normal Basal Rates") }
  113. } header: {
  114. Text("Save on Pump")
  115. }
  116. }
  117. }
  118. .scrollContentBackground(.hidden).background(color)
  119. .onAppear(perform: configureView)
  120. .navigationTitle("Autotune")
  121. .navigationBarTitleDisplayMode(.automatic)
  122. .alert(Text("Are you sure?"), isPresented: $replaceAlert) {
  123. Button("Yes", action: {
  124. state.replace()
  125. replaceAlert.toggle()
  126. })
  127. Button("No", action: { replaceAlert.toggle() })
  128. }
  129. }
  130. }
  131. }