Live Activity Content Density

Nucleic-Session: B3643133-163C-4C5D-BE20-1A6B7FB83DA9
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-04 23:46:00 -07:00
co-authored by Nucleic
parent d8561b325d
commit ff605a3997
@@ -68,23 +68,52 @@ final class LiveActivityManager {
linesRemoved: removed, linesRemoved: removed,
lines: Array(lines)) lines: Array(lines))
if let activity { push(state, hostName: hostName)
Task { await activity.update(ActivityContent(state: state, staleDate: nil)) } }
} else {
// Recover an Activity that survived an app relaunch before starting a new one. /// Apply `state` to the Activity — deduped against the last push and coalesced through one
/// serial task so the newest state always wins.
private func push(_ state: NucleicSessionAttributes.ContentState, hostName: String) {
guard state != lastState else { return }
lastState = state
guard let activity else {
// Recover an Activity that survived an app relaunch before starting a new one; the
// recovered one still needs the fresh state, so fall through to the update pipeline.
if let existing = Activity<NucleicSessionAttributes>.activities.first { if let existing = Activity<NucleicSessionAttributes>.activities.first {
activity = existing activity = existing
Task { await existing.update(ActivityContent(state: state, staleDate: nil)) } enqueue(state)
return } else {
activity = try? Activity.request(
attributes: NucleicSessionAttributes(hostName: hostName),
content: ActivityContent(state: state, staleDate: nil))
} }
activity = try? Activity.request( return
attributes: NucleicSessionAttributes(hostName: hostName), }
content: ActivityContent(state: state, staleDate: nil)) _ = activity
enqueue(state)
}
/// Hand the newest state to the serial drainer (starting it if idle).
private func enqueue(_ state: NucleicSessionAttributes.ContentState) {
pendingState = state
guard updateTask == nil else { return } // the running drainer will pick this up
updateTask = Task { @MainActor [weak self] in
guard let self else { return }
while let next = self.pendingState {
self.pendingState = nil
await self.activity?.update(ActivityContent(state: next, staleDate: nil))
}
self.updateTask = nil
} }
} }
/// End the Activity (all idle, or unpaired). /// End the Activity (all idle, or unpaired).
func end() { func end() {
updateTask?.cancel()
updateTask = nil
pendingState = nil
lastState = nil
guard let activity else { return } guard let activity else { return }
self.activity = nil self.activity = nil
Task { Task {