Cache-first refresh policy: auto-fetch at most twice a day (12h gate), no fetch on launch/foreground/location/fuel-switch, pull-to-refresh forces; geofences still follow location
This commit is contained in:
@@ -87,7 +87,8 @@ struct ContentView: View {
|
||||
location: location,
|
||||
radiusKM: alertsRadius,
|
||||
favouriteIDs: favouriteIDs,
|
||||
onToggleFavourite: toggleFavourite
|
||||
onToggleFavourite: toggleFavourite,
|
||||
onRefresh: { await refresh(force: true) }
|
||||
)
|
||||
.tabItem { Label("Stations", systemImage: "fuelpump.fill") }
|
||||
|
||||
@@ -113,6 +114,7 @@ struct ContentView: View {
|
||||
monitor.update(stations: stations, favourites: refreshedFavourites,
|
||||
fuel: selectedFuel, radiusKM: alertsRadius)
|
||||
monitor.setEnabled(alertsEnabled)
|
||||
// Refresh only when the cache is stale (twice-a-day policy).
|
||||
Task { await refresh() }
|
||||
}
|
||||
.onChange(of: scenePhase) { _, newPhase in
|
||||
@@ -120,7 +122,7 @@ struct ContentView: View {
|
||||
locationManager.startForegroundTracking()
|
||||
monitor.update(stations: stations, favourites: refreshedFavourites,
|
||||
fuel: selectedFuel, radiusKM: alertsRadius)
|
||||
Task { await refresh() }
|
||||
// No network fetch on foreground — pull-to-refresh is the override.
|
||||
} else {
|
||||
locationManager.stopForegroundTracking()
|
||||
}
|
||||
@@ -130,13 +132,15 @@ struct ContentView: View {
|
||||
location = newLocation
|
||||
FuelStore.saveLocation(lat: newLocation.lat, lng: newLocation.lng)
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
Task { await refresh() }
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
.onChange(of: selectedFuel) { _, _ in
|
||||
// Re-fetch so the station set matches the selected fuel (relay
|
||||
// filters by grade); all prices still come back in one response.
|
||||
Task { await refresh() }
|
||||
// No re-fetch needed — one response carries E5/E10/DIESEL prices.
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
}
|
||||
.onChange(of: alertsEnabled) { _, newValue in
|
||||
FuelStore.saveAlertsEnabled(newValue)
|
||||
@@ -166,13 +170,19 @@ struct ContentView: View {
|
||||
fuel: selectedFuel, radiusKM: alertsRadius)
|
||||
}
|
||||
|
||||
private func refresh() async {
|
||||
/// Fetches fresh prices, but only when the cache is stale — unless
|
||||
/// `force` is true (pull-to-refresh is the manual override).
|
||||
private func refresh(force: Bool = false) async {
|
||||
if !force, FuelStore.isCacheFresh {
|
||||
return // data already fresh — skip network entirely
|
||||
}
|
||||
isLoading = true
|
||||
defer { isLoading = false }
|
||||
do {
|
||||
let fetched = try await FuelPriceProvider.active.fetchStations(near: location?.lat, lng: location?.lng, fuel: selectedFuel)
|
||||
stations = fetched
|
||||
FuelStore.saveStations(fetched)
|
||||
FuelStore.saveLastRefresh()
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
statusMessage = "Loaded \(fetched.count) stations · \(Date().formatted(date: .omitted, time: .shortened))"
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user