From 1b6184c03544c25051bcf8b45aefd058316328cb Mon Sep 17 00:00:00 2001 From: FuelBoard Contributor Date: Sat, 17 Oct 2026 14:03:45 +0100 Subject: [PATCH] Simplify shared fill-up wording and help --- FuelBoard/FavouritesView.swift | 21 +++++++++++++--- FuelBoard/FuelSavingsViews.swift | 35 +++++++++++++++++++++----- FuelBoard/en.lproj/Localizable.strings | 9 +++++-- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/FuelBoard/FavouritesView.swift b/FuelBoard/FavouritesView.swift index 526a172..a9b24c4 100644 --- a/FuelBoard/FavouritesView.swift +++ b/FuelBoard/FavouritesView.swift @@ -69,6 +69,15 @@ struct FavouritesView: View { } private var cheapestPrice: Double? { cheapest?.prices[activeFuel] } + /// The baseline note is useful only when at least one visible favourite has + /// an actual savings comparison. An unavailable result (for example, while + /// location is missing) must not leave an orphaned explanation below the list. + private var showsSavingsComparisonExplanation: Bool { + fuelSavingsSettings.isConfigured && ordered.contains { station in + savingsForStation(station)?.result != nil + } + } + /// IDs favourited for the active fuel — the star state on each row. private var activeFuelFavouriteIDs: Set { Set(favourites.filter { $0.fuel == activeFuel }.map(\.station.id)) @@ -145,8 +154,6 @@ struct FavouritesView: View { if fuelSavingsSettings.isConfigured { Section { FuelSavingsAdjustmentView(amount: $fuelSavingsAmount) - } footer: { - Text(String(localized: "Savings below are estimated against the closest station by journey distance — the same baseline as the Stations list.", comment: "Favourites fuel-savings explanation")) } } @@ -171,7 +178,15 @@ struct FavouritesView: View { } header: { Text(String(format: String(localized: "%@ favourites", comment: "Favourites section title for fuel type"), activeFuel.displayName)) } footer: { - Text(String(localized: "The first station is the favourite used in single widgets. Tap Edit, then drag to reorder.", comment: "Favourites reorder explanation")) + VStack(alignment: .leading, spacing: 12) { + Text(String(localized: "The first station is the favourite used in single widgets. Tap Edit, then drag to reorder.", comment: "Favourites reorder explanation")) + if showsSavingsComparisonExplanation { + Text(String(localized: "Savings are compared with your nearest station, just like in the Stations tab.", comment: "Favourites fuel-savings explanation")) + } + } + .font(.footnote) + .foregroundStyle(.secondary) + .frame(maxWidth: .infinity, alignment: .leading) } if let cheapest = cheapest { diff --git a/FuelBoard/FuelSavingsViews.swift b/FuelBoard/FuelSavingsViews.swift index 86b4029..117ad48 100644 --- a/FuelBoard/FuelSavingsViews.swift +++ b/FuelBoard/FuelSavingsViews.swift @@ -4,6 +4,7 @@ struct FuelSavingsAdjustmentView: View { @Binding var amount: FuelSavingsFillAmount @State private var unitChangeNotice: String? + @State private var showingComparisonHelp = false private var range: ClosedRange { FuelSavingsCalculator.fillAmountSliderRange(for: amount.unit) @@ -26,8 +27,33 @@ struct FuelSavingsAdjustmentView: View { var body: some View { VStack(alignment: .leading, spacing: 10) { - Text("How much are you filling up?") - .font(.subheadline.weight(.semibold)) + HStack { + Text("How much fuel?") + .font(.subheadline.weight(.semibold)) + Spacer() + Button { + showingComparisonHelp = true + } label: { + Image(systemName: "info.circle") + } + .buttonStyle(.plain) + .foregroundStyle(.secondary) + .accessibilityLabel("About comparison modes") + .popover(isPresented: $showingComparisonHelp) { + VStack(alignment: .leading, spacing: 12) { + Text("Comparison modes") + .font(.headline) + Text("£: Compare how much fuel your budget buys at each station.") + .fixedSize(horizontal: false, vertical: true) + Text("Litres: Compare the cost of buying the same amount of fuel.") + .fixedSize(horizontal: false, vertical: true) + } + .font(.footnote) + .frame(width: 280, alignment: .leading) + .padding() + .presentationCompactAdaptation(.popover) + } + } Picker("Fill-up unit", selection: unitBinding) { ForEach(FuelSavingsFillUnit.allCases) { unit in Text(unit.displayName).tag(unit) @@ -42,10 +68,7 @@ struct FuelSavingsAdjustmentView: View { .monospacedDigit() .frame(width: 72, alignment: .trailing) } - Text("Changes the estimate for this session only — your Settings default stays unchanged.") - .font(.caption2) - .foregroundStyle(.secondary) - Text("£ compares the litres your budget buys at each station; Litres compares one fixed quantity.") + Text("Adjust your fill-up amount for this visit. Your default won’t change.") .font(.caption2) .foregroundStyle(.secondary) if let unitChangeNotice { diff --git a/FuelBoard/en.lproj/Localizable.strings b/FuelBoard/en.lproj/Localizable.strings index b5de580..45eb0cc 100644 --- a/FuelBoard/en.lproj/Localizable.strings +++ b/FuelBoard/en.lproj/Localizable.strings @@ -41,7 +41,7 @@ "Best Value compares each station with the closest station by journey distance. It works out what you could save at the pump, then takes off the fuel used for the extra return journey." = "Best Value compares each station with the closest station by journey distance. It works out what you could save at the pump, then takes off the fuel used for the extra return journey."; "With a £ budget you spend that amount at each station; the litres differ by station. Savings compare those litres with the same quantity at your closest station, then deduct extra journey fuel. You do not receive cash back." = "With a £ budget you spend that amount at each station; the litres differ by station. Savings compare those litres with the same quantity at your closest station, then deduct extra journey fuel. You do not receive cash back."; "Your closest station by journey distance is the baseline — every other saving is measured against it." = "Your closest station by journey distance is the baseline — every other saving is measured against it."; -"Savings below are estimated against the closest station by journey distance — the same baseline as the Stations list." = "Savings below are estimated against the closest station by journey distance — the same baseline as the Stations list."; +"Savings are compared with your nearest station, just like in the Stations tab." = "Savings are compared with your nearest station, just like in the Stations tab."; "Your fill-up amount and MPG are used to show whether you could save overall." = "Your fill-up amount and MPG are used to show whether you could save overall."; "Results are marked “Approx.” until road distances are available." = "Results are marked “Approx.” until road distances are available."; @@ -223,7 +223,12 @@ "Proximity alerts" = "Proximity alerts"; /* Best Value calculation and station price age */ -"£ compares the litres your budget buys at each station; Litres compares one fixed quantity." = "£ compares the litres your budget buys at each station; Litres compares one fixed quantity."; +"How much fuel?" = "How much fuel?"; +"Adjust your fill-up amount for this visit. Your default won’t change." = "Adjust your fill-up amount for this visit. Your default won’t change."; +"About comparison modes" = "About comparison modes"; +"Comparison modes" = "Comparison modes"; +"£: Compare how much fuel your budget buys at each station." = "£: Compare how much fuel your budget buys at each station."; +"Litres: Compare the cost of buying the same amount of fuel." = "Litres: Compare the cost of buying the same amount of fuel."; "You pay the selected budget here. The saving compares the same litres at your closest station; litres differ between stations, and this is not a refund." = "You pay the selected budget here. The saving compares the same litres at your closest station; litres differ between stations, and this is not a refund."; "Best Value unavailable · location needed" = "Best Value unavailable · location needed"; "your order" = "your order";