Show full fetch in list (count picker respected); radius scope only for cheapest/RAG reference; row = logo | name/address/distance | £price + delta | star
This commit is contained in:
+23
-17
@@ -21,10 +21,11 @@ struct ContentView: View {
|
||||
@State private var locationManager = LocationManager()
|
||||
@StateObject private var monitor = ProximityMonitor()
|
||||
|
||||
/// Stations within the alert trigger radius of the current location, used
|
||||
/// as the pool for "cheapest" (RAG reference, TOP, sorting). Falls back to
|
||||
/// the full fetch when location is unknown or the radius pool is empty
|
||||
/// (rural areas) so the list is never blank.
|
||||
/// Stations within the alert trigger radius of the current location — used
|
||||
/// ONLY as the "cheapest" reference (RAG, TOP, deltas), so the cheapest
|
||||
/// label matches what alerts would flag. The list itself shows the full
|
||||
/// fetch so the count picker works. Falls back to the full fetch when
|
||||
/// location is unknown or the radius pool is empty.
|
||||
private var radiusScopedStations: [FuelStation] {
|
||||
guard let location else { return stations }
|
||||
let within = stations.filter {
|
||||
@@ -42,7 +43,9 @@ struct ContentView: View {
|
||||
}
|
||||
|
||||
private var sortedStations: [FuelStation] {
|
||||
let available = radiusScopedStations.filter { $0.prices[selectedFuel] != nil }
|
||||
// Full fetch pool — NOT radius-scoped, so the results count picker
|
||||
// (10/25/50/75/100) is respected.
|
||||
let available = stations.filter { $0.prices[selectedFuel] != nil }
|
||||
switch sortMode {
|
||||
case .closest:
|
||||
guard let location else { return available.sorted { $0.prices[selectedFuel]! < $1.prices[selectedFuel]! } }
|
||||
@@ -224,7 +227,7 @@ struct StationRow: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 12) {
|
||||
// Round brand logo (or generic fuel pump fallback)
|
||||
// LEFT — round brand logo (or generic fuel pump fallback)
|
||||
Group {
|
||||
if let asset = station.brandImageName {
|
||||
Image(asset)
|
||||
@@ -243,10 +246,9 @@ struct StationRow: View {
|
||||
.overlay(Circle().stroke(Color.primary.opacity(0.08), lineWidth: 1))
|
||||
.shadow(color: .black.opacity(0.08), radius: 2, y: 1)
|
||||
|
||||
// Name at natural width (does NOT fill the row — truncates);
|
||||
// price + details stay on the row below, right-aligned.
|
||||
VStack(alignment: .leading, spacing: 3) {
|
||||
HStack(alignment: .firstTextBaseline, spacing: 6) {
|
||||
// MIDDLE — name, full address, distance
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
HStack(spacing: 6) {
|
||||
Text(station.name)
|
||||
.font(.headline)
|
||||
.lineLimit(1)
|
||||
@@ -259,28 +261,32 @@ struct StationRow: View {
|
||||
.background(Capsule().fill(.blue.opacity(0.15)))
|
||||
.foregroundStyle(.blue)
|
||||
}
|
||||
Spacer(minLength: 6)
|
||||
}
|
||||
|
||||
HStack(spacing: 5) {
|
||||
Text("\(station.address), \(station.postcode)")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
.lineLimit(1)
|
||||
Spacer(minLength: 8)
|
||||
.truncationMode(.tail)
|
||||
if let location {
|
||||
Text(String(format: "%.1f km", station.distanceKM(to: location.lat, lng2: location.lng)))
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
.monospacedDigit()
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
// RIGHT — price in £ (no p) + difference vs cheapest
|
||||
VStack(alignment: .trailing, spacing: 2) {
|
||||
if let price = station.prices[fuel] {
|
||||
HStack(spacing: 5) {
|
||||
Circle()
|
||||
.fill(ragColor)
|
||||
.frame(width: 10, height: 10)
|
||||
Text(String(format: "%.1fp", price))
|
||||
.frame(width: 8, height: 8)
|
||||
Text(String(format: "£%.3f", price / 100))
|
||||
.font(.title3.bold())
|
||||
.monospacedDigit()
|
||||
}
|
||||
if let deltaText {
|
||||
Text(deltaText)
|
||||
.font(.caption2.bold())
|
||||
@@ -288,8 +294,8 @@ struct StationRow: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FAR RIGHT — favourite star
|
||||
Button {
|
||||
onToggleFavourite()
|
||||
} label: {
|
||||
|
||||
Reference in New Issue
Block a user