From d348157a45d91a3f8b121509d92fc9b9d81d5799 Mon Sep 17 00:00:00 2001 From: FuelBoard Contributor Date: Sun, 11 Oct 2026 20:11:57 +0100 Subject: [PATCH] Best Value: rename the remaining user-facing copy, hide the sheet section when off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following the sort-segment rename, the rest of the user-facing "Worth the Drive" copy moves to "Best Value". - Settings: the toggle is now just "Best Value" (was "Enable Worth the Drive"), and the narrative footer opens "Best Value estimates fuel cost only, …". - More info sheet: the section header is "Best Value" (was "Worth the drive?"), and the section itself is now conditional. `fuelSavings` is nil whenever the feature is off — `savingsLookup` returns nil when it is not configured — so the heading is never left dangling over an empty section while the feature is disabled. - The unavailable text reads "Best Value unavailable: …". - Comments and doc comments that named the sort were updated so they match the UI instead of contradicting it. Deliberately unchanged: the enum's raw value stays `worthTheDrive`, so stored sort preferences and widget configs keep decoding, and FuelSavingsStatus keeps its verdict wording ("Worth the drive" / "Not worth the drive") — that describes a station's verdict rather than the feature, and is not shown in the UI. Verified on the simulator: with the feature OFF the more info sheet shows Address / Distance / Directions and no heading at all; with it ON the sheet shows the "Best Value" section; Settings reads "Fuel Savings" / "Best Value" with no "Enable" anywhere. 172 tests, 0 failures. --- FuelBoard/ContentView.swift | 4 ++-- FuelBoard/FuelSavingsViews.swift | 2 +- FuelBoard/SettingsView.swift | 6 ++--- FuelBoard/StationDetailView.swift | 24 ++++++++++++------- .../SortModeNamesTests.swift | 8 ++++--- Shared/FuelSavings.swift | 2 +- Shared/FuelStore.swift | 8 +++---- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/FuelBoard/ContentView.swift b/FuelBoard/ContentView.swift index 160d92b..3865e5d 100644 --- a/FuelBoard/ContentView.swift +++ b/FuelBoard/ContentView.swift @@ -340,7 +340,7 @@ struct ContentView: View { private static var lastDriveLogLine: String? /// One summary line per ranking pass (FB-DRIVE) so a device console shows - /// whether the Worth the Drive list is actually carrying savings for the + /// whether the Best Value list is actually carrying savings for the /// whole pool — the regression was silent otherwise. private func logWorthTheDriveSummary(_ ordered: [FuelStation], baseline: FuelStation?, @@ -1357,7 +1357,7 @@ struct StationRow: View { VStack(alignment: .trailing, spacing: 2) { if isTopResult { // The badge always marks the CHEAPEST PUMP PRICE (never - // "best saving"), so in Worth the Drive order — where the + // "best saving"), so in Best Value order — where the // top row is the best net saving — it may sit lower down // the list, and says so. It sits ABOVE the price it // annotates rather than beside the name, so it reads as diff --git a/FuelBoard/FuelSavingsViews.swift b/FuelBoard/FuelSavingsViews.swift index 42febd8..f5bc283 100644 --- a/FuelBoard/FuelSavingsViews.swift +++ b/FuelBoard/FuelSavingsViews.swift @@ -142,7 +142,7 @@ struct FuelSavingsSummaryView: View { } } case .unavailable(let reason): - Text(compact ? "Savings unavailable" : "Worth the Drive unavailable: \(reason)") + Text(compact ? "Savings unavailable" : "Best Value unavailable: \(reason)") .font(compact ? .caption2 : .caption) .foregroundStyle(.secondary) case nil: diff --git a/FuelBoard/SettingsView.swift b/FuelBoard/SettingsView.swift index f631b06..23dd413 100644 --- a/FuelBoard/SettingsView.swift +++ b/FuelBoard/SettingsView.swift @@ -150,13 +150,13 @@ struct SettingsView: View { } Section { - Toggle("Enable Worth the Drive", isOn: fuelSavingsEnabledBinding) + Toggle("Best Value", isOn: fuelSavingsEnabledBinding) // The feature's own controls follow its toggle: switched // off they grey out but stay on screen (same rule as the // distance picker in Closest mode) and keep their values, so // re-enabling restores exactly what was there. The sections // that USE the feature — the in-list fill-up control and the - // Worth the Drive sort option — are gated on `isConfigured`, + // Best Value sort option — are gated on `isConfigured`, // which already includes `enabled`, so they hide entirely. Group { HStack { @@ -199,7 +199,7 @@ struct SettingsView: View { } header: { Text("Fuel Savings") } footer: { - Text("Worth the Drive estimates fuel cost only, using UK imperial MPG, your typical purchase amount, fuel prices and Apple Maps road distances. Real-world average MPG is better than manufacturer figures; the fill-up amount is your usual purchase, not tank capacity.") + Text("Best Value estimates fuel cost only, using UK imperial MPG, your typical purchase amount, fuel prices and Apple Maps road distances. Real-world average MPG is better than manufacturer figures; the fill-up amount is your usual purchase, not tank capacity.") } Section { diff --git a/FuelBoard/StationDetailView.swift b/FuelBoard/StationDetailView.swift index aadcb15..768f231 100644 --- a/FuelBoard/StationDetailView.swift +++ b/FuelBoard/StationDetailView.swift @@ -69,15 +69,21 @@ struct StationDetailView: View { .background(Capsule().fill(Color.orange.opacity(0.14))) } } - Section { - FuelSavingsSummaryView( - availability: fuelSavings, - amount: fuelSavingsAmount, - baselineStationName: savingsBaselineStationName, - distanceUnit: distanceUnit - ) - } header: { - Text("Worth the drive?") + // Only shown while Fuel Savings backs it. `fuelSavings` is nil + // when the feature is off — `savingsLookup` returns nil when it + // is not configured — so the heading cannot be left dangling + // over an empty section. + if let fuelSavings { + Section { + FuelSavingsSummaryView( + availability: fuelSavings, + amount: fuelSavingsAmount, + baselineStationName: savingsBaselineStationName, + distanceUnit: distanceUnit + ) + } header: { + Text("Best Value") + } } Section { diff --git a/FuelBoardTests/Tests/FuelBoardSharedTests/SortModeNamesTests.swift b/FuelBoardTests/Tests/FuelBoardSharedTests/SortModeNamesTests.swift index 338968d..74149f4 100644 --- a/FuelBoardTests/Tests/FuelBoardSharedTests/SortModeNamesTests.swift +++ b/FuelBoardTests/Tests/FuelBoardSharedTests/SortModeNamesTests.swift @@ -21,9 +21,11 @@ final class SortModeNamesTests: XCTestCase { XCTAssertEqual(SortMode.allCases.map(\.rawValue), ["cheapest", "closest", "worthTheDrive"]) } - func testTheFeatureItselfIsStillCalledWorthTheDrive() { - // Only the sort was renamed — the status wording the feature produces - // keeps its own name. + func testTheVerdictWordingIsUnchanged() { + // The feature and its sort are both called "Best Value" in user-facing + // copy now (Settings toggle + narrative, the sheet's section header). + // FuelSavingsStatus's own wording describes a VERDICT rather than the + // feature, and is not shown in the UI, so it keeps the drive phrasing. XCTAssertEqual(FuelSavingsStatus.worthTheDrive.displayName, "Worth the drive") XCTAssertEqual(FuelSavingsStatus.notWorthTheDrive.displayName, "Not worth the drive") } diff --git a/Shared/FuelSavings.swift b/Shared/FuelSavings.swift index d0332ca..9e904d6 100644 --- a/Shared/FuelSavings.swift +++ b/Shared/FuelSavings.swift @@ -398,7 +398,7 @@ enum FuelSavingsEstimator { } } - /// Ranks a whole pool for the Worth the Drive sort. + /// Ranks a whole pool for the Best Value sort. /// /// EVERY priced station in the pool gets an estimate, not just the handful /// whose road routes happen to have been measured: journeys that have no diff --git a/Shared/FuelStore.swift b/Shared/FuelStore.swift index 5e2353d..a4cd888 100644 --- a/Shared/FuelStore.swift +++ b/Shared/FuelStore.swift @@ -53,10 +53,10 @@ enum SortMode: String, Codable, CaseIterable, Identifiable { switch self { case .cheapest: return "Cheapest" case .closest: return "Closest" - // "Best Value" is the user-facing name of this sort. The raw value stays - // `worthTheDrive` so stored preferences keep decoding, and it is the SORT - // that is called Best Value — the Fuel Savings feature itself is still - // "Worth the Drive" (its Settings toggle, section and sheet header). + // "Best Value" is the user-facing name of this sort — the segmented + // control, the Stations caption, the Settings toggle and narrative, and + // the sheet's section header all read it. The raw value stays + // `worthTheDrive` so stored preferences and widget configs keep decoding. case .worthTheDrive: return "Best Value" } }