Fix widget distance menu + geofence notification chain

Widget distance menu: the Distance picker only makes sense for
Cheapest ordering. It was hidden for Favourites but Closest still
showed it (regressed when the per-widget Distance picker was added).
parameterSummary now nests When clauses: Distance visible for
Cheapest only; Closest and Favourites hide it.

Notifications: three compounding defects kept real geofence alerts
from ever firing while the app was suspended:

1. Always permission was never properly requested. requestPermissions
   fired WhenInUse and Always back-to-back; iOS ignores the second
   call while the first prompt is pending, leaving the app stuck on
   WhenInUse — and region entries are never delivered in the
   background. Added locationManagerDidChangeAuthorization to
   ProximityMonitor: escalate WhenInUse -> Always, and re-register
   geofences on grant (regions registered under WhenInUse-only won't
   deliver in the background).

2. The 18-region window was frozen in the background. Re-registration
   lived in SwiftUI .onChange(of: locationManager.current), which
   never runs while suspended. Added a delegate hook
   (LocationManager.onLocationUpdate) fired from didUpdateLocations on
   every fix including background significant-change wake-ups; the app
   wires it to re-register geofences around the new position.

3. Region-registration failures were invisible. monitoringDidFailFor
   was never implemented, so a failed startMonitoring (region budget,
   auth, radius) silently stopped alerts. Now surfaced as
   monitor.lastRegionError and shown in Settings -> Debug; cleared on
   the next successful registration.
This commit is contained in:
FuelBoard Contributor
2026-08-12 18:18:24 +01:00
parent f822bd2636
commit 1dcd47c6cd
4 changed files with 93 additions and 11 deletions
+16 -8
View File
@@ -70,20 +70,28 @@ struct FuelBoardWidgetConfigurationIntent: WidgetConfigurationIntent {
@Parameter(title: "Distance", default: .five)
var distance: WidgetDistance
/// Edit-Widget UI: Favourites ranks pinned stations cheapest-first and is
/// not radius-bound, so the Distance picker is hidden in that mode.
/// Edit-Widget UI: the Distance picker only makes sense for Cheapest
/// ordering Closest is inherently "nearest within range" and Favourites
/// is not radius-bound. Show it for Cheapest only; hide for both others.
static var parameterSummary: some ParameterSummary {
When(\.$sort, .equalTo, WidgetSort.favourites) {
Summary("Show \(\.$fuel) favourites") {
\.$fuel
\.$sort
}
} otherwise: {
When(\.$sort, .equalTo, WidgetSort.cheapest) {
Summary("Show \(\.$fuel) by \(\.$sort) within \(\.$distance)") {
\.$fuel
\.$sort
\.$distance
}
} otherwise: {
When(\.$sort, .equalTo, WidgetSort.favourites) {
Summary("Show \(\.$fuel) favourites") {
\.$fuel
\.$sort
}
} otherwise: {
Summary("Show \(\.$fuel) by \(\.$sort)") {
\.$fuel
\.$sort
}
}
}
}
}