Consumer chain: GitHub-only — relay removed from app+widget, Local Network permission gone
The LAN relay is unreachable from any phone outside the developer's LAN, so for App Store users a relay fallback was dead weight AND harmful: attempting the private IP fires the iOS Local Network prompt on a stranger's phone and adds a timeout before the bundled dump. GitHub raw is reachable anywhere the relay would be, and more reliably. - LiveChainProvider: GitHub mirror first EVERYWHERE (focused alert path no longer relay-first); LAN relay only joins behind the hidden dev flag fuelboard.relayFallback (Settings → Debug, keychain-first, off by default) - MirrorFuelProvider: focused() projection replaces the relay's server-side radius endpoint (fuel filter + within-radius + nearest-first + limit 500) — the alert path re-checks radius/fuel itself, so behaviour is identical - Widget: fetchFocused/fetchFuelOnly now GitHub-first via the chain (day-cache shared through the app group); relay + widget-diag GET gated on the same dev flag — off-LAN widgets no longer attempt local network at all - FuelBeacon: fires only when the dev flag is on — consumers make zero local-network attempts; /stats app-hit spike = GitHub down + dev flag on - Onboarding: Local Network machinery removed entirely (no probe, no prompt, no 12 s stall) — data page is now informational: prices download from the internet, no permissions needed. Replay on cellular can no longer hang. - Info.plist: NSLocalNetworkUsageDescription copy → optional dev-only wording - 95 tests (6 new: relay-skip-when-disabled x2, focused prefer-mirror, mirror focused projection x3, beacon dev-flag gate)
This commit is contained in:
@@ -151,6 +151,10 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
"station":"\(first?.name ?? "")","price":\(first?.prices[entry.fuel] ?? -1)}
|
||||
"""
|
||||
FuelStore.saveWidgetDiag(json, intentType: intentType)
|
||||
// The relay GET is dev-only (same flag as the app beacon): consumers
|
||||
// must never make a local-network attempt. The local app-group diag
|
||||
// write above stays — Settings → Widget Diagnostics reads that.
|
||||
guard FuelStore.loadRelayFallbackEnabled() else { return }
|
||||
guard var components = URLComponents(
|
||||
url: RelayFuelProvider().baseURL.appendingPathComponent("api/v1/widget-diag"),
|
||||
resolvingAgainstBaseURL: false
|
||||
@@ -297,10 +301,18 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
)
|
||||
}
|
||||
|
||||
/// One focused fetch from the relay around the widget's location — small
|
||||
/// response (radius + limit 500), bounded so a dead relay can't stall the
|
||||
/// timeline. Returns nil on any failure so callers fall back to cache.
|
||||
/// One focused fetch around the widget's location. GitHub mirror FIRST —
|
||||
/// HTTPS, works anywhere, and the app-group day-cache usually makes it a
|
||||
/// local decode rather than a 2.8 MB download. The LAN relay only joins
|
||||
/// behind the dev flag (fuelboard.relayFallback); consumers must never
|
||||
/// attempt local-network access. Returns nil on any failure so callers
|
||||
/// fall back to cache/placeholder.
|
||||
private static func fetchFocused(near location: Coordinate, fuel: FuelType, radiusKM: Double) async -> [FuelStation]? {
|
||||
if let stations = try? await MirrorFuelProvider().fetchStations(
|
||||
near: location.lat, lng: location.lng, fuel: fuel, radiusKM: radiusKM) {
|
||||
return stations
|
||||
}
|
||||
guard FuelStore.loadRelayFallbackEnabled() else { return nil }
|
||||
var components = URLComponents(
|
||||
url: RelayFuelProvider().baseURL.appendingPathComponent("api/v1/stations"),
|
||||
resolvingAgainstBaseURL: false
|
||||
@@ -322,11 +334,16 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
}
|
||||
}
|
||||
|
||||
/// Fuel-only UK-wide fetch (no lat/lng/radius) — the relay returns the
|
||||
/// cheapest-first dataset for the fuel, bounded by limit. Used when the
|
||||
/// widget has no location fix so the face shows real stations instead of
|
||||
/// sample data. Same timeout/bounded semantics as fetchFocused.
|
||||
/// Fuel-only UK-wide fetch (no lat/lng/radius) — used when the widget has
|
||||
/// no location fix so the face shows real stations instead of sample
|
||||
/// data. GitHub mirror first (full dump + local fuel filter), relay only
|
||||
/// behind the dev flag. Same nil-on-failure semantics as fetchFocused.
|
||||
private static func fetchFuelOnly(fuel: FuelType, limit: Int) async -> [FuelStation]? {
|
||||
if let stations = try? await MirrorFuelProvider().fetchStations(
|
||||
near: nil, lng: nil, fuel: fuel, radiusKM: nil) {
|
||||
return Array(stations.filter { $0.prices[fuel] != nil }.prefix(limit))
|
||||
}
|
||||
guard FuelStore.loadRelayFallbackEnabled() else { return nil }
|
||||
var components = URLComponents(
|
||||
url: RelayFuelProvider().baseURL.appendingPathComponent("api/v1/stations"),
|
||||
resolvingAgainstBaseURL: false
|
||||
|
||||
Reference in New Issue
Block a user