import Foundation import monalxmpp final class WrapperChat: ObservableObject { @Published private(set) var messages: [Message] = [] @Published var replyText: String = "" @Published private(set) var mamRequestInProgress = false @Published var isOmemoEnabled: Bool { didSet { toggleOmemo(isOmemoEnabled) } } let contact: Contact private let xmpp: MLXMPPManager private let db: DataLayer private let monalContact: MLContact private var notificationObservers: [AnyObject] = [] init?(with: Contact) { contact = with xmpp = MLXMPPManager.sharedInstance() db = DataLayer.sharedInstance() guard let monalContact = db.contactList() .first(where: { $0.accountID.intValue == with.ownerId }) else { return nil } self.monalContact = monalContact isOmemoEnabled = monalContact.isEncrypted subscribe() NotificationCenter.default.post(name: Notification.Name(kMonalNewMessageNotice), object: nil) } init?(with: Chat) { xmpp = MLXMPPManager.sharedInstance() db = DataLayer.sharedInstance() guard let monalContact = db.contactList() .first(where: { $0.accountID.intValue == with.accountId }) else { return nil } self.monalContact = monalContact isOmemoEnabled = monalContact.isEncrypted guard let contact = Contact(monalContact) else { return nil } self.contact = contact subscribe() NotificationCenter.default.post(name: Notification.Name(kMonalNewMessageNotice), object: nil) // guard let account = accounts.first(where: { $0.id == with.accountId }) else { return nil } // // var contact = contacts.first(where: { $0.ownerId == with.accountId && $0.contactJid == with.participantJid }) // if contact == nil { // let semaphore = DispatchSemaphore(value: 0) // Task { // await addContact(contactJid: with.participantJid, forAccountID: with.accountId) // semaphore.signal() // } // semaphore.wait() // contact = contacts.first(where: { $0.ownerId == with.accountId && $0.contactJid == with.participantJid }) // } // // guard let contact else { return nil } // let chatModel = WrapperChat(account: account, contact: contact, db: db, xmpp: xmpp) // return chatModel } // init(account: Account, contact: Contact, db: DataLayer, xmpp: MLXMPPManager) { // self.contact = contact // self.account = account // self.db = db // self.xmpp = xmpp // // monalContact = db.contactList().first { $0.accountID.intValue == contact.ownerId && $0.contactJid == contact.contactJid }! // isOmemoEnabled = monalContact.isEncrypted // // subscribe() // NotificationCenter.default.post(name: Notification.Name(kMonalNewMessageNotice), object: nil) // // // // } deinit { notificationObservers.forEach { NotificationCenter.default.removeObserver($0) } } var chatTitle: String { contact.name } func sendText(_ text: String) { let newMessageId = UUID().uuidString _ = db.addMessageHistory( to: contact.contactJid, forAccount: monalContact.accountID, withMessage: text, // MARK: WARNING! actuallyFrom: "testmon3@test.anal.company", withId: newMessageId, encrypted: monalContact.isEncrypted, messageType: kMessageTypeText, mimeType: nil, size: nil ) print(newMessageId) xmpp.sendMessage(text, to: monalContact, isEncrypted: monalContact.isEncrypted, isUpload: false, messageId: newMessageId) } func requestMAM() { guard let acc = monalContact.account else { return } if mamRequestInProgress { return } mamRequestInProgress = true let lastStanzaId = messages.last?.stanzaId // last here because list is reversed ?? db.lastStanzaId(forAccount: NSNumber(value: contact.ownerId)) acc.setMAMQueryMostRecentFor(monalContact, before: lastStanzaId) { [weak self] msgs, _ in DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in self?.mamRequestInProgress = false if !(msgs ?? []).isEmpty { self?.refreshMessages() } } } } } private extension WrapperChat { func subscribe() { let newMsg = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalNewMessageNotice), object: nil, queue: .main) { [weak self] _ in self?.refreshMessages() } notificationObservers.append(newMsg) let sentMsg = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalSentMessageNotice), object: nil, queue: .main) { [weak self] _ in self?.refreshMessages() } notificationObservers.append(sentMsg) } func refreshMessages() { let messages = db.messages(forContact: contact.contactJid, forAccount: NSNumber(value: contact.ownerId)) .compactMap { obj -> Message? in guard let message = obj as? MLMessage else { return nil } return Message(message) } .sorted { $0.timestamp > $1.timestamp } self.messages = messages } func toggleOmemo(_ new: Bool) { if monalContact.isEncrypted != new { monalContact.toggleEncryption(new) } } }