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:
+13
-18
@@ -4,10 +4,14 @@ import SwiftUI
|
||||
/// being monitored.
|
||||
struct AlertsView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var radius: Double
|
||||
@Binding var radius: Double // stored in km (monitor + storage)
|
||||
let distanceUnit: DistanceUnit
|
||||
let monitoredCount: Int
|
||||
let lastAlert: String?
|
||||
var onShowOnboarding: () -> Void = {}
|
||||
|
||||
/// The radius slider works in the user's chosen unit; the stored value
|
||||
/// stays km so ProximityMonitor and persistence never change.
|
||||
private var radiusInUnit: Double { distanceUnit.fromKM(radius) }
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
@@ -24,11 +28,15 @@ struct AlertsView: View {
|
||||
HStack {
|
||||
Text("Radius")
|
||||
Spacer()
|
||||
Text("\(Int(radius)) km")
|
||||
Text(String(format: "%.1f %@", radiusInUnit, distanceUnit.shortName))
|
||||
.foregroundStyle(.secondary)
|
||||
.monospacedDigit()
|
||||
}
|
||||
Slider(value: $radius, in: 1...10, step: 1)
|
||||
// 1–10 in the user's unit; convert back to km on change.
|
||||
Slider(value: Binding(
|
||||
get: { radiusInUnit },
|
||||
set: { radius = distanceUnit.toKM($0) }
|
||||
), in: 1...10, step: distanceUnit == .kilometers ? 1 : 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +50,7 @@ struct AlertsView: View {
|
||||
Text("Your favourites get priority, then the closest stations fill the rest (18 max, iOS region limit).")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
Text("Alerts are checked against the cheapest station within \(Int(radius)) km for the selected fuel. Each station alerts at most once per hour.")
|
||||
Text("Alerts are checked against the cheapest station within the trigger radius for the selected fuel. Each station alerts at most once per hour.")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
@@ -55,19 +63,6 @@ struct AlertsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Testing hook — in production onboarding shows once at first
|
||||
// launch; this button re-opens it to verify the flow.
|
||||
Section {
|
||||
Button {
|
||||
onShowOnboarding()
|
||||
} label: {
|
||||
Label("Show onboarding (testing)", systemImage: "flag.fill")
|
||||
.font(.footnote)
|
||||
}
|
||||
} footer: {
|
||||
Text("Testing only — onboarding normally appears once on first launch.")
|
||||
}
|
||||
}
|
||||
.navigationTitle("Alerts")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user