import Foundation import UserNotifications import UIKit /// Surfaces WS events as local notifications while the app has an active /// session (foregrounded or background-grace). APNs push lands at v1.1. @MainActor enum NotificationCenterBridge { static func requestAuthorizationIfNeeded() async { let center = UNUserNotificationCenter.current() let current = await center.notificationSettings() guard current.authorizationStatus == .notDetermined else { return } _ = try? await center.requestAuthorization(options: [.alert, .badge, .sound]) } static func notifyTaskStatus(taskId: String, taskName: String, status: String) { let status = status.lowercased() let (title, body): (String?, String?) = { switch status { case "done", "completed": return ("TASK COMPLETED", "\(taskName) is done.") case "failed", "error": return ("TASK FAILED", "\(taskName) stopped with an error.") case "blocked": return ("TASK BLOCKED", "\(taskName) needs your input.") default: return (nil, nil) } }() guard let title, let body else { return } let content = UNMutableNotificationContent() content.title = title content.body = body content.sound = .default content.userInfo = ["deepLink": "makima://task/\(taskId)"] let request = UNNotificationRequest( identifier: "task-\(taskId)-\(status)", content: content, trigger: nil ) UNUserNotificationCenter.current().add(request) } static func notifyDirectiveQuestion(directiveId: String, title: String) { let content = UNMutableNotificationContent() content.title = "DIRECTIVE QUESTION" content.body = "\(title) needs your answer." content.sound = .default content.userInfo = ["deepLink": "makima://directive/\(directiveId)"] let request = UNNotificationRequest( identifier: "directive-\(directiveId)", content: content, trigger: nil ) UNUserNotificationCenter.current().add(request) } }