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:
+73
-4
@@ -48,21 +48,75 @@ enum RAGRating: Int, Codable {
|
||||
}
|
||||
|
||||
enum FuelType: String, Codable, CaseIterable, Identifiable {
|
||||
case e10 // Unleaded 95 (E10)
|
||||
case e5 // Premium 97/98 (E5)
|
||||
case e10 // Unleaded (E10)
|
||||
case e5 // Premium (E5)
|
||||
case diesel // B7 diesel
|
||||
|
||||
var id: String { rawValue }
|
||||
|
||||
var displayName: 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Display unit for all distances in the app + widget. Internally distances
|
||||
/// are always stored/computed in km; conversion happens at the display and
|
||||
/// filter boundary so nothing else needs to know the unit.
|
||||
enum DistanceUnit: String, Codable, CaseIterable, Identifiable {
|
||||
case miles
|
||||
case kilometers
|
||||
|
||||
var id: String { rawValue }
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .miles: return "Miles"
|
||||
case .kilometers: return "Kilometres"
|
||||
}
|
||||
}
|
||||
|
||||
/// Short suffix for values ("5 mi", "3.2 km").
|
||||
var shortName: String {
|
||||
switch self {
|
||||
case .miles: return "mi"
|
||||
case .kilometers: return "km"
|
||||
}
|
||||
}
|
||||
|
||||
/// Full word for narrative text ("within 5 miles", "within 8 km").
|
||||
var label: String {
|
||||
switch self {
|
||||
case .miles: return "miles"
|
||||
case .kilometers: return "km"
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a value expressed in this unit to km.
|
||||
func toKM(_ value: Double) -> Double {
|
||||
switch self {
|
||||
case .miles: return value * 1.60934
|
||||
case .kilometers: return value
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a km value to this unit.
|
||||
func fromKM(_ km: Double) -> Double {
|
||||
switch self {
|
||||
case .miles: return km * 0.621371
|
||||
case .kilometers: return km
|
||||
}
|
||||
}
|
||||
|
||||
/// Format a km distance in this unit ("1.2 mi", "3.4 km").
|
||||
func format(_ km: Double) -> String {
|
||||
String(format: "%.1f %@", fromKM(km), shortName)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Station model
|
||||
|
||||
struct FuelStation: Identifiable, Codable, Equatable {
|
||||
@@ -179,6 +233,7 @@ struct FuelStore {
|
||||
static let fuelKey = "fuelboard.selectedFuel" // FuelType raw value
|
||||
static let sortModeKey = "fuelboard.sortMode" // SortMode raw value
|
||||
static let stationLimitKey = "fuelboard.stationLimitMiles" // Int miles (5/10/15)
|
||||
static let distanceUnitKey = "fuelboard.distanceUnit" // DistanceUnit raw value
|
||||
static let favouritesKey = "fuelboard.favourites" // [FuelStation] JSON
|
||||
static let alertsEnabledKey = "fuelboard.alertsEnabled" // Bool
|
||||
static let alertsRadiusKey = "fuelboard.alertsRadius" // Double km
|
||||
@@ -277,6 +332,20 @@ struct FuelStore {
|
||||
saveString(String(miles), service: stationLimitKey)
|
||||
}
|
||||
|
||||
// MARK: Distance unit — miles or kilometres. Stored raw value; default
|
||||
// miles for backward compatibility with pre-toggle installs.
|
||||
|
||||
static func loadDistanceUnit() -> DistanceUnit {
|
||||
if let raw = loadString(service: distanceUnitKey), let unit = DistanceUnit(rawValue: raw) {
|
||||
return unit
|
||||
}
|
||||
return .miles
|
||||
}
|
||||
|
||||
static func saveDistanceUnit(_ unit: DistanceUnit) {
|
||||
saveString(unit.rawValue, service: distanceUnitKey)
|
||||
}
|
||||
|
||||
// MARK: Favourites
|
||||
|
||||
static func loadFavourites() -> [FuelStation] {
|
||||
|
||||
Reference in New Issue
Block a user