import Foundation import monalxmpp enum AccountsAvailability { case noAccounts case allDisabled case someEnabled } final class MonalXmppWrapper: ObservableObject { @Published var accountsAvailability: AccountsAvailability = .noAccounts private let xmpp: MLXMPPManager private let db: DataLayer init() { // here is some inits (just for now) MLProcessLock.initialize(forProcess: "MainApp") // init monalxmpp components xmpp = MLXMPPManager.sharedInstance() db = DataLayer.sharedInstance() checkAccountsOnLoad() } // try login func tryLogin(_ login: String, _ password: String) async throws { let loginObject = LoginTry(xmpp: xmpp) let result = await loginObject.tryLogin(login, password) if !result { throw AimErrors.loginError } } func reconnectAll() { xmpp.reconnectAll() } } // MARK: - Accounts private extension MonalXmppWrapper { // Check accounts state on launch func checkAccountsOnLoad() { let enabledAcocunts = db.enabledAccountList() let allAccounts = db.accountList() if allAccounts.isEmpty { accountsAvailability = .noAccounts } else if !enabledAcocunts.isEmpty { accountsAvailability = .someEnabled } else { accountsAvailability = .allDisabled } } } // MARK: - Try login from Login screen private final class LoginTry { weak var xmpp: MLXMPPManager? var successObserver: AnyObject? var failureObserver: AnyObject? init(xmpp: MLXMPPManager) { self.xmpp = xmpp } // TODO: Добавить автовключение отключенных аккаунтов при попытке ввести тот же JID // Обработать кейс когда бесячий monalxmpp возвращает nil при попытке добавить тот же JID func tryLogin(_ login: String, _ password: String) async -> Bool { async let notify = await withCheckedContinuation { [weak self] continuation in self?.successObserver = NotificationCenter.default.addObserver(forName: Notification.Name("kMLResourceBoundNotice"), object: nil, queue: .main) { notification in print(notification.debugDescription) continuation.resume(returning: true) } self?.failureObserver = NotificationCenter.default.addObserver(forName: Notification.Name("kXMPPError"), object: nil, queue: .main) { notification in print(notification.debugDescription) continuation.resume(returning: false) } } defer { if let successObserver { NotificationCenter.default.removeObserver(successObserver) } if let failureObserver { NotificationCenter.default.removeObserver(failureObserver) } } let accountNumber = xmpp?.login(login, password: password) let result = await notify if let accountNumber, !result { xmpp?.removeAccount(forAccountID: accountNumber) } return result } }