Stop Approx. distances beside routed values; add Best Value alert mode
Distances (the "Approx. 1.5 mi" report): - Refuse junk CoreLocation fixes (invalid accuracy, or a coarse >300 m fix within 3 km of the position already held; a coarse fix in another city is real travel and is still accepted). - Resolve ONE display basis per render through FuelStore.distanceDisplayOrigin, used by rows, radius filter, sorting, savings figures and the Live Activity, so a stray fix can no longer re-base the list outside the route cache's 600 m ring while the routed values sit unused in the cache. - Treat an incomplete route set as a state: retry it after 30 s rather than the full 10-minute throttle, and repair a stale incomplete flag once every in-radius station has a route (nothing left to route, flag stuck down). - Widget extension resolves the same origin for fetch, radius, ordering and labels, and keeps its own fix in fuelboard.widgetLocation instead of overwriting the app's GPS fix. Alerts: - Best Value as a distinct alert mode on the existing geofence/notification pipeline, with a persisted threshold; reverts to cheapest when the feature is unconfigured and is not selectable while disabled. Diagnostics (DEBUG, gated): FB_DIST_FOCUS now prints FB-DIST-ORIGIN (candidate, accuracy, anchor, offset, resolved branch, served origin), FB_FAKE_FIX feeds a synthetic fix through the real guard, FB_STALE_INCOMPLETE forces the stale-flag state, and the route-fill status is surfaced in Settings behind debug mode.
This commit is contained in:
@@ -54,6 +54,7 @@ struct SettingsView: View {
|
||||
var regionEventCount: Int = 0
|
||||
/// Debug fence state (monitor.debugFenceIdentifier) — armed vs cleared.
|
||||
var debugFenceIdentifier: String?
|
||||
var roadDistanceDebugStatus: RoadDistanceFillDebugStatus = .idle
|
||||
/// Arms a 100 m fence at the current location (monitor.registerDebugFenceAroundMe).
|
||||
var onDebugFence: () -> Void = {}
|
||||
/// Clears the armed fence (monitor.clearDebugFence).
|
||||
@@ -400,6 +401,36 @@ struct SettingsView: View {
|
||||
Text("Connection shows the source of the current prices (CSV mirror or API). Data updated is the latest price change reported by the GOV.UK server itself. Prices use the UK Fuel Finder dataset (Open Government Licence) and refresh up to twice a day.")
|
||||
}
|
||||
|
||||
Section {
|
||||
LabeledContent("Status", value: roadDistanceDebugStatus.summary)
|
||||
LabeledContent("Updated", value: roadDistanceDebugStatus.updatedAt.formatted(date: .omitted, time: .standard))
|
||||
if let lat = roadDistanceDebugStatus.originLat,
|
||||
let lng = roadDistanceDebugStatus.originLng {
|
||||
LabeledContent("Origin", value: String(format: "%.5f, %.5f", lat, lng))
|
||||
}
|
||||
LabeledContent("Pool", value: "\(roadDistanceDebugStatus.stationPoolCount)")
|
||||
LabeledContent("Candidates", value: "\(roadDistanceDebugStatus.candidateCount)")
|
||||
LabeledContent("Cached", value: "\(roadDistanceDebugStatus.cachedCount)")
|
||||
if roadDistanceDebugStatus.routedCount > 0 || roadDistanceDebugStatus.failedCount > 0 {
|
||||
LabeledContent("Routed", value: "\(roadDistanceDebugStatus.routedCount)")
|
||||
LabeledContent("Failed", value: "\(roadDistanceDebugStatus.failedCount)")
|
||||
}
|
||||
if let elapsed = roadDistanceDebugStatus.elapsedSeconds {
|
||||
LabeledContent("Elapsed", value: String(format: "%.1fs", elapsed))
|
||||
}
|
||||
if let moved = roadDistanceDebugStatus.movedMeters {
|
||||
LabeledContent("Moved", value: String(format: "%.0f m", moved))
|
||||
}
|
||||
if let remaining = roadDistanceDebugStatus.throttleSecondsRemaining {
|
||||
LabeledContent("Throttle", value: String(format: "%.0f s remaining", max(0, remaining)))
|
||||
}
|
||||
LabeledContent("Ready", value: roadDistanceDebugStatus.complete ? "yes" : "no")
|
||||
} header: {
|
||||
Text("Road distance fill")
|
||||
} footer: {
|
||||
Text("Shows whether Accurate distances is running or gated. Distances stay Approx. until Ready is yes for the current origin; gated reasons explain why no fill is happening.")
|
||||
}
|
||||
|
||||
Section {
|
||||
if monitoredCount == 0 {
|
||||
Text("No stations monitored yet — open the Stations tab to load prices first.")
|
||||
|
||||
Reference in New Issue
Block a user