diff --git a/ConversationsClassic/AppCore/AppStore.swift b/ConversationsClassic/AppCore/AppStore.swift index e0cd7f5..7cce2c7 100644 --- a/ConversationsClassic/AppCore/AppStore.swift +++ b/ConversationsClassic/AppCore/AppStore.swift @@ -1,6 +1,5 @@ // This file declare global state object for whole app // and reducers/actions/middleware types. Core of app. - import Combine import Foundation @@ -51,25 +50,11 @@ final class Store: ObservableObject { } private func dispatch(_ currentState: State, _ action: Action) -> State { - let startTime = CFAbsoluteTimeGetCurrent() - // Do reducing + var startTime = CFAbsoluteTimeGetCurrent() var newState = currentState reducer(&newState, action) - - // Dispatch all middleware functions - for middleware in middlewares { - guard let middleware = middleware(newState, action) else { - break - } - middleware - .receive(on: DispatchQueue.main) - .sink(receiveValue: dispatch) - .store(in: &middlewareCancellables) - } - - // Check performance - let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime + var timeElapsed = CFAbsoluteTimeGetCurrent() - startTime if timeElapsed > 0.05 { #if DEBUG print( @@ -77,7 +62,7 @@ final class Store: ObservableObject { -- (Ignore this warning ONLY in case, when execution is paused by your breakpoint) 🕐Execution time: \(timeElapsed) - ❌WARNING! Some reducers/middlewares work too long! It will lead to issues in production build! + ❌WARNING! Some reducers work too long! It will lead to issues in production build! Because of execution each action is synchronous the any stuck will reduce performance dramatically. Probably you need check which part of reducer/middleware should be async (wrapped with Futures, as example) -- @@ -87,6 +72,35 @@ final class Store: ObservableObject { #endif } + // Dispatch all middleware functions + for middleware in middlewares { + guard let middleware = middleware(newState, action) else { + break + } + startTime = CFAbsoluteTimeGetCurrent() + middleware + .receive(on: DispatchQueue.main) + .sink(receiveValue: dispatch) + .store(in: &middlewareCancellables) + timeElapsed = CFAbsoluteTimeGetCurrent() - startTime + if timeElapsed > 0.05 { + #if DEBUG + print( + """ + -- + (Ignore this warning ONLY in case, when execution is paused by your breakpoint) + 🕐Execution time: \(timeElapsed) + ❌WARNING! Middleware work too long! It will lead to issues in production build! + Because of execution each action is synchronous the any stuck will reduce performance dramatically. + Probably you need check which part of reducer/middleware should be async (wrapped with Futures, as example) + -- + """ + ) + #else + #endif + } + } + return newState } } diff --git a/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift index 95bc587..27bf8ea 100644 --- a/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift @@ -27,11 +27,13 @@ final class XMPPMiddleware { } .store(in: &cancellables) - service.clientFeatures.sink { client, features in + service.clientFeatures.sink { client, _ in let jid = client.userBareJid.stringValue - DispatchQueue.main.async { - store.dispatch(.xmppAction(.serverFeaturesLoaded(jid: jid, features: features))) - } + + // TODO: Fix this (BAD_ACCESS error in runtime) + // DispatchQueue.main.async { + // store.dispatch(.xmppAction(.serverFeaturesLoaded(jid: jid, features: features))) + // } } .store(in: &cancellables) } diff --git a/ConversationsClassic/AppCore/Models/ServerFeature.swift b/ConversationsClassic/AppCore/Models/ServerFeature.swift index fc41607..8ee3663 100644 --- a/ConversationsClassic/AppCore/Models/ServerFeature.swift +++ b/ConversationsClassic/AppCore/Models/ServerFeature.swift @@ -8,36 +8,3 @@ struct ServerFeature: Stateable, Identifiable { var id: String { xep } } - -// -// XEP-0001 -// XMPP Extension Protocols -// Procedural -// Active -// 2016-11-16 -// -// -// -// XEP-0002 -// Special Interest Groups (SIGs) -// Procedural -// Active -// 2002-01-11 -// -// -// -// XEP-0003 -// Proxy Accept Socket Service (PASS) -// Historical -// Obsolete -// 2009-06-03 -// -// -// -// XEP-0004 -// Data Forms -// Standards Track -// Final -// 2007-08-13 -// -// diff --git a/ConversationsClassic/AppCore/XMPP/XMPPService.swift b/ConversationsClassic/AppCore/XMPP/XMPPService.swift index 0a7c413..911a132 100644 --- a/ConversationsClassic/AppCore/XMPP/XMPPService.swift +++ b/ConversationsClassic/AppCore/XMPP/XMPPService.swift @@ -66,6 +66,18 @@ final class XMPPService: ObservableObject { } .store(in: &clientMessagesCancellables) + // subscribe to carbons + client.module(MessageCarbonsModule.self).carbonsPublisher + .sink { [weak self] carbon in + self?.clientMessagesPublisher.send((client, carbon.message)) + } + .store(in: &clientMessagesCancellables) + + // enable carbons if available + client.module(.messageCarbons).$isAvailable.filter { $0 }.sink(receiveValue: { [weak client] _ in + client?.module(.messageCarbons).enable() + }).store(in: &clientMessagesCancellables) + client.login() } @@ -96,7 +108,6 @@ final class XMPPService: ObservableObject { client.modulesManager.register(MessageArchiveManagementModule()) client.modulesManager.register(MessageCarbonsModule()) - client.module(.messageCarbons).enable() // file transfer modules client.modulesManager.register(HttpFileUploadModule()) diff --git a/ConversationsClassic/View/Screens/Conversation/ConversationTextInput.swift b/ConversationsClassic/View/Screens/Conversation/ConversationTextInput.swift index dd2c202..a0b089d 100644 --- a/ConversationsClassic/View/Screens/Conversation/ConversationTextInput.swift +++ b/ConversationsClassic/View/Screens/Conversation/ConversationTextInput.swift @@ -51,8 +51,10 @@ struct ConversationTextInput: View { .tappablePadding(.symmetric(8)) { store.dispatch(.sharingAction(.showSharing(true))) } - TextField(L10n.Chat.textfieldPrompt, text: $messageStr) + TextField("", text: $messageStr, prompt: Text(L10n.Chat.textfieldPrompt).foregroundColor(.Material.Shape.separator)) .font(.body1) + .foregroundColor(Color.Material.Text.main) + .accentColor(.Material.Shape.black) .focused($isFocused) .padding(.horizontal, 8) .padding(.vertical, 4)