Alerts choose their own fuel, independent of the Stations tab

The proximity monitor was tied to the Stations-tab fuel selection, so
switching the list to another fuel silently re-targeted geofences. Now the
Alerts tab has its own 'Fuel to monitor' picker (persisted as
fuelboard.alertsFuel):
- Monitor reads loadAlertsFuel() on init/background relaunch
- Changing the alerts fuel re-registers geofences around stations selling
  that fuel only
- Favourites priority slots stay scoped to the monitored fuel
- Tests: alerts fuel round-trip + default (33/33 passing)
This commit is contained in:
FuelBoard Contributor
2026-08-12 08:51:31 +01:00
parent 35e0adaf0b
commit 46d5d45c93
5 changed files with 67 additions and 11 deletions
+16 -7
View File
@@ -13,6 +13,7 @@ struct ContentView: View {
@State private var favourites: [FavouriteEntry] = FuelStore.loadFavourites()
@State private var alertsEnabled: Bool = FuelStore.loadAlertsEnabled()
@State private var alertsRadius: Double = FuelStore.loadAlertsRadius()
@State private var alertsFuel: FuelType = FuelStore.loadAlertsFuel()
@State private var location: Coordinate? = {
if let loc = FuelStore.loadLocation() { return Coordinate(lat: loc.lat, lng: loc.lng) }
return nil
@@ -136,6 +137,7 @@ struct ContentView: View {
AlertsView(
enabled: $alertsEnabled,
radius: $alertsRadius,
fuel: $alertsFuel,
distanceUnit: distanceUnit,
monitoredCount: monitor.monitoredStationIDs.count,
lastAlert: monitor.lastAlert
@@ -162,7 +164,7 @@ struct ContentView: View {
showOnboarding = true
}
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
monitor.setEnabled(alertsEnabled)
// Refresh only when the cache is stale (twice-a-day policy).
Task { await refresh() }
@@ -178,7 +180,7 @@ struct ContentView: View {
if newPhase == .active {
locationManager.startForegroundTracking()
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
// No network fetch on foreground pull-to-refresh is the override.
} else {
locationManager.stopForegroundTracking()
@@ -192,7 +194,7 @@ struct ContentView: View {
// Geofences follow the user's position, but the station list is
// NOT re-fetched on every movement (cached, twice-a-day policy).
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
}
}
.onChange(of: selectedFuel) { _, _ in
@@ -211,7 +213,7 @@ struct ContentView: View {
FuelStore.saveAlertsEnabled(newValue)
monitor.setEnabled(newValue)
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
if newValue {
locationManager.startBackgroundTracking()
}
@@ -219,7 +221,14 @@ struct ContentView: View {
.onChange(of: alertsRadius) { _, newValue in
FuelStore.saveAlertsRadius(newValue)
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
}
.onChange(of: alertsFuel) { _, newValue in
// Alerts fuel is independent of the Stations-tab selection
// changing it re-targets geofences to stations selling that fuel.
FuelStore.saveAlertsFuel(newValue)
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: newValue, radiusKM: alertsRadius)
}
}
@@ -233,7 +242,7 @@ struct ContentView: View {
FuelStore.saveFavourites(favourites)
WidgetCenter.shared.reloadAllTimelines()
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
}
/// Fetches fresh prices, but only when the cache is stale unless
@@ -261,7 +270,7 @@ struct ContentView: View {
}
// Keep monitor geofences in sync with the freshest data.
monitor.update(stations: stations, favourites: refreshedFavourites,
fuel: selectedFuel, radiusKM: alertsRadius)
fuel: alertsFuel, radiusKM: alertsRadius)
}
}