The sheet's header (navigationTitle, .inline) shows the station name, and the address row no longer leads with the name either, so the Name row restated the header immediately above the address. The section now opens straight with Address; distance, Worth the drive and the buttons are untouched. Verified on the simulator: the sheet reads "Sainsbury's Halifax" in the header with rows "Address / WADE STREET, HX1 1SB" and "Distance / 0.5 mi", and no Name row. No other surface in the app prints a Name row.
130 lines
6.0 KiB
Swift
130 lines
6.0 KiB
Swift
import SwiftUI
|
|
import MapKit
|
|
import UIKit
|
|
|
|
/// Detail sheet for a tapped station (when Settings → Tap station = More info).
|
|
/// Shows a small map preview, the address, distance from the current location,
|
|
/// and a Directions button that opens Apple Maps — the same destination a direct
|
|
/// tap would have opened. The station name lives in the sheet header, not in a
|
|
/// row.
|
|
struct StationDetailView: View {
|
|
let station: FuelStation
|
|
let location: Coordinate?
|
|
let distanceUnit: DistanceUnit
|
|
var fuelSavings: FuelSavingsAvailability? = nil
|
|
var fuelSavingsAmount: FuelSavingsFillAmount = FuelSavingsSettings.defaultPreferredAmount
|
|
var savingsBaselineStationName: String? = nil
|
|
/// Whether this station is starred for the fuel currently being viewed, and
|
|
/// the toggle that flips it. Passed from the list that opened the sheet, so
|
|
/// the star here and the star on the row are the same fuel-scoped
|
|
/// favourite and cannot drift apart.
|
|
var isFavourite: Bool = false
|
|
var onToggleFavourite: (() -> Void)? = nil
|
|
@Environment(\.dismiss) private var dismiss
|
|
@State private var showingReportIssueConfirmation = false
|
|
|
|
private let reportIssueURL = URL(string: "https://www.gov.uk/guidance/report-an-error-in-fuel-prices-or-forecourt-details")!
|
|
|
|
private var stationCoordinate: CLLocationCoordinate2D {
|
|
CLLocationCoordinate2D(latitude: station.lat, longitude: station.lng)
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
List {
|
|
Section {
|
|
Map(position: .constant(.region(MKCoordinateRegion(
|
|
center: stationCoordinate,
|
|
span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)
|
|
)))) {
|
|
Marker(station.name, coordinate: stationCoordinate)
|
|
.tint(.red)
|
|
}
|
|
.frame(height: 180)
|
|
.clipShape(RoundedRectangle(cornerRadius: 12))
|
|
.allowsHitTesting(false)
|
|
.listRowInsets(EdgeInsets())
|
|
}
|
|
Section {
|
|
// The station name is NOT repeated here: the sheet header
|
|
// (navigationTitle, inline) already shows it, and the address
|
|
// line below has any leading repeat of the name stripped, so
|
|
// a "Name" row only said it twice.
|
|
LabeledContent("Address", value: StationAddressLine.display(address: station.address,
|
|
postcode: station.postcode,
|
|
name: station.name))
|
|
if let location {
|
|
let km = FuelStore.displayDistanceKM(
|
|
station: station, userLat: location.lat, userLng: location.lng
|
|
)
|
|
LabeledContent("Distance", value: distanceUnit.format(km))
|
|
.monospacedDigit()
|
|
}
|
|
ForEach(StationNotice.notices(for: station)) { notice in
|
|
Label(notice.title, systemImage: notice.symbolName)
|
|
.font(.subheadline.weight(.semibold))
|
|
.foregroundStyle(.orange)
|
|
.padding(.horizontal, 10)
|
|
.padding(.vertical, 6)
|
|
.background(Capsule().fill(Color.orange.opacity(0.14)))
|
|
}
|
|
}
|
|
Section {
|
|
FuelSavingsSummaryView(
|
|
availability: fuelSavings,
|
|
amount: fuelSavingsAmount,
|
|
baselineStationName: savingsBaselineStationName,
|
|
distanceUnit: distanceUnit
|
|
)
|
|
} header: {
|
|
Text("Worth the drive?")
|
|
}
|
|
|
|
Section {
|
|
Button {
|
|
if let url = station.mapsDirectionsURL {
|
|
UIApplication.shared.open(url)
|
|
}
|
|
} label: {
|
|
Label("Directions", systemImage: "arrow.triangle.turn.up.right.diamond.fill")
|
|
}
|
|
Button(role: .destructive) {
|
|
showingReportIssueConfirmation = true
|
|
} label: {
|
|
Label("Report issue", systemImage: "exclamationmark.bubble.fill")
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle(station.name)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.alert("Report an error?", isPresented: $showingReportIssueConfirmation) {
|
|
Button("Cancel", role: .cancel) { }
|
|
Button("Report") {
|
|
UIApplication.shared.open(reportIssueURL)
|
|
}
|
|
} message: {
|
|
Text("Are you sure you want to report an error in fuel prices or forecourt details? This will open in your chosen browser.")
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Done") { dismiss() }
|
|
}
|
|
ToolbarItem(placement: .confirmationAction) {
|
|
Button {
|
|
onToggleFavourite?()
|
|
} label: {
|
|
Image(systemName: isFavourite ? "star.fill" : "star")
|
|
}
|
|
.tint(isFavourite ? Color.yellow : nil)
|
|
.disabled(onToggleFavourite == nil)
|
|
.accessibilityLabel(
|
|
isFavourite
|
|
? String(localized: "Remove from favourites", comment: "Unstar a station from the More info sheet")
|
|
: String(localized: "Add to favourites", comment: "Star a station from the More info sheet")
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|