Retire the Best Value proximity alert option; move Key sheet copy into a tested model
- Alerts: drop the alert-type picker and the Best Value alert path, so proximity alerts always follow the cheapest station. A stored `bestValue` selection now falls back to cheapest when loaded. - Key sheet: the price-rating, savings, station-label and favourite wording comes from `KeySheetContent` in Shared/FuelSavings.swift — a Foundation-only model with tests that pin the exact meaning of each indicator — and the sheet is built from that model rather than inline strings. - BACKLOG: record the plan to restore Best Value proximity alerts behind one shared evaluator (user-location baseline, a single disclosed qualification rule, and real/Test alert parity). - Bump CURRENT_PROJECT_VERSION to 29.
This commit is contained in:
@@ -37,7 +37,6 @@ struct ContentView: View {
|
||||
@State private var alertsEnabled: Bool = FuelStore.loadAlertsEnabled()
|
||||
@State private var alertsRadius: Double = FuelStore.loadAlertsRadius()
|
||||
@State private var alertsFuel: FuelType = FuelStore.loadAlertsFuel()
|
||||
@State private var alertsMode: AlertMode = FuelStore.loadAlertsMode()
|
||||
@State private var alertsBestValueThresholdGBP: Double = FuelStore.loadAlertsBestValueThresholdGBP()
|
||||
@State private var favouriteDropAlertsEnabled: Bool = FuelStore.loadFavouriteDropAlertsEnabled()
|
||||
@State private var favouriteDropAlertsFuel: FuelType = FuelStore.loadFavouriteDropAlertsFuel()
|
||||
@@ -152,23 +151,13 @@ struct ContentView: View {
|
||||
FuelStore.effectiveAlertsRadiusKM(followsSearch: alertsFollowsSearch, manualKM: alertsRadius)
|
||||
}
|
||||
|
||||
private var effectiveAlertsMode: AlertMode {
|
||||
(alertsMode == .bestValue && !fuelSavingsSettings.isConfigured) ? .cheapest : alertsMode
|
||||
}
|
||||
|
||||
private func ensureBestValueAlertModeIsAvailable() {
|
||||
guard alertsMode == .bestValue, !fuelSavingsSettings.isConfigured else { return }
|
||||
alertsMode = .cheapest
|
||||
FuelStore.saveAlertsMode(.cheapest)
|
||||
}
|
||||
|
||||
private func updateAlertMonitor(fuel overrideFuel: FuelType? = nil) {
|
||||
monitor.update(
|
||||
stations: stations,
|
||||
favourites: refreshedFavourites,
|
||||
fuel: overrideFuel ?? alertsFuel,
|
||||
radiusKM: effectiveAlertsRadiusKM,
|
||||
alertMode: effectiveAlertsMode,
|
||||
alertMode: .cheapest,
|
||||
bestValueThresholdGBP: alertsBestValueThresholdGBP,
|
||||
fuelSavingsSettings: fuelSavingsSettings,
|
||||
fuelSavingsAmount: sessionFuelSavingsAmount
|
||||
@@ -1154,7 +1143,6 @@ struct ContentView: View {
|
||||
// or the choice wouldn't take effect until the next launch.
|
||||
fuelSavingsSettings = FuelStore.loadFuelSavingsSettings()
|
||||
sessionFuelSavingsAmount = fuelSavingsSettings.preferredAmount
|
||||
ensureBestValueAlertModeIsAvailable()
|
||||
locationManager.startForegroundTracking()
|
||||
installLocationUpdateHook()
|
||||
ensureBackgroundMotionTrackingIfNeeded()
|
||||
@@ -1174,7 +1162,6 @@ struct ContentView: View {
|
||||
#if DEBUG
|
||||
print("FB-SAVINGS settings changed: enabled=\(old.enabled)->\(new.enabled) configured=\(new.isConfigured)")
|
||||
#endif
|
||||
ensureBestValueAlertModeIsAvailable()
|
||||
updateAlertMonitor()
|
||||
}
|
||||
.onChange(of: sessionFuelSavingsAmount) { _, _ in
|
||||
@@ -1257,16 +1244,6 @@ struct ContentView: View {
|
||||
FuelStore.saveAlertsFuel(newValue)
|
||||
updateAlertMonitor(fuel: newValue)
|
||||
}
|
||||
.onChange(of: alertsMode) { _, newValue in
|
||||
if newValue == .bestValue, !fuelSavingsSettings.isConfigured {
|
||||
alertsMode = .cheapest
|
||||
FuelStore.saveAlertsMode(.cheapest)
|
||||
updateAlertMonitor()
|
||||
return
|
||||
}
|
||||
FuelStore.saveAlertsMode(newValue)
|
||||
updateAlertMonitor()
|
||||
}
|
||||
.onChange(of: alertsBestValueThresholdGBP) { _, newValue in
|
||||
FuelStore.saveAlertsBestValueThresholdGBP(newValue)
|
||||
updateAlertMonitor()
|
||||
@@ -1609,9 +1586,6 @@ struct ContentView: View {
|
||||
enabled: $alertsEnabled,
|
||||
radius: $alertsRadius,
|
||||
fuel: $alertsFuel,
|
||||
alertMode: $alertsMode,
|
||||
bestValueThresholdGBP: alertsBestValueThresholdGBP,
|
||||
bestValueConfigured: fuelSavingsSettings.isConfigured,
|
||||
favouriteDropEnabled: $favouriteDropAlertsEnabled,
|
||||
favouriteDropFuel: $favouriteDropAlertsFuel,
|
||||
followsSearch: $alertsFollowsSearch,
|
||||
@@ -2053,9 +2027,7 @@ struct StationRow: View {
|
||||
// scaled down or truncated.
|
||||
if let price = station.prices[fuel] {
|
||||
HStack(spacing: 5) {
|
||||
Circle()
|
||||
.fill(ragColor)
|
||||
.frame(width: 8, height: 8)
|
||||
PriceRatingDot(color: ragColor)
|
||||
FuelStore.priceTextAttributed(price, style: priceDisplayStyle,
|
||||
size: priceSize, weight: .bold)
|
||||
.lineLimit(1)
|
||||
@@ -2088,8 +2060,7 @@ struct StationRow: View {
|
||||
Button {
|
||||
onToggleFavourite()
|
||||
} label: {
|
||||
Image(systemName: isFavourite ? "star.fill" : "star")
|
||||
.foregroundStyle(isFavourite ? .yellow : .secondary)
|
||||
FavouriteStarGlyph(isFavourite: isFavourite)
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
}
|
||||
@@ -2110,14 +2081,7 @@ struct StationRow: View {
|
||||
/// app: coloured text keeps its contrast in both appearances, at every
|
||||
/// Dynamic Type size, without introducing a colour outside the palette.
|
||||
private func badgeCapsule(_ badge: StationRecommendationBadge) -> some View {
|
||||
Text(badge.title)
|
||||
.font(.caption2.bold())
|
||||
.foregroundStyle(badge.tint)
|
||||
.padding(.horizontal, 7)
|
||||
.padding(.vertical, 3)
|
||||
.background(Capsule().fill(badge.tint.opacity(0.15)))
|
||||
.lineLimit(1)
|
||||
.fixedSize()
|
||||
StationLabelBadge(label: badge.title, color: badge.tint)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user