another.im-ios/ConversationsClassic/AppData/Client/Client+MartinMAM.swift

80 lines
2.4 KiB
Swift
Raw Normal View History

2024-08-18 17:20:55 +00:00
import Combine
import Foundation
import GRDB
import Martin
2024-08-19 02:47:56 +00:00
private typealias ArchMsg = Martin.MessageArchiveManagementModule.ArchivedMessageReceived
2024-08-18 17:20:55 +00:00
final class ClientMartinMAM {
private var cancellables: Set<AnyCancellable> = []
2024-08-19 02:47:56 +00:00
private var processor = ArchiveMessageProcessor()
2024-08-18 17:20:55 +00:00
init(_ xmppConnection: XMPPClient) {
// subscribe to archived messages
2024-08-19 02:47:56 +00:00
xmppConnection.module(.mam).archivedMessagesPublisher
2024-08-18 17:20:55 +00:00
.sink(receiveValue: { [weak self] archived in
2024-08-18 20:27:12 +00:00
guard let self = self else { return }
Task {
2024-08-19 02:47:56 +00:00
await self.processor.append(archived)
2024-08-18 20:27:12 +00:00
}
2024-08-18 17:20:55 +00:00
})
.store(in: &cancellables)
}
2024-08-19 02:47:56 +00:00
}
private actor ArchiveMessageProcessor {
private var accumulator: [ArchMsg] = []
init() {
Task {
while true {
try? await Task.sleep(nanoseconds: 700 * NSEC_PER_MSEC)
await process()
}
}
}
2024-08-18 17:20:55 +00:00
2024-08-19 02:47:56 +00:00
func append(_ msg: ArchMsg) async {
accumulator.append(msg)
if accumulator.count >= Const.mamRequestLimit {
await process()
}
}
func process() async {
if accumulator.isEmpty { return }
await handleMessages(accumulator)
accumulator.removeAll()
}
2024-08-18 17:20:55 +00:00
2024-08-19 02:47:56 +00:00
private func handleMessages(_ received: [ArchMsg]) async {
if received.isEmpty { return }
2024-08-19 02:38:06 +00:00
try? await Database.shared.dbQueue.write { db in
2024-08-19 02:47:56 +00:00
for recv in received {
let message = recv.message
let date = recv.timestamp
if let msgId = message.id {
if try Message.fetchOne(db, key: msgId) != nil {
#if DEBUG
print("---")
print("Skipping archived message with id \(msgId) (message exists)")
print("---")
#endif
} else {
#if DEBUG
print("---")
print("Archive message received: \(message)")
print("Date: \(date)")
print("---")
#endif
if var msg = Message.map(message) {
msg.date = date
try msg.insert(db)
}
}
2024-08-18 17:20:55 +00:00
}
}
}
}
}