another.im-ios/Monal/another.im/XMPP/Wrappers/WrapperXMPP.swift

158 lines
5.5 KiB
Swift
Raw Normal View History

2024-11-19 12:59:22 +00:00
import Foundation
import monalxmpp
2024-11-29 17:35:20 +00:00
enum AccountsAvailability {
case noAccounts
case allDisabled
case someEnabled
}
2024-12-02 15:50:23 +00:00
final class WrapperXMPP: ObservableObject {
2024-11-21 16:03:55 +00:00
@Published private(set) var accountsAvailability: AccountsAvailability = .noAccounts
@Published private(set) var accounts: [Account] = []
@Published private(set) var contacts: [Contact] = []
2024-11-23 16:23:56 +00:00
@Published private(set) var activeChats: [Chat] = []
2024-11-19 12:59:22 +00:00
2024-11-20 15:52:49 +00:00
private let xmpp: MLXMPPManager
private let db: DataLayer
2024-11-19 12:59:22 +00:00
2024-11-21 16:03:55 +00:00
private var notificationObservers: [AnyObject] = []
2024-11-19 12:59:22 +00:00
init() {
2024-11-21 13:32:38 +00:00
// init monalxmpp components
xmpp = MLXMPPManager.sharedInstance()
db = DataLayer.sharedInstance()
2024-11-21 16:03:55 +00:00
// subscribe to monalxmpp notifications and fire notification for update
subscribeToUpdates()
2024-12-04 15:00:37 +00:00
processOnStart()
// xmpp.reconnectAll()
// NotificationCenter.default.post(name: Notification.Name(kMonalRefresh), object: nil)
2024-11-21 16:03:55 +00:00
}
deinit {
notificationObservers.forEach { NotificationCenter.default.removeObserver($0) }
2024-11-19 12:59:22 +00:00
}
2024-11-22 14:45:38 +00:00
}
2024-11-20 15:52:49 +00:00
2024-11-22 14:45:38 +00:00
// MARK: - Public
2024-12-02 15:50:23 +00:00
extension WrapperXMPP {
2024-11-20 15:52:49 +00:00
func tryLogin(_ login: String, _ password: String) async throws {
2024-11-29 17:43:27 +00:00
let scenario = ScenarioLogIn()
let result = await scenario.tryLogin(login, password)
2024-11-20 15:52:49 +00:00
if !result {
throw AimErrors.loginError
2024-11-19 12:59:22 +00:00
} else {
2024-12-04 15:00:37 +00:00
processOnStart()
2024-11-19 12:59:22 +00:00
}
}
2024-11-22 14:45:38 +00:00
2024-11-22 16:34:56 +00:00
func addContact(contactJid: String, forAccountID: Int) async {
2024-11-22 16:54:07 +00:00
let contact = MLContact.createContact(fromJid: contactJid, andAccountID: NSNumber(value: forAccountID))
xmpp.add(contact)
}
func deleteContact(_ contact: Contact) async throws {
if let mlContact = db.contactList().first(where: { $0.contactJid == contact.contactJid }) {
xmpp.remove(mlContact)
} else {
throw AimErrors.contactRemoveError
2024-11-22 16:34:56 +00:00
}
2024-11-22 14:45:38 +00:00
}
2024-11-23 23:22:07 +00:00
2024-12-02 15:50:23 +00:00
func chat(with: Contact) -> WrapperChat {
2024-11-25 13:14:23 +00:00
// swiftlint:disable:next force_unwrapping
let account = accounts.first { $0.id == with.ownerId }!
2024-12-02 15:50:23 +00:00
let chatModel = WrapperChat(account: account, contact: with, db: db, xmpp: xmpp)
2024-11-23 23:22:07 +00:00
return chatModel
}
2024-11-25 10:51:00 +00:00
2024-12-02 15:50:23 +00:00
func chat(with: Chat) -> WrapperChat? {
2024-11-25 13:14:23 +00:00
guard let account = accounts.first(where: { $0.id == with.accountId }) else { return nil }
2024-11-28 16:34:41 +00:00
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()
refreshChats()
refreshContacts()
contact = contacts.first(where: { $0.ownerId == with.accountId && $0.contactJid == with.participantJid })
}
guard let contact else { return nil }
2024-12-02 15:50:23 +00:00
let chatModel = WrapperChat(account: account, contact: contact, db: db, xmpp: xmpp)
2024-11-25 10:51:00 +00:00
return chatModel
}
2024-11-19 12:59:22 +00:00
}
2024-11-20 15:52:49 +00:00
2024-11-21 16:03:55 +00:00
// MARK: - Handle notifications
2024-12-02 15:50:23 +00:00
private extension WrapperXMPP {
2024-12-04 15:00:37 +00:00
// Subsribe to monalxmpp events
2024-11-21 16:03:55 +00:00
func subscribeToUpdates() {
2024-12-04 15:00:37 +00:00
notificationObservers.append(
NotificationCenter.default.addObserver(forName: Notification.Name(kMonalRefresh), object: nil, queue: .main) { [weak self] notification in
self?.processEvent(kMonalRefresh, notification.object)
}
)
notificationObservers.append(
NotificationCenter.default.addObserver(forName: Notification.Name(kMonalContactRefresh), object: nil, queue: .main) { [weak self] notification in
self?.processEvent(kMonalContactRefresh, notification.object)
}
)
notificationObservers.append(
NotificationCenter.default.addObserver(forName: Notification.Name(kMonalContactRemoved), object: nil, queue: .main) { [weak self] notification in
self?.processEvent(kMonalContactRemoved, notification.object)
}
)
}
2024-11-21 16:03:55 +00:00
2024-12-04 15:00:37 +00:00
// Process monalxmpp events
func processEvent(_ notificationName: String, _ object: Any?) {
print(notificationName, object)
2024-11-22 13:12:09 +00:00
}
2024-11-21 16:03:55 +00:00
2024-12-04 15:00:37 +00:00
// Initital monalxmpp db fetch
func processOnStart() {
// get all accounts and contacts once
2024-11-22 13:12:09 +00:00
let accounts = db.accountList()
.compactMap { dict -> Account? in
guard let dict = dict as? NSDictionary else { return nil }
return Account(dict)
}
self.accounts = accounts
2024-12-04 15:00:37 +00:00
// check if active accounts existed
2024-11-22 13:12:09 +00:00
if accounts.isEmpty {
accountsAvailability = .noAccounts
} else if accounts.filter({ $0.isEnabled }).isEmpty {
accountsAvailability = .allDisabled
} else {
accountsAvailability = .someEnabled
2024-11-21 16:03:55 +00:00
}
2024-11-23 16:23:56 +00:00
2024-12-04 15:00:37 +00:00
// get all contacts
if !accounts.isEmpty {
contacts = db.contactList()
.filter { $0.isSubscribedTo || $0.hasOutgoingContactRequest || $0.isSubscribedFrom }
.filter { !$0.isSelfChat } // removed for now
.compactMap { Contact($0) }
// get active chats
if !contacts.isEmpty {
activeChats = db.activeContacts(withPinned: false)
.compactMap {
guard let contact = $0 as? MLContact else { return nil }
return Chat(contact)
}
2024-11-23 16:23:56 +00:00
}
2024-12-04 15:00:37 +00:00
}
// try reconnect active clients
xmpp.connectIfNecessary()
2024-11-23 16:23:56 +00:00
}
2024-11-21 16:03:55 +00:00
}