import Combine import Foundation import GRDB import Martin final class ClientMartinMessagesManager { private var cancellable: AnyCancellable? init(_ xmppConnection: XMPPClient) { cancellable = xmppConnection.module(MessageModule.self).messagesPublisher .sink { [weak self] message in self?.handleClientMessage(message) } } private func handleClientMessage(_ received: MessageModule.MessageReceived) { let message = received.message let chat = received.chat #if DEBUG print("---") print("Message received: \(message)") print("In chat: \(chat)") print("---") #endif // Check that the message type is supported let chatTypes: [StanzaType] = [.chat, .groupchat] guard let mType = message.type, chatTypes.contains(mType) else { #if DEBUG print("Unsupported message type: \(message.type?.rawValue ?? "nil")") #endif return } // Type let type = MessageType(rawValue: message.type?.rawValue ?? "") ?? .chat // Content type var contentType: MessageContentType = .text if let oob = message.oob { contentType = .attachment(.init( type: oob.attachmentType, localName: nil, thumbnailName: nil, remotePath: oob )) } else if message.hints.contains(.noStore) { contentType = .typing // skip for now return } // From/To let from = message.from?.bareJid.stringValue ?? "" let to = message.to?.bareJid.stringValue // Extract date or set current var date = Date() if let timestampStr = message.attribute("archived_date"), let timeInterval = TimeInterval(timestampStr) { date = Date(timeIntervalSince1970: timeInterval) } // Msg let msg = Message( id: message.id ?? UUID().uuidString, type: type, date: date, contentType: contentType, status: .sent, from: from, to: to, body: message.body, subject: message.subject, thread: message.thread, oobUrl: message.oob ) // Save message Task { do { try await msg.save() } catch { logIt(.error, "Error saving message: \(error)") } } } }