Ver código fonte

Redesign carbs and bolus input (pickers, UI) WIP

Deniz Cengiz 1 ano atrás
pai
commit
ff2509bf53

+ 88 - 21
Trio Watch App Extension/Views/BolusInputView.swift

@@ -9,8 +9,11 @@ struct BolusInputView: View {
     @State private var bolusAmount = 0.0
     @State private var showingConfirmation = false
     @State private var confirmationProgress = 0.0
+
     let state: WatchState
 
+    @FocusState private var isCrownFocused: Bool
+
     var body: some View {
         if showingConfirmation {
             BolusConfirmationView(
@@ -27,7 +30,7 @@ struct BolusInputView: View {
                         if state.carbsAmount > 0 {
                             state.carbsAmount = 0 // reset carbs in state
                         }
-                        dismiss()
+                        showingConfirmation.toggle()
                     } label: {
                         Image(systemName: "xmark")
                     }
@@ -37,6 +40,7 @@ struct BolusInputView: View {
 
                 ToolbarItem(placement: .topBarTrailing) {
                     Image(systemName: "digitalcrown.arrow.counterclockwise.fill")
+                        .symbolRenderingMode(.hierarchical)
                         .foregroundStyle(Color.white)
                 }
             }
@@ -44,26 +48,85 @@ struct BolusInputView: View {
             VStack {
                 if state.carbsAmount > 0 {
                     HStack {
-                        Text("Carbs: \(state.carbsAmount) g").font(.subheadline).padding(.bottom)
+                        Text("Carbs:").bold().font(.subheadline).padding(.leading)
+                        Text(String(format: "%.0f g", state.carbsAmount)).font(.subheadline).foregroundStyle(Color.orange)
                         Spacer()
                     }
                 }
 
-                // TODO: handle bolus recommendation
-                Picker("Bolus", selection: $bolusAmount) {
-                    ForEach(0 ... 100, id: \.self) { number in
-                        Text(String(format: "%.1f U", Double(number) / 10))
-                            .tag(Double(number) / 10)
+                Spacer()
+
+                HStack {
+                    // "-" Button
+                    Button(action: {
+                        if bolusAmount > 0 { bolusAmount -= 1 }
+                    }) {
+                        Image(systemName: "minus.circle.fill")
+                            .font(.title3)
+                            .foregroundColor(.blue)
                     }
-                }
+                    .buttonStyle(.borderless)
+                    .disabled(bolusAmount < 1)
+
+                    Spacer()
+
+                    // Display the current carb amount
+                    Text(String(format: "%.2f U", bolusAmount))
+                        .fontWeight(.bold)
+                        .font(.system(.title2, design: .rounded))
+                        .foregroundColor(.primary)
+                        .focusable(true)
+                        .focused($isCrownFocused)
+                        .digitalCrownRotation(
+                            $bolusAmount,
+                            from: 0,
+                            through: 150.0, // TODO: use maxBolus here
+                            by: 1, // TODO: use pump increment here
+                            sensitivity: .medium,
+                            isContinuous: false,
+                            isHapticFeedbackEnabled: true
+                        )
+
+                    Spacer()
+
+                    // TODO: introduce maxBolus here, disable button if bolusAmount > maxBolus
+                    // "+" Button
+                    Button(action: {
+                        bolusAmount += 1
+                    }) {
+                        Image(systemName: "plus.circle.fill")
+                            .font(.title3)
+                            .foregroundColor(.blue)
+                    }
+                    .buttonStyle(.borderless)
+                }.padding(.horizontal)
 
-                Button("Add Bolus") {
+                Text("Insulin")
+                    .font(.subheadline)
+                    .foregroundColor(.secondary)
+                    .padding(.bottom)
+
+                Spacer()
+
+                Button("Log Bolus") {
                     showingConfirmation = true
                 }
                 .buttonStyle(.bordered)
                 .tint(.blue)
+                .disabled(!(bolusAmount > 0.0))
+            }
+            .toolbar {
+                ToolbarItem(placement: .topBarTrailing) {
+                    Image(systemName: "syringe.fill")
+                        .resizable()
+                        .aspectRatio(contentMode: .fit)
+                        .frame(width: 14, height: 14)
+                        .padding()
+                        .background(Color.blue)
+                        .foregroundStyle(.white)
+                        .clipShape(Circle())
+                }
             }
-            .navigationTitle("Add Insulin")
         }
     }
 }
@@ -79,22 +142,26 @@ struct BolusConfirmationView: View {
     var body: some View {
         VStack(spacing: 10) {
             if state.carbsAmount > 0 {
-                Text(String(format: "%.1f g", state.carbsAmount))
-                    .bold()
-                    .foregroundStyle(.orange)
+                HStack {
+                    Text("Carbs:")
+                    Spacer()
+                    Text(String(format: "%.1f g", state.carbsAmount))
+                        .bold()
+                        .foregroundStyle(.orange)
+                }.padding(.horizontal)
             }
 
-            Text(String(format: "%.1f U", bolusAmount))
-                .bold()
-                .foregroundStyle(.blue)
+            HStack {
+                Text("Bolus")
+                Spacer()
+                Text(String(format: "%.1f U", bolusAmount))
+                    .bold()
+                    .foregroundStyle(.blue)
+            }.padding(.horizontal)
 
             ProgressView(value: progress, total: 1.0)
-                .tint(progress >= 1.0 ? .green : .blue)
+                .tint(progress >= 1.0 ? .green : .gray)
                 .padding(.horizontal)
-
-            Text("\(Int(progress * 100))%")
-                .font(.caption2)
-                .foregroundStyle(.secondary)
         }
         .focusable(true)
         .focused($isCrownFocused)

+ 69 - 14
Trio Watch App Extension/Views/CarbsInputView.swift

@@ -5,7 +5,7 @@ import SwiftUI
 
 struct CarbsInputView: View {
     @Environment(\.dismiss) var dismiss
-    @State private var carbsAmount = 0
+    @State private var carbsAmount: Double = 0.0 // Needs to be Double due to .digitalCrownRotation() stride
     @State private var navigateToBolus = false // Track navigation to BolusInputView
     @FocusState private var isCrownFocused: Bool // Manage crown focus
 
@@ -13,34 +13,89 @@ struct CarbsInputView: View {
     let continueToBolus: Bool
 
     var body: some View {
-        let buttonLabel = continueToBolus ? "Proceed" : "Add Carbs"
+        let buttonLabel = continueToBolus ? "Proceed" : "Log Carbs"
 
         // TODO: introduce meal setting fpu enablement to conditional handle FPU
         VStack {
-            Picker("Carbs", selection: $carbsAmount) {
-                ForEach(0 ... 100, id: \.self) { amount in
-                    Text("\(amount) g").tag(amount)
+            Spacer()
+
+            HStack {
+                // "-" Button
+                Button(action: {
+                    if carbsAmount > 0 { carbsAmount -= 1 }
+                }) {
+                    Image(systemName: "minus.circle.fill")
+                        .font(.title3)
+                        .foregroundColor(.orange)
                 }
-            }
-            .focusable(true) // Enable focus for Digital Crown
-            .focused($isCrownFocused) // Bind focus state
-            .onAppear {
-                isCrownFocused = true // Automatically focus when view appears
-            }
+                .buttonStyle(.borderless)
+                .disabled(carbsAmount < 1)
+
+                Spacer()
+
+                // Display the current carb amount
+                Text(String(format: "%.0f g", carbsAmount))
+                    .fontWeight(.bold)
+                    .font(.system(.title2, design: .rounded))
+                    .foregroundColor(.primary)
+                    .focusable(true)
+                    .focused($isCrownFocused)
+                    .digitalCrownRotation(
+                        $carbsAmount,
+                        from: 0,
+                        through: 150.0, // TODO: introduce maxCarbs here
+                        by: 1,
+                        sensitivity: .medium,
+                        isContinuous: false,
+                        isHapticFeedbackEnabled: true
+                    )
+
+                Spacer()
+
+                // TODO: introduce maxCarbs here, disable button if carbsAmount > maxCarbs
+                // "+" Button
+                Button(action: {
+                    carbsAmount += 1
+                }) {
+                    Image(systemName: "plus.circle.fill")
+                        .font(.title3)
+                        .foregroundColor(.orange)
+                }
+                .buttonStyle(.borderless)
+            }.padding(.horizontal)
+
+            Text("Carbohydrates")
+                .font(.subheadline)
+                .foregroundColor(.secondary)
+                .padding(.bottom)
+
+            Spacer()
 
             Button(buttonLabel) {
                 if continueToBolus {
-                    state.carbsAmount = carbsAmount
+                    state.carbsAmount = Int(carbsAmount)
                     navigateToBolus = true
                 } else {
-                    state.sendCarbsRequest(carbsAmount)
+                    state.sendCarbsRequest(Int(carbsAmount))
                     dismiss()
                 }
             }
             .buttonStyle(.bordered)
             .tint(.orange)
+            .disabled(!(carbsAmount > 0.0))
+        }
+        .toolbar {
+            ToolbarItem(placement: .topBarTrailing) {
+                Image(systemName: "fork.knife")
+                    .resizable()
+                    .aspectRatio(contentMode: .fit)
+                    .frame(width: 14, height: 14)
+                    .padding()
+                    .background(Color.orange)
+                    .foregroundStyle(.white)
+                    .clipShape(Circle())
+            }
         }
-        .navigationTitle("Add Carbs")
         .navigationDestination(isPresented: $navigateToBolus) {
             BolusInputView(state: state) // Navigate to BolusInputView
         }

+ 24 - 21
Trio Watch App Extension/Views/TreatmentMenuView.swift

@@ -1,43 +1,46 @@
 import SwiftUI
 
 struct TreatmentMenuView: View {
-    @Environment(\.presentationMode) var presentationMode
+    @Environment(\.dismiss) var dismiss
     @Binding var selectedTreatment: TreatmentOption?
 
     let treatments = TreatmentOption.allCases
 
+    private var is40mm: Bool {
+        let size = WKInterfaceDevice.current().screenBounds.size
+        return size.height < 225 && size.width < 185
+    }
+
+    private var iconSize: CGFloat {
+        is40mm ? 18 : 22
+    }
+
     var body: some View {
         NavigationView {
             List {
                 ForEach(treatments) { treatment in
                     Button(action: {
                         selectedTreatment = treatment
-                        presentationMode.wrappedValue.dismiss() // Close after selecting
+                        dismiss() // Close after selecting
                     }) {
-                        HStack(alignment: .center) {
+                        HStack(spacing: 10) {
                             switch treatment {
-                            case .mealBolusCombo:
-                                mealIcon
-
-                                // Plus Icon
-                                Image(systemName: "plus")
-                                    .font(.caption)
-                                    .bold()
-                                    .frame(width: 24, height: 24)
-
-                                bolusIcon
                             case .meal:
                                 mealIcon
-
+                                Text(treatment.displayName)
                             case .bolus:
                                 bolusIcon
+                                Text(treatment.displayName)
+                            case .mealBolusCombo:
+                                mealIcon
+                                bolusIcon
                             }
                         }
                         .foregroundColor(.white)
                         .frame(maxWidth: .infinity)
                     }
                     .buttonStyle(PressableIconButtonStyle())
-                }.listRowBackground(Color.clear)
+                }
             }.navigationTitle("Pick Treatment")
         }
     }
@@ -46,8 +49,8 @@ struct TreatmentMenuView: View {
         Image(systemName: "fork.knife")
             .resizable()
             .aspectRatio(contentMode: .fit)
-            .frame(width: 22, height: 22) // Icon size
-            .padding(10)
+            .frame(width: iconSize, height: iconSize)
+            .padding(is40mm ? 6 : 10)
             .background(Color.orange)
             .clipShape(Circle())
     }
@@ -56,8 +59,8 @@ struct TreatmentMenuView: View {
         Image(systemName: "syringe.fill")
             .resizable()
             .aspectRatio(contentMode: .fit)
-            .frame(width: 22, height: 22) // Icon size
-            .padding(10)
+            .frame(width: iconSize, height: iconSize)
+            .padding(is40mm ? 6 : 10)
             .background(Color.blue)
             .clipShape(Circle())
     }
@@ -83,7 +86,7 @@ struct PressableIconButtonStyle: ButtonStyle {
     func makeBody(configuration: Configuration) -> some View {
         configuration.label
             .background(Color.clear)
-            .opacity(configuration.isPressed ? 0.5 : 1.0) // Change opacity when pressed
-            .animation(.easeInOut(duration: 0.2), value: configuration.isPressed) // Smooth transition
+            .opacity(configuration.isPressed ? 0.3 : 1.0) // Change opacity when pressed
+            .animation(.easeInOut(duration: 0.25), value: configuration.isPressed) // Smooth transition
     }
 }

+ 4 - 4
Trio.xcodeproj/project.pbxproj

@@ -2472,13 +2472,13 @@
 		BDA25F1A2D26BCE800035F34 /* Views */ = {
 			isa = PBXGroup;
 			children = (
-				DD246F052D2836AA0027DDE0 /* GlucoseTrendView.swift */,
-				BD54A9702D281A7A00F9C1EE /* TempTargetPresetsView.swift */,
-				DD6F63CB2D27F606007D94CF /* TreatmentMenuView.swift */,
-				BD54A9582D27FB6A00F9C1EE /* OverridePresetsView.swift */,
 				BDA25F212D26D62200035F34 /* BolusInputView.swift */,
 				BDA25F1F2D26D5FB00035F34 /* CarbsInputView.swift */,
 				BDA25F1D2D26D5D800035F34 /* GlucoseChartView.swift */,
+				DD246F052D2836AA0027DDE0 /* GlucoseTrendView.swift */,
+				BD54A9582D27FB6A00F9C1EE /* OverridePresetsView.swift */,
+				BD54A9702D281A7A00F9C1EE /* TempTargetPresetsView.swift */,
+				DD6F63CB2D27F606007D94CF /* TreatmentMenuView.swift */,
 				BDA25F1B2D26BD0300035F34 /* TrendShape.swift */,
 				BDFF7A842D25F97D0016C40C /* TrioMainWatchView.swift */,
 			);