Closest mode: deltas vs the CLOSEST station (signed +X.Xp/-X.Xp), not the nationwide cheapest; baseline = sortedStations.first
This commit is contained in:
+19
-10
@@ -36,8 +36,15 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var cheapestPrice: Double? {
|
/// The price reference every row's delta + RAG compares against.
|
||||||
poolStations.compactMap { $0.prices[selectedFuel] }.min()
|
/// Cheapest mode → the cheapest station in the pool (best value).
|
||||||
|
/// Closest mode → the CLOSEST station: deltas answer "is it worth leaving
|
||||||
|
/// the station nearest to me?" (+X.Xp pricier / -X.Xp cheaper).
|
||||||
|
private var baselinePrice: Double? {
|
||||||
|
if sortMode == .closest {
|
||||||
|
return sortedStations.first?.prices[selectedFuel]
|
||||||
|
}
|
||||||
|
return poolStations.compactMap { $0.prices[selectedFuel] }.min()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var displayedStations: [FuelStation] {
|
private var displayedStations: [FuelStation] {
|
||||||
@@ -86,7 +93,7 @@ struct ContentView: View {
|
|||||||
selectedFuel: $selectedFuel,
|
selectedFuel: $selectedFuel,
|
||||||
sortMode: $sortMode,
|
sortMode: $sortMode,
|
||||||
stationLimit: $stationLimit,
|
stationLimit: $stationLimit,
|
||||||
cheapestPrice: cheapestPrice,
|
baselinePrice: baselinePrice,
|
||||||
location: location,
|
location: location,
|
||||||
favouriteIDs: favouriteIDs,
|
favouriteIDs: favouriteIDs,
|
||||||
onToggleFavourite: toggleFavourite,
|
onToggleFavourite: toggleFavourite,
|
||||||
@@ -214,14 +221,14 @@ struct StationRow: View {
|
|||||||
let station: FuelStation
|
let station: FuelStation
|
||||||
let fuel: FuelType
|
let fuel: FuelType
|
||||||
let location: Coordinate?
|
let location: Coordinate?
|
||||||
let cheapestPrice: Double?
|
let baselinePrice: Double?
|
||||||
let isTopResult: Bool
|
let isTopResult: Bool
|
||||||
let isFavourite: Bool
|
let isFavourite: Bool
|
||||||
var onToggleFavourite: () -> Void = {}
|
var onToggleFavourite: () -> Void = {}
|
||||||
|
|
||||||
private var ragColor: Color {
|
private var ragColor: Color {
|
||||||
guard let price = station.prices[fuel], let cheapestPrice else { return .gray }
|
guard let price = station.prices[fuel], let baselinePrice else { return .gray }
|
||||||
switch RAGRating.rating(price: price, cheapest: cheapestPrice) {
|
switch RAGRating.rating(price: price, cheapest: baselinePrice) {
|
||||||
case .green: return .green
|
case .green: return .green
|
||||||
case .amber: return .orange
|
case .amber: return .orange
|
||||||
case .red: return .red
|
case .red: return .red
|
||||||
@@ -229,10 +236,12 @@ struct StationRow: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var deltaText: String? {
|
private var deltaText: String? {
|
||||||
guard let price = station.prices[fuel], let cheapestPrice else { return nil }
|
guard let price = station.prices[fuel], let baselinePrice else { return nil }
|
||||||
let delta = price - cheapestPrice
|
let delta = price - baselinePrice
|
||||||
if delta <= 0.05 { return "best" }
|
if abs(delta) <= 0.05 { return "best" }
|
||||||
return String(format: "+%.1fp", delta)
|
// Signed: +X.Xp pricier than baseline, -X.Xp cheaper (Closest mode);
|
||||||
|
// in Cheapest mode the baseline is the cheapest so deltas are ≥ 0.
|
||||||
|
return String(format: "%+.1fp", delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct FavouritesView: View {
|
|||||||
station: station,
|
station: station,
|
||||||
fuel: selectedFuel,
|
fuel: selectedFuel,
|
||||||
location: location,
|
location: location,
|
||||||
cheapestPrice: cheapestPrice,
|
baselinePrice: cheapestPrice,
|
||||||
isTopResult: index == 0,
|
isTopResult: index == 0,
|
||||||
isFavourite: favouriteIDs.contains(station.id),
|
isFavourite: favouriteIDs.contains(station.id),
|
||||||
onToggleFavourite: { onToggleFavourite(station) }
|
onToggleFavourite: { onToggleFavourite(station) }
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ struct StationsView: View {
|
|||||||
@Binding var selectedFuel: FuelType
|
@Binding var selectedFuel: FuelType
|
||||||
@Binding var sortMode: SortMode
|
@Binding var sortMode: SortMode
|
||||||
@Binding var stationLimit: Int
|
@Binding var stationLimit: Int
|
||||||
let cheapestPrice: Double?
|
let baselinePrice: Double?
|
||||||
let location: Coordinate?
|
let location: Coordinate?
|
||||||
let favouriteIDs: Set<String>
|
let favouriteIDs: Set<String>
|
||||||
var onToggleFavourite: (FuelStation) -> Void = { _ in }
|
var onToggleFavourite: (FuelStation) -> Void = { _ in }
|
||||||
@@ -110,7 +110,7 @@ struct StationsView: View {
|
|||||||
station: station,
|
station: station,
|
||||||
fuel: selectedFuel,
|
fuel: selectedFuel,
|
||||||
location: location,
|
location: location,
|
||||||
cheapestPrice: cheapestPrice,
|
baselinePrice: baselinePrice,
|
||||||
isTopResult: index == 0,
|
isTopResult: index == 0,
|
||||||
isFavourite: favouriteIDs.contains(station.id),
|
isFavourite: favouriteIDs.contains(station.id),
|
||||||
onToggleFavourite: { onToggleFavourite(station) }
|
onToggleFavourite: { onToggleFavourite(station) }
|
||||||
|
|||||||
Reference in New Issue
Block a user