Live Activity: price now respects the Price display style — style carried in ContentState (captured at push time, extension renders deterministically instead of re-reading storage), setting change pushes an in-place content update via explicit override (no save-ordering race)
This commit is contained in:
@@ -322,13 +322,21 @@ struct ContentView: View {
|
|||||||
fuel: alertsFuel, radiusKM: effectiveAlertsRadiusKM)
|
fuel: alertsFuel, radiusKM: effectiveAlertsRadiusKM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onChange(of: priceDisplayStyle) { _, newValue in
|
||||||
|
// The pill carries its own display style in content state — push
|
||||||
|
// an update so the running activity re-renders in the new style
|
||||||
|
// immediately. Pass the style explicitly: SettingsView saves it
|
||||||
|
// in its own onChange, whose ordering vs this one isn't guaranteed,
|
||||||
|
// so reading storage here could push the OLD style.
|
||||||
|
updateLiveActivity(priceDisplayStyleOverride: newValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes the current best-in-radius station into the Live Activity.
|
/// Pushes the current best-in-radius station into the Live Activity.
|
||||||
/// No-op (or ends the activity) when the toggle is off or there's no
|
/// No-op (or ends the activity) when the toggle is off or there's no
|
||||||
/// location/data yet. Uses the Live Activity's OWN fuel + radius (set in
|
/// location/data yet. Uses the Live Activity's OWN fuel + radius (set in
|
||||||
/// Settings) — independent of the Stations-tab fuel/distance.
|
/// Settings) — independent of the Stations-tab fuel/distance.
|
||||||
private func updateLiveActivity() {
|
private func updateLiveActivity(priceDisplayStyleOverride: PriceDisplayStyle? = nil) {
|
||||||
// "Follow search" mirrors the Stations-tab distance exactly (no cap —
|
// "Follow search" mirrors the Stations-tab distance exactly (no cap —
|
||||||
// the pill only displays, it doesn't geofence).
|
// the pill only displays, it doesn't geofence).
|
||||||
let radiusKM = liveActivityFollowsSearch
|
let radiusKM = liveActivityFollowsSearch
|
||||||
@@ -339,7 +347,8 @@ struct ContentView: View {
|
|||||||
fuel: liveActivityFuel,
|
fuel: liveActivityFuel,
|
||||||
radiusKM: radiusKM,
|
radiusKM: radiusKM,
|
||||||
location: location,
|
location: location,
|
||||||
enabled: liveActivityEnabled
|
enabled: liveActivityEnabled,
|
||||||
|
priceDisplayStyle: priceDisplayStyleOverride
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,15 @@ enum LiveActivityManager {
|
|||||||
|
|
||||||
/// Recomputes the cheapest-in-radius station and updates the activity.
|
/// Recomputes the cheapest-in-radius station and updates the activity.
|
||||||
/// Passing `enabled: false` (or no usable data) ends any running activity.
|
/// Passing `enabled: false` (or no usable data) ends any running activity.
|
||||||
|
/// `priceDisplayStyle` overrides the saved style (used when the setting
|
||||||
|
/// just changed and the save may not have landed yet); nil = read storage.
|
||||||
static func update(
|
static func update(
|
||||||
stations: [FuelStation],
|
stations: [FuelStation],
|
||||||
fuel: FuelType,
|
fuel: FuelType,
|
||||||
radiusKM: Double,
|
radiusKM: Double,
|
||||||
location: Coordinate?,
|
location: Coordinate?,
|
||||||
enabled: Bool
|
enabled: Bool,
|
||||||
|
priceDisplayStyle: PriceDisplayStyle? = nil
|
||||||
) {
|
) {
|
||||||
guard enabled, let location else {
|
guard enabled, let location else {
|
||||||
end()
|
end()
|
||||||
@@ -53,6 +56,7 @@ enum LiveActivityManager {
|
|||||||
stationName: best.name,
|
stationName: best.name,
|
||||||
brand: best.brand,
|
brand: best.brand,
|
||||||
pricePence: price,
|
pricePence: price,
|
||||||
|
priceDisplayStyle: priceDisplayStyle ?? FuelStore.loadPriceDisplayStyle(),
|
||||||
distanceKM: best.distanceKM(to: location.lat, lng2: location.lng),
|
distanceKM: best.distanceKM(to: location.lat, lng2: location.lng),
|
||||||
lat: best.lat,
|
lat: best.lat,
|
||||||
lng: best.lng,
|
lng: best.lng,
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ private struct FuelBoardLiveActivityView: View {
|
|||||||
|
|
||||||
// RIGHT — price
|
// RIGHT — price
|
||||||
VStack(alignment: .trailing, spacing: 2) {
|
VStack(alignment: .trailing, spacing: 2) {
|
||||||
FuelStore.priceTextAttributed(context.state.pricePence, size: 22, weight: .bold)
|
FuelStore.priceTextAttributed(context.state.pricePence,
|
||||||
|
style: context.state.priceDisplayStyle,
|
||||||
|
size: 22, weight: .bold)
|
||||||
Text("Tap for directions")
|
Text("Tap for directions")
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
@@ -86,7 +88,9 @@ private struct FuelBoardLiveActivityPriceView: View {
|
|||||||
let context: ActivityViewContext<FuelBoardLiveActivityAttributes>
|
let context: ActivityViewContext<FuelBoardLiveActivityAttributes>
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
FuelStore.priceTextAttributed(context.state.pricePence, size: 17, weight: .bold)
|
FuelStore.priceTextAttributed(context.state.pricePence,
|
||||||
|
style: context.state.priceDisplayStyle,
|
||||||
|
size: 17, weight: .bold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,9 +130,10 @@ extension FuelBoardLiveActivityAttributes.ContentState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Price string from pence, in the user's chosen display style
|
/// Price string from pence, in the user's chosen display style
|
||||||
/// (station sign "129.9" or pounds "£1.29⁹/L").
|
/// (station sign "129.9" or pounds "£1.29⁹/L"). Uses the style captured
|
||||||
|
/// in the state at push time.
|
||||||
var priceText: String {
|
var priceText: String {
|
||||||
FuelStore.priceText(pricePence)
|
FuelStore.priceText(pricePence, style: priceDisplayStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apple Maps directions URL to the pinned station.
|
/// Apple Maps directions URL to the pinned station.
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ struct FuelBoardLiveActivityAttributes: ActivityAttributes {
|
|||||||
var brand: String
|
var brand: String
|
||||||
/// Price in pence per litre (same unit as `FuelStation.prices`).
|
/// Price in pence per litre (same unit as `FuelStation.prices`).
|
||||||
var pricePence: Double
|
var pricePence: Double
|
||||||
|
/// Display style at push time (station sign vs pounds & pence) — carried
|
||||||
|
/// in the state so the extension renders deterministically instead of
|
||||||
|
/// re-reading storage that may not be shared on sideloads.
|
||||||
|
var priceDisplayStyle: PriceDisplayStyle
|
||||||
var distanceKM: Double
|
var distanceKM: Double
|
||||||
var lat: Double
|
var lat: Double
|
||||||
var lng: Double
|
var lng: Double
|
||||||
|
|||||||
Reference in New Issue
Block a user