Distance picker disabled in Closest mode; whole-country pool for nearest-first (radius never empties Closest)
This commit is contained in:
+15
-27
@@ -21,47 +21,35 @@ struct ContentView: View {
|
||||
@State private var locationManager = LocationManager()
|
||||
@StateObject private var monitor = ProximityMonitor()
|
||||
|
||||
/// Stations within the CHOSEN search radius (miles) of the current location
|
||||
/// — the same pool the list shows, so "cheapest" (RAG, TOP, deltas) matches
|
||||
/// exactly what's on screen. STRICT: no fallback to out-of-radius stations
|
||||
/// (a cached fetch around another location must never leak far results in).
|
||||
private var radiusScopedStations: [FuelStation] {
|
||||
guard let location else { return [] }
|
||||
/// The pool the list draws from. In Cheapest mode the chosen miles radius
|
||||
/// bounds it ("best price within X miles"); in Closest mode the radius is
|
||||
/// redundant — the whole country sorted nearest-first, because "nearest"
|
||||
/// must never answer with an empty state. STRICT: no fallback to
|
||||
/// out-of-radius stations in Cheapest mode.
|
||||
private var poolStations: [FuelStation] {
|
||||
let selling = stations.filter { $0.prices[selectedFuel] != nil }
|
||||
guard let location else { return selling }
|
||||
if sortMode == .closest { return selling } // radius disabled in Closest
|
||||
let radiusKM = Double(stationLimit) * 1.60934 // chosen miles → km
|
||||
return stations.filter {
|
||||
return selling.filter {
|
||||
$0.distanceKM(to: location.lat, lng2: location.lng) <= radiusKM
|
||||
}
|
||||
}
|
||||
|
||||
private var cheapestPrice: Double? {
|
||||
radiusScopedStations.compactMap { $0.prices[selectedFuel] }.min()
|
||||
poolStations.compactMap { $0.prices[selectedFuel] }.min()
|
||||
}
|
||||
|
||||
private var displayedStations: [FuelStation] {
|
||||
// Relay already returns every station within the selected miles radius
|
||||
// (sorted nearest-first); no local cap needed.
|
||||
sortedStations
|
||||
}
|
||||
|
||||
private var sortedStations: [FuelStation] {
|
||||
// Stations selling the selected fuel, scoped STRICTLY to the chosen
|
||||
// miles radius from the current location. Local enforcement matters:
|
||||
// the cache can hold stations from a previous, larger radius (or a
|
||||
// different area), and the relay filter only applies at fetch time.
|
||||
let selling = stations.filter { $0.prices[selectedFuel] != nil }
|
||||
let available: [FuelStation]
|
||||
if let location {
|
||||
let radiusKM = Double(stationLimit) * 1.60934 // miles → km
|
||||
available = selling.filter {
|
||||
$0.distanceKM(to: location.lat, lng2: location.lng) <= radiusKM
|
||||
}
|
||||
} else {
|
||||
available = selling
|
||||
}
|
||||
let pool = poolStations
|
||||
switch sortMode {
|
||||
case .closest:
|
||||
guard let location else { return available.sorted { $0.prices[selectedFuel]! < $1.prices[selectedFuel]! } }
|
||||
return available.sorted { lhs, rhs in
|
||||
guard let location else { return pool.sorted { $0.prices[selectedFuel]! < $1.prices[selectedFuel]! } }
|
||||
return pool.sorted { lhs, rhs in
|
||||
// Closest first; price only breaks ties.
|
||||
let lDist = lhs.distanceKM(to: location.lat, lng2: location.lng)
|
||||
let rDist = rhs.distanceKM(to: location.lat, lng2: location.lng)
|
||||
@@ -69,7 +57,7 @@ struct ContentView: View {
|
||||
return lhs.prices[selectedFuel]! < rhs.prices[selectedFuel]!
|
||||
}
|
||||
case .cheapest:
|
||||
return available.sorted { lhs, rhs in
|
||||
return pool.sorted { lhs, rhs in
|
||||
// Cheapest first; distance only breaks ties.
|
||||
let lPrice = lhs.prices[selectedFuel]!
|
||||
let rPrice = rhs.prices[selectedFuel]!
|
||||
|
||||
Reference in New Issue
Block a user