Add iOS notification scheduler
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import AVFoundation
|
import AVFoundation
|
||||||
|
|
||||||
|
#if canImport(UserNotifications)
|
||||||
|
import UserNotifications
|
||||||
|
#endif
|
||||||
|
|
||||||
#if canImport(UIKit)
|
#if canImport(UIKit)
|
||||||
import UIKit
|
import UIKit
|
||||||
#endif
|
#endif
|
||||||
@@ -62,6 +66,49 @@ public protocol NotificationScheduling: Sendable {
|
|||||||
func schedule(chat: ChatSummary, message: Message) async throws
|
func schedule(chat: ChatSummary, message: Message) async throws
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct SystemNotificationScheduler: NotificationScheduling {
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public func schedule(chat: ChatSummary, message: Message) async throws {
|
||||||
|
#if canImport(UserNotifications)
|
||||||
|
let content = UNMutableNotificationContent()
|
||||||
|
content.title = chat.title
|
||||||
|
content.body = "\(message.senderName): \(message.text)"
|
||||||
|
content.sound = .default
|
||||||
|
|
||||||
|
let request = UNNotificationRequest(
|
||||||
|
identifier: "chat-\(chat.id)-message-\(message.id)",
|
||||||
|
content: content,
|
||||||
|
trigger: nil
|
||||||
|
)
|
||||||
|
try await UNUserNotificationCenter.current().add(request)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct NotificationCoordinator: Sendable {
|
||||||
|
public var policy: NotificationPolicy
|
||||||
|
public var scheduler: NotificationScheduling
|
||||||
|
public var mentionOnly: Bool
|
||||||
|
|
||||||
|
public init(
|
||||||
|
policy: NotificationPolicy = NotificationPolicy(),
|
||||||
|
scheduler: NotificationScheduling,
|
||||||
|
mentionOnly: Bool = false
|
||||||
|
) {
|
||||||
|
self.policy = policy
|
||||||
|
self.scheduler = scheduler
|
||||||
|
self.mentionOnly = mentionOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
public func handle(chat: ChatSummary, message: Message) async throws {
|
||||||
|
guard policy.shouldNotify(chat: chat, message: message, mentionOnly: mentionOnly) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try await scheduler.schedule(chat: chat, message: message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public actor RecordingNotificationScheduler: NotificationScheduling {
|
public actor RecordingNotificationScheduler: NotificationScheduling {
|
||||||
public private(set) var scheduled: [(ChatSummary, Message)] = []
|
public private(set) var scheduled: [(ChatSummary, Message)] = []
|
||||||
|
|
||||||
@@ -70,6 +117,10 @@ public actor RecordingNotificationScheduler: NotificationScheduling {
|
|||||||
public func schedule(chat: ChatSummary, message: Message) async throws {
|
public func schedule(chat: ChatSummary, message: Message) async throws {
|
||||||
scheduled.append((chat, message))
|
scheduled.append((chat, message))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func scheduledCount() -> Int {
|
||||||
|
scheduled.count
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol URLOpening: Sendable {
|
public protocol URLOpening: Sendable {
|
||||||
|
|||||||
@@ -161,6 +161,17 @@ struct TeleTuiIOSSmokeTests {
|
|||||||
precondition(policy.shouldNotify(chat: chat, message: incomingMention, mentionOnly: true))
|
precondition(policy.shouldNotify(chat: chat, message: incomingMention, mentionOnly: true))
|
||||||
precondition(!policy.shouldNotify(chat: chat, message: incomingPlain, mentionOnly: true))
|
precondition(!policy.shouldNotify(chat: chat, message: incomingPlain, mentionOnly: true))
|
||||||
precondition(!policy.shouldNotify(chat: muted, message: incomingMention, mentionOnly: false))
|
precondition(!policy.shouldNotify(chat: muted, message: incomingMention, mentionOnly: false))
|
||||||
|
let scheduler = RecordingNotificationScheduler()
|
||||||
|
let mentionCoordinator = NotificationCoordinator(scheduler: scheduler, mentionOnly: true)
|
||||||
|
try await mentionCoordinator.handle(chat: chat, message: incomingPlain)
|
||||||
|
var scheduledCount = await scheduler.scheduledCount()
|
||||||
|
precondition(scheduledCount == 0)
|
||||||
|
try await mentionCoordinator.handle(chat: chat, message: incomingMention)
|
||||||
|
scheduledCount = await scheduler.scheduledCount()
|
||||||
|
precondition(scheduledCount == 1)
|
||||||
|
try await mentionCoordinator.handle(chat: muted, message: incomingMention)
|
||||||
|
scheduledCount = await scheduler.scheduledCount()
|
||||||
|
precondition(scheduledCount == 1)
|
||||||
|
|
||||||
let clipboard = InMemoryClipboardWriter()
|
let clipboard = InMemoryClipboardWriter()
|
||||||
await clipboard.write(text: "copied")
|
await clipboard.write(text: "copied")
|
||||||
|
|||||||
Reference in New Issue
Block a user