| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- import SwiftUI
- import Swinject
- extension BasalProfileEditor {
- struct RootView: BaseView {
- let resolver: Resolver
- @StateObject var state = StateModel()
- @State private var editMode = EditMode.inactive
- @Environment(\.colorScheme) var colorScheme
- var color: LinearGradient {
- colorScheme == .dark ? LinearGradient(
- gradient: Gradient(colors: [
- Color("Background_1"),
- Color("Background_1"),
- Color("Background_2")
- // Color("Background_1")
- ]),
- startPoint: .top,
- endPoint: .bottom
- )
- :
- LinearGradient(
- gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
- startPoint: .top,
- endPoint: .bottom
- )
- }
- private var dateFormatter: DateFormatter {
- let formatter = DateFormatter()
- formatter.timeZone = TimeZone(secondsFromGMT: 0)
- formatter.timeStyle = .short
- return formatter
- }
- private var rateFormatter: NumberFormatter {
- let formatter = NumberFormatter()
- formatter.numberStyle = .decimal
- return formatter
- }
- var body: some View {
- Form {
- Section(header: Text("Schedule")) {
- list
- addButton
- }
- Section {
- HStack {
- Text("Total")
- .bold()
- .foregroundColor(.primary)
- Spacer()
- Text(rateFormatter.string(from: state.total as NSNumber) ?? "0")
- .foregroundColor(.primary) +
- Text(" U/day")
- .foregroundColor(.secondary)
- }
- }
- Section {
- HStack {
- if state.syncInProgress {
- ProgressView().padding(.trailing, 10)
- }
- Button { state.save() }
- label: {
- Text(state.syncInProgress ? "Saving..." : "Save on Pump")
- }
- .disabled(state.syncInProgress || state.items.isEmpty)
- }
- }
- }
- .scrollContentBackground(.hidden).background(color)
- .onAppear(perform: configureView)
- .navigationTitle("Basal Profile")
- .navigationBarTitleDisplayMode(.automatic)
- .navigationBarItems(
- trailing: EditButton()
- )
- .environment(\.editMode, $editMode)
- .onAppear {
- state.validate()
- }
- }
- private func pickers(for index: Int) -> some View {
- GeometryReader { geometry in
- VStack {
- HStack {
- Text("Rate").frame(width: geometry.size.width / 2)
- Text("Time").frame(width: geometry.size.width / 2)
- }
- HStack(spacing: 0) {
- Picker(selection: $state.items[index].rateIndex, label: EmptyView()) {
- ForEach(0 ..< state.rateValues.count, id: \.self) { i in
- Text(
- (
- self.rateFormatter
- .string(from: state.rateValues[i] as NSNumber) ?? ""
- ) + " U/hr"
- ).tag(i)
- }
- }
- .onChange(of: state.items[index].rateIndex, perform: { _ in state.calcTotal() })
- .frame(maxWidth: geometry.size.width / 2)
- .clipped()
- Picker(selection: $state.items[index].timeIndex, label: EmptyView()) {
- ForEach(0 ..< state.timeValues.count, id: \.self) { i in
- Text(
- self.dateFormatter
- .string(from: Date(
- timeIntervalSince1970: state
- .timeValues[i]
- ))
- ).tag(i)
- }
- }
- .onChange(of: state.items[index].timeIndex, perform: { _ in state.calcTotal() })
- .frame(maxWidth: geometry.size.width / 2)
- .clipped()
- }
- }
- }
- }
- private var list: some View {
- List {
- ForEach(state.items.indexed(), id: \.1.id) { index, item in
- NavigationLink(destination: pickers(for: index)) {
- HStack {
- Text("Rate").foregroundColor(.secondary)
- Text(
- "\(rateFormatter.string(from: state.rateValues[item.rateIndex] as NSNumber) ?? "0") U/hr"
- )
- Spacer()
- Text("starts at").foregroundColor(.secondary)
- Text(
- "\(dateFormatter.string(from: Date(timeIntervalSince1970: state.timeValues[item.timeIndex])))"
- )
- }
- }
- .moveDisabled(true)
- }
- .onDelete(perform: onDelete)
- }
- }
- private var addButton: some View {
- guard state.canAdd else {
- return AnyView(EmptyView())
- }
- switch editMode {
- case .inactive:
- return AnyView(Button(action: onAdd) { Text("Add") })
- default:
- return AnyView(EmptyView())
- }
- }
- func onAdd() {
- state.add()
- }
- private func onDelete(offsets: IndexSet) {
- state.items.remove(atOffsets: offsets)
- state.validate()
- state.calcTotal()
- }
- }
- }
|