Settings: price display toggle — station sign (£129.9) vs pounds & pence (£1.299); display-only, all surfaces (list, widgets, Live Activity, Siri cards); Siri dialog stays speech-safe pounds

This commit is contained in:
FuelBoard Contributor
2026-08-14 15:33:26 +01:00
parent 819d2e6152
commit fd7fa5f9c9
10 changed files with 150 additions and 36 deletions
+53
View File
@@ -143,6 +143,25 @@ enum DistanceUnit: String, Codable, CaseIterable, Identifiable {
}
}
/// Display style for fuel prices. Internally prices are always stored and
/// computed in pence-per-litre (GOV.UK's unit, e.g. 129.9); the style only
/// affects RENDERING: the station-sign convention shows the pence figure
/// ("£129.9", what a forecourt sign shows), pounds & pence shows the
/// converted value ("£1.299"). Calculations never see this.
enum PriceDisplayStyle: String, Codable, CaseIterable, Identifiable {
case stationSign // £129.9 matches the sign
case poundsPence // £1.299
var id: String { rawValue }
var displayName: String {
switch self {
case .stationSign: return "Station sign (£129.9)"
case .poundsPence: return "Pounds & pence (£1.299)"
}
}
}
// MARK: - Station model
struct FuelStation: Identifiable, Codable, Equatable {
@@ -435,6 +454,40 @@ struct FuelStore {
saveString(unit.rawValue, service: distanceUnitKey)
}
// MARK: Price display station-sign (£129.9) vs pounds & pence (£1.299).
// Prices are always stored/computed in pence-per-litre; this style only
// changes how they are RENDERED, so it can never affect calculations.
// Default station sign = the forecourt convention.
static let priceDisplayStyleKey = "fuelboard.priceDisplayStyle"
static func loadPriceDisplayStyle() -> PriceDisplayStyle {
if let raw = loadString(service: priceDisplayStyleKey), let style = PriceDisplayStyle(rawValue: raw) {
return style
}
return .stationSign
}
static func savePriceDisplayStyle(_ style: PriceDisplayStyle) {
saveString(style.rawValue, service: priceDisplayStyleKey)
}
/// Render a pence-per-litre price per the saved style:
/// stationSign -> "£129.9" (sign convention), poundsPence -> "£1.299".
static func priceText(_ pence: Double, style: PriceDisplayStyle? = nil) -> String {
switch style ?? loadPriceDisplayStyle() {
case .stationSign: return String(format: "£%.1f", pence)
case .poundsPence: return String(format: "£%.3f", pence / 100)
}
}
/// Speech-safe pounds form for Siri dialogs Siri would read "£129.9"
/// aloud as "one hundred and twenty-nine pounds", so the SPOKEN answer
/// always uses pounds regardless of the display style.
static func priceTextSpoken(_ pence: Double) -> String {
String(format: "£%.3f", pence / 100)
}
// MARK: Debug mode
/// Hidden developer flag. NOT exposed in the UI: toggled by tapping the