diff --git a/NucleicRemote/NucleicRemote/LiveActivityManager.swift b/NucleicRemote/NucleicRemote/LiveActivityManager.swift index b57ecae..e97793d 100644 --- a/NucleicRemote/NucleicRemote/LiveActivityManager.swift +++ b/NucleicRemote/NucleicRemote/LiveActivityManager.swift @@ -24,6 +24,18 @@ final class LiveActivityManager { private var activity: Activity? + /// Whether an aggregate glance is currently on screen — `RemoteStore` checks this to decide + /// whether to fall back to a banner (no glance ⇒ the banner is the only surface). + var hasLiveActivity: Bool { activity != nil } + + /// Whether the app is foreground, mirrored from `RemoteStore` (its `isForeground`). Drives where + /// a "needs you" arrival is announced: **foreground** the app UI / a banner does it, so the glance + /// updates silently; **backgrounded** there's no banner (we prefer the glance), so the update + /// itself carries an `AlertConfiguration` (sound/haptic). Starts `true` — `onAppear` runs + /// foreground; the background adopt path flips it. Mirrors the host's connected-vs-away gate for + /// the pushed glance, but for the still-connected phone whose own socket is alive. + var foreground = true + /// The last content we pushed. Updates that don't change it are skipped so we don't spend /// ActivityKit's update budget on no-ops — `sync` fires on every host message (dashboard, /// connectivity, pong, diff ticks…), most of which leave the aggregate identical. Burning the