Live Activity Content Density
Nucleic-Session: B3643133-163C-4C5D-BE20-1A6B7FB83DA9 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -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(
|
activity = try? Activity.request(
|
||||||
attributes: NucleicSessionAttributes(hostName: hostName),
|
attributes: NucleicSessionAttributes(hostName: hostName),
|
||||||
content: ActivityContent(state: state, staleDate: nil))
|
content: ActivityContent(state: state, staleDate: nil))
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = 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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user