import Combine import Foundation import GRDB import Martin final class ClientMartinMAM { private var cancellables: Set = [] private weak var module: MessageArchiveManagementModule? private var afterAvailable = true private var beforeAvailable = true init(_ xmppConnection: XMPPClient) { module = xmppConnection.module(.mam) subscribe() } private func subscribe() { // subscribe to archived messages module?.archivedMessagesPublisher .delay(for: 0.7, scheduler: DispatchQueue.main) .sink(receiveValue: { [weak self] archived in guard let self = self else { return } Task { await self.handleMessage(archived) } }) .store(in: &cancellables) } private func handleMessage(_ received: Martin.MessageArchiveManagementModule.ArchivedMessageReceived) async { let message = received.message let date = received.timestamp #if DEBUG print("---") print("Archive message received: \(message)") print("Date: \(date)") print("---") #endif // Skip archived message if such message already exists in the database if let archiveId = message.id { try? await Database.shared.dbQueue.read { db in if try Message.fetchOne(db, key: archiveId) != nil { return } } } if let msg = Message.map(message) { do { var msg = msg msg.date = received.timestamp try await msg.save() } catch { logIt(.error, "Error saving message: \(error)") } } } }