Add Settings tab: distance units toggle, onboarding replay, £4.99 tip; drop E10/E5 from labels

- FuelType labels: 'Unleaded (E10)'/'Premium (E5)' -> 'Unleaded'/'Premium'
- New DistanceUnit (miles/km) preference; all app + widget distances,
  radii and alert text convert/display in the chosen unit
- Settings tab (4th tab): segmented miles/km picker, 'Show introduction'
  replay button (onboarding moved out of Alerts tab), StoreKit tip £4.99
- ProximityMonitor + widget notifications use the chosen unit
- Tests: label expectations updated, DistanceUnit conversion + format tests
This commit is contained in:
FuelBoard Contributor
2026-08-12 07:46:08 +01:00
parent fb79cf0788
commit 44c6c38536
10 changed files with 284 additions and 47 deletions
+9 -7
View File
@@ -9,6 +9,7 @@ struct StationsView: View {
@Binding var selectedFuel: FuelType
@Binding var sortMode: SortMode
@Binding var stationLimit: Int
let distanceUnit: DistanceUnit
let baselinePrice: Double?
let topStationID: String?
let location: Coordinate?
@@ -29,11 +30,11 @@ struct StationsView: View {
Section {
if let location {
if sortMode == .closest {
Text("Closest \(selectedFuel.displayName) stations — nearest first, best value within \(stationLimit) miles.")
Text("Closest \(selectedFuel.displayName) stations — nearest first, best value within \(stationLimit) \(distanceUnit.label).")
.font(.footnote)
.foregroundStyle(.secondary)
} else {
Text("Cheapest \(selectedFuel.displayName) within \(stationLimit) miles — tap a station for directions.")
Text("Cheapest \(selectedFuel.displayName) within \(stationLimit) \(distanceUnit.label) — tap a station for directions.")
.font(.footnote)
.foregroundStyle(.secondary)
}
@@ -60,7 +61,7 @@ struct StationsView: View {
Section("Distance") {
Picker("Distance", selection: $stationLimit) {
ForEach(FuelStore.stationRadiusOptions, id: \.self) { miles in
Text("\(miles) miles").tag(miles)
Text("\(miles) \(distanceUnit.label)").tag(miles)
}
}
.pickerStyle(.segmented)
@@ -79,7 +80,7 @@ struct StationsView: View {
.font(.caption2)
.foregroundStyle(.secondary)
} else {
Text("\(totalCount) stations within \(stationLimit) miles")
Text("\(totalCount) stations within \(stationLimit) \(distanceUnit.label)")
.font(.caption2)
.foregroundStyle(.secondary)
}
@@ -111,6 +112,7 @@ struct StationsView: View {
station: station,
fuel: selectedFuel,
location: location,
distanceUnit: distanceUnit,
baselinePrice: baselinePrice,
isTopResult: station.id == topStationID,
isFavourite: favouriteIDs.contains(station.id),
@@ -193,12 +195,12 @@ struct StationsView: View {
// MARK: - Fuel-type iconography (app target only FuelStore.swift is Foundation-only)
extension FuelType {
/// Short segment label ("Unleaded (E10)" / "Premium (E5)" / "Diesel") for
/// Short segment label ("Unleaded" / "Premium" / "Diesel") for
/// the picker and description.
var shortName: String {
switch self {
case .e10: return "Unleaded (E10)"
case .e5: return "Premium (E5)"
case .e10: return "Unleaded"
case .e5: return "Premium"
case .diesel: return "Diesel"
}
}