wip
This commit is contained in:
parent
7bb48e8719
commit
6ce16b1f3b
|
@ -7,4 +7,6 @@ enum AccountsAction: Codable {
|
|||
case addAccountError(jid: String, reason: String?)
|
||||
|
||||
case makeAccountPermanent(account: Account)
|
||||
|
||||
case clientServerFeaturesUpdated(jid: String, features: [ServerFeature])
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ enum XMPPAction: Codable {
|
|||
case xmppSharingTryUpload(Message)
|
||||
case xmppSharingUploadFailed(msgId: String, reason: String)
|
||||
case xmppSharingUploadSuccess(msgId: String, attachmentRemotePath: String)
|
||||
case serverFeaturesLoaded(jid: String, features: [String])
|
||||
}
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
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)):
|
||||
|
@ -36,6 +48,16 @@ final class AccountsMiddleware {
|
|||
}
|
||||
.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.xep == featureId })
|
||||
}
|
||||
promise(.success(.accountsAction(.clientServerFeaturesUpdated(jid: jid, features: serverFeatures))))
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
default:
|
||||
return Empty().eraseToAnyPublisher()
|
||||
}
|
||||
|
|
|
@ -26,6 +26,14 @@ final class XMPPMiddleware {
|
|||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
service.clientFeatures.sink { client, features in
|
||||
let jid = client.userBareJid.stringValue
|
||||
DispatchQueue.main.async {
|
||||
store.dispatch(.xmppAction(.serverFeaturesLoaded(jid: jid, features: features)))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func middleware(state: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
||||
|
|
43
ConversationsClassic/AppCore/Models/ServerFeature.swift
Normal file
43
ConversationsClassic/AppCore/Models/ServerFeature.swift
Normal file
|
@ -0,0 +1,43 @@
|
|||
import Foundation
|
||||
|
||||
struct ServerFeature: Stateable, Identifiable {
|
||||
let xep: String
|
||||
let name: String
|
||||
let xmppId: String?
|
||||
let description: String?
|
||||
|
||||
var id: String { xep }
|
||||
}
|
||||
|
||||
// <feature id="">
|
||||
// <xep>XEP-0001</xep>
|
||||
// <name>XMPP Extension Protocols</name>
|
||||
// <type>Procedural</type>
|
||||
// <status>Active</status>
|
||||
// <date>2016-11-16</date>
|
||||
// <description/>
|
||||
// </feature>
|
||||
// <feature id="">
|
||||
// <xep>XEP-0002</xep>
|
||||
// <name>Special Interest Groups (SIGs)</name>
|
||||
// <type>Procedural</type>
|
||||
// <status>Active</status>
|
||||
// <date>2002-01-11</date>
|
||||
// <description/>
|
||||
// </feature>
|
||||
// <feature id="jabber:iq:pass">
|
||||
// <xep>XEP-0003</xep>
|
||||
// <name>Proxy Accept Socket Service (PASS)</name>
|
||||
// <type>Historical</type>
|
||||
// <status>Obsolete</status>
|
||||
// <date>2009-06-03</date>
|
||||
// <description/>
|
||||
// </feature>
|
||||
// <feature id="">
|
||||
// <xep>XEP-0004</xep>
|
||||
// <name>Data Forms</name>
|
||||
// <type>Standards Track</type>
|
||||
// <status>Final</status>
|
||||
// <date>2007-08-13</date>
|
||||
// <description/>
|
||||
// </feature>
|
|
@ -15,6 +15,10 @@ extension AccountsState {
|
|||
state.accounts = state.accounts.filter { $0.bareJid != jid }
|
||||
state.addAccountError = reason
|
||||
|
||||
case .clientServerFeaturesUpdated(let jid, let features):
|
||||
state.discoFeatures[jid] = features
|
||||
print(features)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ enum AccountNavigationState: Stateable {
|
|||
struct AccountsState: Stateable {
|
||||
var navigation: AccountNavigationState
|
||||
var accounts: [Account]
|
||||
var discoFeatures: [String: [ServerFeature]]
|
||||
|
||||
var addAccountError: String?
|
||||
}
|
||||
|
@ -14,5 +15,6 @@ extension AccountsState {
|
|||
init() {
|
||||
navigation = .addAccount
|
||||
accounts = []
|
||||
discoFeatures = [:]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@ final class XMPPService: ObservableObject {
|
|||
private let manager: MartinsManager
|
||||
private let clientStatePublisher = PassthroughSubject<(XMPPClient, XMPPClient.State), Never>()
|
||||
private let clientMessagesPublisher = PassthroughSubject<(XMPPClient, Martin.Message), Never>()
|
||||
private let clientFeaturesPublisher = PassthroughSubject<(XMPPClient, [String]), Never>()
|
||||
private var clientStateCancellables: Set<AnyCancellable> = []
|
||||
private var clientMessagesCancellables: Set<AnyCancellable> = []
|
||||
private var clientFeaturesCancellables: Set<AnyCancellable> = []
|
||||
|
||||
@Published private(set) var clients: [XMPPClient] = []
|
||||
var clientState: AnyPublisher<(XMPPClient, XMPPClient.State), Never> {
|
||||
|
@ -21,6 +23,10 @@ final class XMPPService: ObservableObject {
|
|||
clientMessagesPublisher.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
var clientFeatures: AnyPublisher<(XMPPClient, [String]), Never> {
|
||||
clientFeaturesPublisher.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(manager: MartinsManager) {
|
||||
self.manager = manager
|
||||
}
|
||||
|
@ -46,6 +52,13 @@ final class XMPPService: ObservableObject {
|
|||
}
|
||||
.store(in: &clientStateCancellables)
|
||||
|
||||
// subscribe to client server features
|
||||
client.module(DiscoveryModule.self).$serverDiscoResult
|
||||
.sink { [weak self] disco in
|
||||
self?.clientFeaturesPublisher.send((client, disco.features))
|
||||
}
|
||||
.store(in: &clientFeaturesCancellables)
|
||||
|
||||
// subscribe to client messages
|
||||
client.module(MessageModule.self).messagesPublisher
|
||||
.sink { [weak self] message in
|
||||
|
@ -80,9 +93,11 @@ final class XMPPService: ObservableObject {
|
|||
|
||||
client.modulesManager.register(PubSubModule())
|
||||
client.modulesManager.register(MessageModule(chatManager: manager))
|
||||
client.modulesManager.register(MessageCarbonsModule())
|
||||
client.modulesManager.register(MessageArchiveManagementModule())
|
||||
|
||||
client.modulesManager.register(MessageCarbonsModule())
|
||||
client.module(.messageCarbons).enable()
|
||||
|
||||
// file transfer modules
|
||||
client.modulesManager.register(HttpFileUploadModule())
|
||||
|
||||
|
@ -160,8 +175,8 @@ final class XMPPService: ObservableObject {
|
|||
switch res {
|
||||
case .success(let slot):
|
||||
var request = URLRequest(url: slot.putUri)
|
||||
for (k, v) in slot.putHeaders {
|
||||
request.addValue(v, forHTTPHeaderField: k)
|
||||
for (key, value) in slot.putHeaders {
|
||||
request.addValue(value, forHTTPHeaderField: key)
|
||||
}
|
||||
request.httpMethod = "PUT"
|
||||
request.httpBody = data
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,8 +16,10 @@ struct AddAccountScreen: View {
|
|||
@State private var isShowingLoader = false
|
||||
|
||||
#if DEBUG
|
||||
@State private var jidStr: String = "test1@test.anal.company"
|
||||
@State private var pass: String = "12345"
|
||||
@State private var jidStr: String = "nartest1@conversations.im"
|
||||
@State private var pass: String = "nartest12345"
|
||||
// @State private var jidStr: String = "test1@test.anal.company"
|
||||
// @State private var pass: String = "12345"
|
||||
#else
|
||||
@State private var jidStr: String = ""
|
||||
@State private var pass: String = ""
|
||||
|
|
Loading…
Reference in a new issue