another.im-ios/ConversationsClassic/AppData/Stores/RostersStore.swift

120 lines
4.4 KiB
Swift
Raw Normal View History

2024-08-11 00:28:01 +00:00
import Combine
import Foundation
import GRDB
@MainActor
final class RostersStore: ObservableObject {
@Published private(set) var rosters: [Roster] = []
2024-08-11 17:07:02 +00:00
@Published private(set) var locallyDeletedRosters: [Roster] = []
2024-08-11 00:28:01 +00:00
2024-08-11 11:39:17 +00:00
private var cancellable: AnyCancellable?
2024-08-11 19:01:48 +00:00
init() {
2024-08-11 11:39:17 +00:00
let rostersPublisher = ValueObservation.tracking(Roster.fetchAll)
.publisher(in: Database.shared.dbQueue)
.receive(on: DispatchQueue.main)
.catch { _ in Just([]) }
2024-08-11 19:01:48 +00:00
cancellable = ClientsStore.shared.$clients
2024-08-11 17:07:02 +00:00
.map { $0.filter { $0.state != .disabled } } // look rosters only for enabled clients
2024-08-11 11:39:17 +00:00
.flatMap { clients in
Publishers.MergeMany(clients.map { $0.$state })
.prepend(clients.map { $0.state })
.collect()
}
.combineLatest(rostersPublisher)
.sink { [weak self] clientStates, rosters in
self?.handleUpdates(clientStates: clientStates, rosters: rosters)
}
}
private func handleUpdates(clientStates: [ClientState], rosters: [Roster]) {
2024-08-11 17:07:02 +00:00
self.rosters = rosters.filter { !$0.locallyDeleted }
locallyDeletedRosters = rosters.filter { $0.locallyDeleted }
2024-08-11 11:39:17 +00:00
print("Client States: \(clientStates.count), Rosters: \(rosters.count)")
2024-08-11 00:28:01 +00:00
}
}
2024-08-11 17:07:02 +00:00
extension RostersStore {
enum RosterAddResult {
case success
case connectionError
case serverError
}
2024-08-11 19:01:48 +00:00
func addRoster(_ owner: Credentials, contactJID: String, name _: String?, groups _: [String]) async -> RosterAddResult {
2024-08-11 17:07:02 +00:00
// check if such roster was already exists or locally deleted
2024-08-11 19:01:48 +00:00
if var exists = rosters.first(where: { $0.bareJid == owner.bareJid && $0.contactBareJid == contactJID }), exists.locallyDeleted {
2024-08-11 17:07:02 +00:00
try? await exists.setLocallyDeleted(false)
return .success
}
// add new roster
// check that client is enabled and connected
2024-08-11 19:01:48 +00:00
let clientStorage = ClientsStore.shared
while !clientStorage.ready {
await Task.yield()
}
print("!! Clients: \(clientStorage.clients.count)")
guard let client = clientStorage.clients.first(where: { $0.credentials == owner }) else {
2024-08-11 17:07:02 +00:00
return .connectionError
}
2024-08-11 19:01:48 +00:00
guard client.state == .enabled(.connected) else {
return .connectionError
}
// guard let client = ClientsStore.shared.clients.first(where: { $0.credentials == owner }), client.state == .enabled(.connected) else {
// return .connectionError
// }
2024-08-11 17:07:02 +00:00
// add roster
do {
try await client.addRoster(contactJID, name: nil, groups: [])
return .success
} catch {
return .serverError
}
// guard let client = clientsStore.clients.first(where: { $0.credentials == ownerCredentials }), client.state == .enabled(.connected) else {
// router.showAlert(
// .alert,
// title: L10n.Global.Error.title,
// subtitle: L10n.Contacts.Add.connectionError
// ) {
// Button(L10n.Global.ok, role: .cancel) {}
// }
// return
// }
//
// router.showModal {
// LoadingScreen()
// }
//
// do {
// try await client.addRoster(contactJID, name: nil, groups: [])
// } catch {
// router.showAlert(
// .alert,
// title: L10n.Global.Error.title,
// subtitle: L10n.Contacts.Add.serverError
// ) {
// Button(L10n.Global.ok, role: .cancel) {}
// }
// return
// }
//
// router.dismissModal()
// router.dismissScreen()
// client.addRoster(jid: )
// guard let ownerAccount else { return }
// if let exists = store.state.rostersState.rosters.first(where: { $0.bareJid == ownerAccount.bareJid && $0.contactBareJid == contactJID }), exists.locallyDeleted {
// store.dispatch(.rostersAction(.unmarkRosterAsLocallyDeleted(ownerJID: ownerAccount.bareJid, contactJID: contactJID)))
// isPresented = false
// } else {
// isShowingLoader = true
// store.dispatch(.rostersAction(.addRoster(ownerJID: ownerAccount.bareJid, contactJID: contactJID, name: nil, groups: [])))
// }
}
}