Close stale notifications once the item is dealt with

This commit is contained in:
Ian Gulliver
2026-10-17 15:41:54 -07:00
parent 67578352ce
commit e67576ac53
4 changed files with 39 additions and 4 deletions
+36 -1
View File
@@ -59,6 +59,18 @@ private func itemText(_ item: InboxItem) -> String {
}
}
@MainActor
private var queue: Task<Void, Never>?
@MainActor
private func enqueue(_ op: @escaping @MainActor () async -> Void) {
let prev = queue
queue = Task {
await prev?.value
await op()
}
}
@MainActor
private func show(_ store: Store, _ taskId: String, _ tag: String, _ text: String) {
let line = trimmed(text).split(separator: "\n", omittingEmptySubsequences: false).first.map(String.init) ?? ""
@@ -68,7 +80,7 @@ private func show(_ store: Store, _ taskId: String, _ tag: String, _ text: Strin
content.sound = .default
content.userInfo = ["task_id": taskId]
let request = UNNotificationRequest(identifier: tag, content: content, trigger: nil)
Task {
enqueue {
let status = await UNUserNotificationCenter.current().notificationSettings().authorizationStatus
if status != .authorized && status != .provisional {
return
@@ -89,6 +101,29 @@ func notifyInbox(_ store: Store, _ item: InboxItem) {
show(store, item.taskId, item.id, itemText(item))
}
@MainActor
func clearInbox(_ item: InboxItem) {
if item.state == .open {
return
}
enqueue {
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [item.id])
}
}
@MainActor
func clearTurns(_ taskId: String, through seq: Int64) {
enqueue {
let ids = await UNUserNotificationCenter.current().deliveredNotifications().map(\.request).filter { r in
guard r.content.userInfo["task_id"] as? String == taskId, r.identifier.hasPrefix("turn-"), let s = Int64(r.identifier.dropFirst(5)) else {
return false
}
return s <= seq
}.map(\.identifier)
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ids)
}
}
@MainActor
func notifyTurn(_ store: Store, _ ev: ByreEvent) {
guard let me = store.me, me.notificationPrefs.reports, ev.payload.value["summary"] as? Bool == true, let taskId = ev.taskId, !taskId.isEmpty else {
+2
View File
@@ -551,6 +551,7 @@ final class Store {
try await self.loadInbox()
}
case "inbox.updated":
clearInbox(try! decodePayload(ev.payload, as: InboxItem.self))
spawn("load inbox") {
try await self.loadInbox()
}
@@ -566,6 +567,7 @@ final class Store {
case "summary.read":
if let taskId = ev.payload.value["task_id"] as? String, let seq = ev.payload.value["seq"] as? Int {
_ = noteSummaryRead(taskId, Int64(seq))
clearTurns(taskId, through: Int64(seq))
}
case "focus.updated":
if ev.actor != me?.login {