This commit is contained in:
fmodf 2024-07-22 14:18:42 +02:00
parent 6ce16b1f3b
commit 002e152604
5 changed files with 53 additions and 57 deletions

View file

@ -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<State: Stateable, Action: Codable>: 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<State: Stateable, Action: Codable>: 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<State: Stateable, Action: Codable>: 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
}
}

View file

@ -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)
}

View file

@ -8,36 +8,3 @@ struct ServerFeature: Stateable, Identifiable {
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>

View file

@ -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())

View file

@ -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)