import Foundation import GRDB import Martin extension Message { static func map(_ martinMessage: Martin.Message, context: Martin.Context?) -> Message? { // Check that the message type is supported var martinMessage = martinMessage let chatTypes: [StanzaType] = [.chat, .groupchat] guard let mType = martinMessage.type, chatTypes.contains(mType) else { #if DEBUG print("Unsupported martinMessage type: \(martinMessage.type?.rawValue ?? "nil")") #endif return nil } // Type let type = MessageType(rawValue: martinMessage.type?.rawValue ?? "") ?? .chat // Content type var contentType: MessageContentType = .text if let oob = martinMessage.oob { contentType = .attachment(.init( type: oob.attachmentType, localName: nil, thumbnailName: nil, remotePath: oob )) } else if martinMessage.hints.contains(.noStore) { contentType = .typing // skip for now return nil } // Try to recognize if message is omemo-encoded and decode it var secure = false if let omemo = context?.module(.omemo) { let decodingResult = omemo.decode(message: martinMessage) switch decodingResult { case .successMessage(let decodedMessage, _): martinMessage = decodedMessage if let oob = martinMessage.oob { contentType = .attachment(.init( type: oob.attachmentType, localName: nil, thumbnailName: nil, remotePath: oob )) } secure = true case .successTransportKey: break case .failure(let error): logIt(.error, "Error decoding omemo message: \(error)") logIt(.error, "Message: \(martinMessage)") } } // skip for non-visible messages if martinMessage.body == nil, martinMessage.oob == nil, martinMessage.type == .chat { return nil } // From/To let from = martinMessage.from?.bareJid.stringValue ?? "" let to = martinMessage.to?.bareJid.stringValue // Msg let msg = Message( id: martinMessage.id ?? UUID().uuidString, type: type, date: Date(), contentType: contentType, status: .sent, from: from, to: to, body: martinMessage.body, subject: martinMessage.subject, thread: martinMessage.thread, oobUrl: martinMessage.oob, secure: secure ) return msg } }