Watch: show subagent requests on the parent's card, and settle threads by swipe, Settle all and the thread screen

This commit is contained in:
gib committed 2026-11-01 20:26:38 -05:00
1 parent a4754b65b0
commit cf8995e63f
16 files changed
+347 -31

No files matched your search

+36
View File
@@ -26,6 +26,10 @@ final class AppModel {
var path: [Route] = []
private(set) var feed: Feed?
private(set) var feedError: String?
/// Ids of feed items whose settle call is still out. The feed hides them meanwhile.
private(set) var settling: Set<String> = []
/// Why settling an item failed, by item id. Its row shows the message.
private(set) var settleErrors: [String: String] = [:]
private var apnsToken: String?
private var refreshing = false
/// The counts the complication was last told about.
@@ -151,6 +155,38 @@ final class AppModel {
}
}
/// Settles items concurrently. Each one leaves the feed at once and comes back with its error
/// if its call fails. Refreshes once every call has answered.
func settle(_ items: [FeedItem]) async {
let ids = Set(items.map(\.id))
settling.formUnion(ids)
for id in ids { settleErrors[id] = nil }
let api = api
let failures = await withTaskGroup(of: (String, (any Error)?).self) { group in
for item in items {
group.addTask {
do {
try await api.settle(hostId: item.hostId, threadId: item.threadId)
return (item.id, nil)
} catch {
return (item.id, error)
}
}
}
var failures: [String: any Error] = [:]
for await (id, error) in group {
if let error { failures[id] = error }
}
return failures
}
for (id, error) in failures {
settleErrors[id] = message(for: error)
}
feed?.recent.removeAll { ids.contains($0.id) && failures[$0.id] == nil }
settling.subtract(ids)
await refreshFeed()
}
func open(_ route: Route) {
path = [route]
}