10 Commits
Author SHA1 Message Date
FuelBoard Contributor 05f3ef0a70 Add (E10)/(E5) bracket labels to Unleaded/Premium in picker and descriptions 2026-08-11 22:41:50 +01:00
FuelBoard Contributor 313fe84037 Use native large-title behaviour: drop custom icon header, .navigationTitle + .large (exact Mail-style collapse) 2026-08-11 22:27:38 +01:00
FuelBoard Contributor 24fffe1e8f Pin large title above list so it fades+collapses in place on scroll (Mail-style cross-fade) 2026-08-11 22:21:09 +01:00
FuelBoard Contributor ec191d77aa Cross-fade large title with compact bar on scroll (Mail-style) 2026-08-11 22:15:11 +01:00
FuelBoard Contributor cf69350472 Use native onScrollGeometryChange (iOS 18) so the compact icon+title bar actually appears on scroll, Mail-style 2026-08-11 22:05:03 +01:00
FuelBoard Contributor 8d24de401d Large icon+title header at rest; compact gas-pump bar appears only after scrolling (tracker on header row background) 2026-08-11 21:59:32 +01:00
FuelBoard Contributor 644342ae63 Nav bar: always show gas-pump icon next to title (inline mode); remove scroll-offset row hack 2026-08-11 21:54:56 +01:00
FuelBoard Contributor 12cb3707b6 Nav bar: show compact gas-pump+title only when scrolled (large title at rest); drop icons from fuel picker 2026-08-11 21:49:18 +01:00
FuelBoard Contributor 39b310d68d Add gas-pump icon left of title + coloured fuel-type tab icons (Unleaded green, Premium blue, Diesel grey) 2026-08-11 21:36:28 +01:00
FuelBoard Contributor c1edd4d52d App-side defensive price guard: drop grades outside 50-500p at decode (belt-and-braces vs relay regression) 2026-08-11 21:28:19 +01:00
3 changed files with 38 additions and 5 deletions
+30 -1
View File
@@ -47,7 +47,7 @@ struct StationsView: View {
Section("Fuel type") {
Picker("Fuel type", selection: $selectedFuel) {
ForEach(FuelType.allCases) { fuel in
Text(fuel.displayName).tag(fuel)
Text(fuel.shortName).tag(fuel)
}
}
.pickerStyle(.segmented)
@@ -180,7 +180,36 @@ struct StationsView: View {
// New fetch or filter switch back to the first page.
visibleCount = pageSize
}
// Native large-title behaviour (Mail-style): the system shows the
// large title at rest, scrolls it away and fades the compact
// inline title in. No custom toolbar needed the native mechanism
// only renders text, which is exactly what we want here.
.navigationTitle("FuelBoard")
.navigationBarTitleDisplayMode(.large)
}
}
}
// MARK: - Fuel-type iconography (app target only FuelStore.swift is Foundation-only)
extension FuelType {
/// Short segment label ("Unleaded (E10)" / "Premium (E5)" / "Diesel") for
/// the picker and description.
var shortName: String {
switch self {
case .e10: return "Unleaded (E10)"
case .e5: return "Premium (E5)"
case .diesel: return "Diesel"
}
}
/// Pump-handle colour convention (UK): green = unleaded, blue = premium,
/// dark grey = diesel. Used for the fuel-type tab icons and the title icon.
var tintColor: Color {
switch self {
case .e10: return .green
case .e5: return .blue
case .diesel: return Color(red: 0.35, green: 0.38, blue: 0.42)
}
}
}
+6 -2
View File
@@ -84,11 +84,15 @@ private struct RelayResponse: Codable {
let prices: [String: Double]?
/// Map relay grade keys (E5/E10/DIESEL) to FuelType for ALL fuels the
/// station sells one fetch populates every fuel tab.
/// station sells one fetch populates every fuel tab. Defensive guard:
/// any grade outside the 50500 pence/litre band is dropped, so a relay
/// regression (e.g. the band being removed server-side) can't re-poison
/// the nationwide cheapest reference with 1.3p / 1589p garbage.
var allPrices: [FuelType: Double] {
var result: [FuelType: Double] = [:]
if let prices {
for (grade, value) in prices {
guard (50...500).contains(value) else { continue }
switch grade.uppercased() {
case "E10": result[.e10] = value
case "E5": result[.e5] = value
@@ -98,7 +102,7 @@ private struct RelayResponse: Codable {
}
}
// Backwards-compat: relay versions without `prices` still send `price`.
if result.isEmpty, let price {
if result.isEmpty, let price, (50...500).contains(price) {
result[.e10] = price
}
return result
+2 -2
View File
@@ -56,8 +56,8 @@ enum FuelType: String, Codable, CaseIterable, Identifiable {
var displayName: String {
switch self {
case .e10: return "E10 Unleaded"
case .e5: return "E5 Premium"
case .e10: return "Unleaded (E10)"
case .e5: return "Premium (E5)"
case .diesel: return "Diesel"
}
}