iOS Live Activity Updates
Nucleic-Session: 665980BA-E8A5-4E84-9DF4-1757CF792353 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -87,6 +87,41 @@ final class LiveActivityManager {
|
|||||||
push(state, hostName: hostName)
|
push(state, hostName: hostName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Nothing is running or waiting. If the glance was showing active work, flash a brief "Done"
|
||||||
|
/// summary of the just-completed sessions and then dismiss (UX_IOS §5.3 — a run should read as
|
||||||
|
/// *finished*, not just vanish). If nothing was on screen, there's nothing to close.
|
||||||
|
private func finishWithDoneGlance(hostName: String, live: [WireSessionSummary]) {
|
||||||
|
// Already flashing "Done" and scheduled to dismiss — let that run rather than restart it.
|
||||||
|
guard dismissTask == nil else { return }
|
||||||
|
// Nothing tracked on screen: only reach into ActivityKit if an untracked orphan is lingering.
|
||||||
|
guard activity != nil else {
|
||||||
|
if !Activity<NucleicSessionAttributes>.activities.isEmpty { end() }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// The sessions that just finished — completed conversational turns and finished runs. These
|
||||||
|
// are exactly the ones the active-work filter above drops, surfaced now as `.done` rows.
|
||||||
|
let done = live
|
||||||
|
.filter {
|
||||||
|
$0.status == .finished
|
||||||
|
|| ($0.status == .awaitingInput && $0.disposition == .completed)
|
||||||
|
}
|
||||||
|
.sorted(by: StatusStyle.attentionThenRecency)
|
||||||
|
.prefix(Self.maxLines)
|
||||||
|
.map(Self.line(for:))
|
||||||
|
// Nothing to celebrate (e.g. the work was discarded/deleted) → just dismiss.
|
||||||
|
guard !done.isEmpty else { end(); return }
|
||||||
|
|
||||||
|
let state = NucleicSessionAttributes.ContentState(
|
||||||
|
runningCount: 0, needsYouCount: 0, approvalCount: 0,
|
||||||
|
filesChanged: 0, linesAdded: 0, linesRemoved: 0, lines: Array(done))
|
||||||
|
push(state, hostName: hostName)
|
||||||
|
dismissTask = Task { [weak self] in
|
||||||
|
try? await Task.sleep(for: Self.doneLinger)
|
||||||
|
guard !Task.isCancelled else { return }
|
||||||
|
self?.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply `state` to the Activity — deduped against the last push and coalesced through one
|
/// Apply `state` to the Activity — deduped against the last push and coalesced through one
|
||||||
/// serial task so the newest state always wins.
|
/// serial task so the newest state always wins.
|
||||||
private func push(_ state: NucleicSessionAttributes.ContentState, hostName: String) {
|
private func push(_ state: NucleicSessionAttributes.ContentState, hostName: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user