AutotuneConfigRootView.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import SwiftUI
  2. import Swinject
  3. extension AutotuneConfig {
  4. struct RootView: BaseView {
  5. let resolver: Resolver
  6. @StateObject var state = StateModel()
  7. private var isfFormatter: NumberFormatter {
  8. let formatter = NumberFormatter()
  9. formatter.numberStyle = .decimal
  10. formatter.maximumFractionDigits = 2
  11. return formatter
  12. }
  13. private var rateFormatter: NumberFormatter {
  14. let formatter = NumberFormatter()
  15. formatter.numberStyle = .decimal
  16. formatter.maximumFractionDigits = 3
  17. return formatter
  18. }
  19. private var dateFormatter: DateFormatter {
  20. let formatter = DateFormatter()
  21. formatter.dateStyle = .medium
  22. formatter.timeStyle = .short
  23. return formatter
  24. }
  25. var body: some View {
  26. Form {
  27. Section {
  28. Toggle("Use Autotune", isOn: $state.useAutotune)
  29. }
  30. Section {
  31. HStack {
  32. Text("Last run")
  33. Spacer()
  34. Text(dateFormatter.string(from: state.publishedDate))
  35. }
  36. Button { state.run() }
  37. label: { Text("Run now") }
  38. }
  39. if let autotune = state.autotune {
  40. Section {
  41. HStack {
  42. Text("Carb ratio")
  43. Spacer()
  44. Text(isfFormatter.string(from: autotune.carbRatio as NSNumber) ?? "0")
  45. Text("g/U").foregroundColor(.secondary)
  46. }
  47. HStack {
  48. Text("Sensitivity")
  49. Spacer()
  50. if state.units == .mmolL {
  51. Text(isfFormatter.string(from: autotune.sensitivity.asMmolL as NSNumber) ?? "0")
  52. } else {
  53. Text(isfFormatter.string(from: autotune.sensitivity as NSNumber) ?? "0")
  54. }
  55. Text(state.units.rawValue + "/U").foregroundColor(.secondary)
  56. }
  57. }
  58. Section(header: Text("Basal profile")) {
  59. ForEach(0 ..< autotune.basalProfile.count, id: \.self) { index in
  60. HStack {
  61. VStack {
  62. HStack {
  63. Text(autotune.basalProfile[index].displayTime).foregroundColor(.secondary)
  64. Spacer()
  65. Text(rateFormatter.string(from: autotune.basalProfile[index].rate as NSNumber) ?? "0")
  66. Text("U/hr").foregroundColor(.secondary)
  67. }
  68. // To prevent a race condition if Autotune is ran an no profile
  69. // existed before.
  70. if state.basalProfile.indices.contains(index),
  71. let basalProfile = state.basalProfile[index]
  72. {
  73. HStack {
  74. Text("Pump")
  75. Text(basalProfile.displayTime)
  76. Spacer()
  77. Text(rateFormatter.string(from: basalProfile.rate as NSNumber) ?? "0")
  78. Text("U/hr").foregroundColor(.secondary)
  79. }.font(Font.system(size: 12))
  80. }
  81. }
  82. }
  83. }
  84. }
  85. Section {
  86. Button { state.delete() }
  87. label: { Text("Delete autotune data") }
  88. .foregroundColor(.red)
  89. }
  90. Section {
  91. Button { state.copyBasal() }
  92. label: { Text("Copy basal rates to pump") }
  93. .foregroundColor(.red)
  94. }
  95. }
  96. }
  97. .onAppear(perform: configureView)
  98. .navigationTitle("Autotune")
  99. .navigationBarTitleDisplayMode(.automatic)
  100. }
  101. }
  102. }