Преглед изворни кода

Pin Send button to prevent keyboard toolbar overlap (#604)

* Pin Send button below Form to prevent keyboard toolbar overlap

Move the Send button out of the scrollable Form and pin it at the
bottom using .safeAreaInset(edge: .bottom) in all four remote command
views (TRC Bolus, TRC Meal, Loop APNS Bolus, Loop APNS Carbs).

The button is now always visible — above the keyboard when it's open,
at the bottom when it's closed. Also adds .scrollDismissesKeyboard to
allow interactive keyboard dismissal by scrolling.

Fixes #602

* Remove scrollDismissesKeyboard — keyboard has its own dismiss button
Jonas Björkert пре 3 месеци
родитељ
комит
4bf03dec47

+ 21 - 16
LoopFollow/Remote/LoopAPNS/LoopAPNSBolusView.swift

@@ -109,22 +109,6 @@ struct LoopAPNSBolusView: View {
                         }
                     }
 
-                    Section {
-                        Button(action: sendInsulin) {
-                            if isLoading {
-                                HStack {
-                                    ProgressView()
-                                        .scaleEffect(0.8)
-                                    Text("Sending...")
-                                }
-                            } else {
-                                Text("Send Insulin")
-                            }
-                        }
-                        .disabled(insulinAmount.doubleValue(for: .internationalUnit()) <= 0 || isLoading || isTOTPBlocked)
-                        .frame(maxWidth: .infinity)
-                    }
-
                     // TOTP Blocking Warning Section
                     if isTOTPBlocked && showTOTPWarning {
                         Section {
@@ -168,6 +152,27 @@ struct LoopAPNSBolusView: View {
                         }
                     }
                 }
+                .safeAreaInset(edge: .bottom) {
+                    Button(action: sendInsulin) {
+                        if isLoading {
+                            HStack {
+                                ProgressView()
+                                    .scaleEffect(0.8)
+                                Text("Sending...")
+                            }
+                            .frame(maxWidth: .infinity)
+                        } else {
+                            Text("Send Insulin")
+                                .frame(maxWidth: .infinity)
+                        }
+                    }
+                    .buttonStyle(.borderedProminent)
+                    .controlSize(.large)
+                    .disabled(insulinAmount.doubleValue(for: .internationalUnit()) <= 0 || isLoading || isTOTPBlocked)
+                    .padding(.horizontal)
+                    .padding(.vertical, 8)
+                    .background(.bar)
+                }
                 .navigationTitle("Insulin")
                 .navigationBarTitleDisplayMode(.inline)
             }

+ 21 - 16
LoopFollow/Remote/LoopAPNS/LoopAPNSCarbsView.swift

@@ -232,22 +232,6 @@ struct LoopAPNSCarbsView: View {
                             .buttonStyle(.plain)
                         }
                     }
-                    Section {
-                        Button(action: sendCarbs) {
-                            if isLoading {
-                                HStack {
-                                    ProgressView()
-                                        .scaleEffect(0.8)
-                                    Text("Sending...")
-                                }
-                            } else {
-                                Text("Send Carbs")
-                            }
-                        }
-                        .disabled(carbsAmount.doubleValue(for: .gram()) <= 0 || isLoading || isTOTPBlocked)
-                        .frame(maxWidth: .infinity)
-                    }
-
                     // TOTP Blocking Warning Section
                     if isTOTPBlocked && showTOTPWarning {
                         Section {
@@ -292,6 +276,27 @@ struct LoopAPNSCarbsView: View {
                         }
                     }
                 }
+                .safeAreaInset(edge: .bottom) {
+                    Button(action: sendCarbs) {
+                        if isLoading {
+                            HStack {
+                                ProgressView()
+                                    .scaleEffect(0.8)
+                                Text("Sending...")
+                            }
+                            .frame(maxWidth: .infinity)
+                        } else {
+                            Text("Send Carbs")
+                                .frame(maxWidth: .infinity)
+                        }
+                    }
+                    .buttonStyle(.borderedProminent)
+                    .controlSize(.large)
+                    .disabled(carbsAmount.doubleValue(for: .gram()) <= 0 || isLoading || isTOTPBlocked)
+                    .padding(.horizontal)
+                    .padding(.vertical, 8)
+                    .background(.bar)
+                }
                 .navigationTitle("Carbs")
                 .navigationBarTitleDisplayMode(.inline)
             }

+ 32 - 19
LoopFollow/Remote/TRC/BolusView.swift

@@ -81,26 +81,39 @@ struct BolusView: View {
                             }
                         )
                     }
-
-                    LoadingButtonView(
-                        buttonText: "Send Bolus",
-                        progressText: "Sending Bolus...",
-                        isLoading: isLoading,
-                        action: {
-                            bolusFieldIsFocused = false
-                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
-                                let rawValue = self.bolusAmount.doubleValue(for: .internationalUnit())
-                                let steppedAmount = roundedToStep(rawValue)
-
-                                if steppedAmount > 0 {
-                                    bolusAmount = HKQuantity(unit: .internationalUnit(), doubleValue: steppedAmount)
-                                    alertType = .confirmBolus
-                                    showAlert = true
-                                }
+                }
+                .safeAreaInset(edge: .bottom) {
+                    Button {
+                        bolusFieldIsFocused = false
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+                            let rawValue = self.bolusAmount.doubleValue(for: .internationalUnit())
+                            let steppedAmount = roundedToStep(rawValue)
+
+                            if steppedAmount > 0 {
+                                bolusAmount = HKQuantity(unit: .internationalUnit(), doubleValue: steppedAmount)
+                                alertType = .confirmBolus
+                                showAlert = true
                             }
-                        },
-                        isDisabled: isLoading
-                    )
+                        }
+                    } label: {
+                        if isLoading {
+                            HStack {
+                                ProgressView()
+                                    .scaleEffect(0.8)
+                                Text("Sending Bolus...")
+                            }
+                            .frame(maxWidth: .infinity)
+                        } else {
+                            Text("Send Bolus")
+                                .frame(maxWidth: .infinity)
+                        }
+                    }
+                    .buttonStyle(.borderedProminent)
+                    .controlSize(.large)
+                    .disabled(isLoading)
+                    .padding(.horizontal)
+                    .padding(.vertical, 8)
+                    .background(.bar)
                 }
                 .navigationTitle("Bolus")
                 .navigationBarTitleDisplayMode(.inline)

+ 36 - 23
LoopFollow/Remote/TRC/MealView.swift

@@ -140,31 +140,44 @@ struct MealView: View {
                             }
                         }
                     }
+                }
+                .safeAreaInset(edge: .bottom) {
+                    Button {
+                        carbsFieldIsFocused = false
+                        proteinFieldIsFocused = false
+                        fatFieldIsFocused = false
 
-                    LoadingButtonView(
-                        buttonText: "Send Meal",
-                        progressText: "Sending Meal Data...",
-                        isLoading: isLoading,
-                        action: {
-                            carbsFieldIsFocused = false
-                            proteinFieldIsFocused = false
-                            fatFieldIsFocused = false
-
-                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
-                                guard carbs.doubleValue(for: .gram()) != 0 ||
-                                    protein.doubleValue(for: .gram()) != 0 ||
-                                    fat.doubleValue(for: .gram()) != 0
-                                else {
-                                    return
-                                }
-                                if !showAlert {
-                                    alertType = .confirmMeal
-                                    showAlert = true
-                                }
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+                            guard carbs.doubleValue(for: .gram()) != 0 ||
+                                protein.doubleValue(for: .gram()) != 0 ||
+                                fat.doubleValue(for: .gram()) != 0
+                            else {
+                                return
                             }
-                        },
-                        isDisabled: isButtonDisabled
-                    )
+                            if !showAlert {
+                                alertType = .confirmMeal
+                                showAlert = true
+                            }
+                        }
+                    } label: {
+                        if isLoading {
+                            HStack {
+                                ProgressView()
+                                    .scaleEffect(0.8)
+                                Text("Sending Meal Data...")
+                            }
+                            .frame(maxWidth: .infinity)
+                        } else {
+                            Text("Send Meal")
+                                .frame(maxWidth: .infinity)
+                        }
+                    }
+                    .buttonStyle(.borderedProminent)
+                    .controlSize(.large)
+                    .disabled(isButtonDisabled)
+                    .padding(.horizontal)
+                    .padding(.vertical, 8)
+                    .background(.bar)
                 }
                 .navigationTitle("Meal")
                 .navigationBarTitleDisplayMode(.inline)