66 lines
2.7 KiB
Swift
66 lines
2.7 KiB
Swift
import Combine
|
|
import Foundation
|
|
|
|
final class AccountsMiddleware {
|
|
static let shared = AccountsMiddleware()
|
|
|
|
private lazy var allFeatures: [ServerFeature] = {
|
|
guard
|
|
let url = Bundle.main.url(forResource: "server_features", withExtension: "plist"),
|
|
let data = try? Data(contentsOf: url),
|
|
let loaded = try? PropertyListDecoder().decode([ServerFeature].self, from: data)
|
|
else {
|
|
return []
|
|
}
|
|
return loaded
|
|
}()
|
|
|
|
func middleware(state: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
|
switch action {
|
|
case .databaseAction(.storedAccountsLoaded(let accounts)):
|
|
return Just(.accountsAction(.accountsListUpdated(accounts: accounts)))
|
|
.eraseToAnyPublisher()
|
|
|
|
case .xmppAction(.clientConnectionChanged(let jid, let connectionStatus)):
|
|
return Future<AppAction, Never> { promise in
|
|
guard let account = state.accountsState.accounts.first(where: { $0.bareJid == jid }) else {
|
|
promise(.success(.info("AccountsMiddleware: account not found for jid \(jid)")))
|
|
return
|
|
}
|
|
if account.isTemp {
|
|
switch connectionStatus {
|
|
case .connected:
|
|
promise(.success(.accountsAction(.makeAccountPermanent(account: account))))
|
|
|
|
case .disconnected(let reason):
|
|
if reason != "No error!" {
|
|
promise(.success(.accountsAction(.addAccountError(jid: jid, reason: reason))))
|
|
} else {
|
|
promise(.success(.info("AccountsMiddleware: account \(jid) disconnected with no error")))
|
|
}
|
|
|
|
default:
|
|
promise(.success(.info("AccountsMiddleware: account \(jid) connection status changed to \(connectionStatus)")))
|
|
}
|
|
} else {
|
|
promise(.success(.info("AccountsMiddleware: account \(jid) is not temporary, ignoring")))
|
|
}
|
|
}
|
|
.eraseToAnyPublisher()
|
|
|
|
case .xmppAction(.serverFeaturesLoaded(let jid, let features)):
|
|
return Future<AppAction, Never> { [weak self] promise in
|
|
let serverFeatures = features
|
|
.compactMap { featureId in
|
|
self?.allFeatures.first(where: { $0.xmppId == featureId })
|
|
}
|
|
promise(.success(.accountsAction(.clientServerFeaturesUpdated(jid: jid, features: serverFeatures))))
|
|
}
|
|
.eraseToAnyPublisher()
|
|
|
|
default:
|
|
return Empty().eraseToAnyPublisher()
|
|
}
|
|
}
|
|
}
|