live activity: explicit badge (dark circle + bright pump); fix alignment look
fuelpump.circle.fill's first hierarchical style hits the PUMP, not the circle, so the earlier darkened colour landed on the pump and the circle stayed white (user: 'I didn't want the fuel pump darker I wanted the white circle darker'). Rebuild the brand glyph from two explicit shapes: a light-grey (.86) Circle badge + a bright fuel-tinted fuelpump.fill, so circle vs pump colours are unambiguous and the badge centres cleanly with the two-line text block. Add a DEBUG-only -qaLiveActivity <fuel> launch hook that starts a Live Activity with a long station name so the Lock Screen can be rendered in the Simulator and verified by pixels (pump bright green 43,193,81; badge grey 202,201,202).
This commit is contained in:
@@ -1,7 +1,22 @@
|
|||||||
|
import ActivityKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct FuelBoardApp: App {
|
struct FuelBoardApp: App {
|
||||||
|
init() {
|
||||||
|
#if DEBUG
|
||||||
|
// QA hook (Debug builds only): `-qaLiveActivity e10|e5|diesel` starts a
|
||||||
|
// Live Activity with a long station name so the Lock Screen / island
|
||||||
|
// layout can be rendered in the Simulator for visual QA.
|
||||||
|
let args = ProcessInfo.processInfo.arguments
|
||||||
|
if let idx = args.firstIndex(of: "-qaLiveActivity"),
|
||||||
|
args.indices.contains(idx + 1),
|
||||||
|
let fuel = FuelType(rawValue: args[idx + 1]) {
|
||||||
|
startQALiveActivity(fuel: fuel)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
ContentView()
|
ContentView()
|
||||||
@@ -9,6 +24,34 @@ struct FuelBoardApp: App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
private func startQALiveActivity(fuel: FuelType) {
|
||||||
|
let state = FuelBoardLiveActivityAttributes.ContentState(
|
||||||
|
fuel: fuel,
|
||||||
|
stationID: "qa-phoenix",
|
||||||
|
stationName: "Phoenix Filling Stations",
|
||||||
|
brand: "Phoenix",
|
||||||
|
pricePence: 1499,
|
||||||
|
priceDisplayStyle: FuelStore.loadPriceDisplayStyle(),
|
||||||
|
distanceKM: 8.0,
|
||||||
|
lat: 51.5,
|
||||||
|
lng: -0.12,
|
||||||
|
updatedAt: Date()
|
||||||
|
)
|
||||||
|
let attrs = FuelBoardLiveActivityAttributes()
|
||||||
|
do {
|
||||||
|
let activity = try Activity.request(
|
||||||
|
attributes: attrs,
|
||||||
|
content: .init(state: state, staleDate: nil),
|
||||||
|
pushType: nil
|
||||||
|
)
|
||||||
|
print("QA-LIVE-ACTIVITY STARTED id=\(activity.id)")
|
||||||
|
} catch {
|
||||||
|
print("QA-LIVE-ACTIVITY FAILED: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Handles deep links that end up in the app. Widget taps arrive here in
|
/// Handles deep links that end up in the app. Widget taps arrive here in
|
||||||
/// two cases:
|
/// two cases:
|
||||||
/// - legacy/cached widget timelines using the `fuelboard://` relay, or
|
/// - legacy/cached widget timelines using the `fuelboard://` relay, or
|
||||||
|
|||||||
@@ -73,12 +73,13 @@ private struct FuelBoardLiveActivityView: View {
|
|||||||
/// "ideal" width past the iPhone Lock Screen and collapses the full card).
|
/// "ideal" width past the iPhone Lock Screen and collapses the full card).
|
||||||
private let compactWidthThreshold: CGFloat = 280
|
private let compactWidthThreshold: CGFloat = 280
|
||||||
|
|
||||||
/// Slightly darkened fuel tint for the pump circle so the white pump
|
/// The badge circle behind the pump. The user calls this "the white
|
||||||
/// symbol keeps contrast against the bright Lock Screen / card background
|
/// circle" and wants it slightly darkened for contrast against the bright
|
||||||
/// (the raw palette colours like yellow #FFD60A are too light to sit under
|
/// fuel pump. Built as an explicit grey disc (the light-grey "white circle
|
||||||
/// a white glyph).
|
/// darker") — NOT part of the SF Symbol glyph, so it can never swallow the
|
||||||
private var pumpCircleColor: Color {
|
/// darkened colour the way `fuelpump.circle.fill` did.
|
||||||
context.state.fuel.tintColor.mix(with: .black, by: 0.18)
|
private var badgeCircleColor: Color {
|
||||||
|
Color(white: 0.86)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -107,11 +108,20 @@ private struct FuelBoardLiveActivityView: View {
|
|||||||
/// Full three-column design (unchanged): brand glyph · fuel+station · price.
|
/// Full three-column design (unchanged): brand glyph · fuel+station · price.
|
||||||
private var richBody: some View {
|
private var richBody: some View {
|
||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
// LEFT — station brand glyph
|
// LEFT — station brand badge: an explicit darkened circle with a
|
||||||
Image(systemName: "fuelpump.circle.fill")
|
// bright fuel-tinted pump. Built from two shapes so the circle
|
||||||
.font(.system(size: 32))
|
// colour and pump colour are unambiguous (the myth that
|
||||||
.foregroundStyle(pumpCircleColor, .white)
|
// fuelpump.circle.fill's first style is the circle is what put the
|
||||||
.frame(width: 40, height: 40)
|
// darkened colour on the pump).
|
||||||
|
ZStack {
|
||||||
|
Circle()
|
||||||
|
.fill(badgeCircleColor)
|
||||||
|
.frame(width: 40, height: 40)
|
||||||
|
Image(systemName: "fuelpump.fill")
|
||||||
|
.font(.system(size: 19, weight: .semibold))
|
||||||
|
.foregroundStyle(context.state.fuel.tintColor)
|
||||||
|
}
|
||||||
|
.frame(width: 40, height: 40)
|
||||||
|
|
||||||
// MIDDLE — fuel + station
|
// MIDDLE — fuel + station
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
|||||||
Reference in New Issue
Block a user