wip
This commit is contained in:
parent
7bb48e8719
commit
6ce16b1f3b
|
@ -7,4 +7,6 @@ enum AccountsAction: Codable {
|
||||||
case addAccountError(jid: String, reason: String?)
|
case addAccountError(jid: String, reason: String?)
|
||||||
|
|
||||||
case makeAccountPermanent(account: Account)
|
case makeAccountPermanent(account: Account)
|
||||||
|
|
||||||
|
case clientServerFeaturesUpdated(jid: String, features: [ServerFeature])
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,5 @@ enum XMPPAction: Codable {
|
||||||
case xmppSharingTryUpload(Message)
|
case xmppSharingTryUpload(Message)
|
||||||
case xmppSharingUploadFailed(msgId: String, reason: String)
|
case xmppSharingUploadFailed(msgId: String, reason: String)
|
||||||
case xmppSharingUploadSuccess(msgId: String, attachmentRemotePath: String)
|
case xmppSharingUploadSuccess(msgId: String, attachmentRemotePath: String)
|
||||||
|
case serverFeaturesLoaded(jid: String, features: [String])
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,20 @@
|
||||||
import Combine
|
import Combine
|
||||||
|
import Foundation
|
||||||
|
|
||||||
final class AccountsMiddleware {
|
final class AccountsMiddleware {
|
||||||
static let shared = 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> {
|
func middleware(state: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
||||||
switch action {
|
switch action {
|
||||||
case .databaseAction(.storedAccountsLoaded(let accounts)):
|
case .databaseAction(.storedAccountsLoaded(let accounts)):
|
||||||
|
@ -36,6 +48,16 @@ final class AccountsMiddleware {
|
||||||
}
|
}
|
||||||
.eraseToAnyPublisher()
|
.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:
|
default:
|
||||||
return Empty().eraseToAnyPublisher()
|
return Empty().eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,14 @@ final class XMPPMiddleware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.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> {
|
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.accounts = state.accounts.filter { $0.bareJid != jid }
|
||||||
state.addAccountError = reason
|
state.addAccountError = reason
|
||||||
|
|
||||||
|
case .clientServerFeaturesUpdated(let jid, let features):
|
||||||
|
state.discoFeatures[jid] = features
|
||||||
|
print(features)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ enum AccountNavigationState: Stateable {
|
||||||
struct AccountsState: Stateable {
|
struct AccountsState: Stateable {
|
||||||
var navigation: AccountNavigationState
|
var navigation: AccountNavigationState
|
||||||
var accounts: [Account]
|
var accounts: [Account]
|
||||||
|
var discoFeatures: [String: [ServerFeature]]
|
||||||
|
|
||||||
var addAccountError: String?
|
var addAccountError: String?
|
||||||
}
|
}
|
||||||
|
@ -14,5 +15,6 @@ extension AccountsState {
|
||||||
init() {
|
init() {
|
||||||
navigation = .addAccount
|
navigation = .addAccount
|
||||||
accounts = []
|
accounts = []
|
||||||
|
discoFeatures = [:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,10 @@ final class XMPPService: ObservableObject {
|
||||||
private let manager: MartinsManager
|
private let manager: MartinsManager
|
||||||
private let clientStatePublisher = PassthroughSubject<(XMPPClient, XMPPClient.State), Never>()
|
private let clientStatePublisher = PassthroughSubject<(XMPPClient, XMPPClient.State), Never>()
|
||||||
private let clientMessagesPublisher = PassthroughSubject<(XMPPClient, Martin.Message), Never>()
|
private let clientMessagesPublisher = PassthroughSubject<(XMPPClient, Martin.Message), Never>()
|
||||||
|
private let clientFeaturesPublisher = PassthroughSubject<(XMPPClient, [String]), Never>()
|
||||||
private var clientStateCancellables: Set<AnyCancellable> = []
|
private var clientStateCancellables: Set<AnyCancellable> = []
|
||||||
private var clientMessagesCancellables: Set<AnyCancellable> = []
|
private var clientMessagesCancellables: Set<AnyCancellable> = []
|
||||||
|
private var clientFeaturesCancellables: Set<AnyCancellable> = []
|
||||||
|
|
||||||
@Published private(set) var clients: [XMPPClient] = []
|
@Published private(set) var clients: [XMPPClient] = []
|
||||||
var clientState: AnyPublisher<(XMPPClient, XMPPClient.State), Never> {
|
var clientState: AnyPublisher<(XMPPClient, XMPPClient.State), Never> {
|
||||||
|
@ -21,6 +23,10 @@ final class XMPPService: ObservableObject {
|
||||||
clientMessagesPublisher.eraseToAnyPublisher()
|
clientMessagesPublisher.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clientFeatures: AnyPublisher<(XMPPClient, [String]), Never> {
|
||||||
|
clientFeaturesPublisher.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(manager: MartinsManager) {
|
init(manager: MartinsManager) {
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
}
|
}
|
||||||
|
@ -46,6 +52,13 @@ final class XMPPService: ObservableObject {
|
||||||
}
|
}
|
||||||
.store(in: &clientStateCancellables)
|
.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
|
// subscribe to client messages
|
||||||
client.module(MessageModule.self).messagesPublisher
|
client.module(MessageModule.self).messagesPublisher
|
||||||
.sink { [weak self] message in
|
.sink { [weak self] message in
|
||||||
|
@ -80,9 +93,11 @@ final class XMPPService: ObservableObject {
|
||||||
|
|
||||||
client.modulesManager.register(PubSubModule())
|
client.modulesManager.register(PubSubModule())
|
||||||
client.modulesManager.register(MessageModule(chatManager: manager))
|
client.modulesManager.register(MessageModule(chatManager: manager))
|
||||||
client.modulesManager.register(MessageCarbonsModule())
|
|
||||||
client.modulesManager.register(MessageArchiveManagementModule())
|
client.modulesManager.register(MessageArchiveManagementModule())
|
||||||
|
|
||||||
|
client.modulesManager.register(MessageCarbonsModule())
|
||||||
|
client.module(.messageCarbons).enable()
|
||||||
|
|
||||||
// file transfer modules
|
// file transfer modules
|
||||||
client.modulesManager.register(HttpFileUploadModule())
|
client.modulesManager.register(HttpFileUploadModule())
|
||||||
|
|
||||||
|
@ -160,8 +175,8 @@ final class XMPPService: ObservableObject {
|
||||||
switch res {
|
switch res {
|
||||||
case .success(let slot):
|
case .success(let slot):
|
||||||
var request = URLRequest(url: slot.putUri)
|
var request = URLRequest(url: slot.putUri)
|
||||||
for (k, v) in slot.putHeaders {
|
for (key, value) in slot.putHeaders {
|
||||||
request.addValue(v, forHTTPHeaderField: k)
|
request.addValue(value, forHTTPHeaderField: key)
|
||||||
}
|
}
|
||||||
request.httpMethod = "PUT"
|
request.httpMethod = "PUT"
|
||||||
request.httpBody = data
|
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
|
@State private var isShowingLoader = false
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@State private var jidStr: String = "test1@test.anal.company"
|
@State private var jidStr: String = "nartest1@conversations.im"
|
||||||
@State private var pass: String = "12345"
|
@State private var pass: String = "nartest12345"
|
||||||
|
// @State private var jidStr: String = "test1@test.anal.company"
|
||||||
|
// @State private var pass: String = "12345"
|
||||||
#else
|
#else
|
||||||
@State private var jidStr: String = ""
|
@State private var jidStr: String = ""
|
||||||
@State private var pass: String = ""
|
@State private var pass: String = ""
|
||||||
|
|
Loading…
Reference in a new issue