mv-experiment #1

Merged
fmodf merged 88 commits from mv-experiment into develop 2024-09-03 15:13:59 +00:00
5 changed files with 70 additions and 1 deletions
Showing only changes of commit 7df723e62d - Show all commits

View file

@ -0,0 +1,24 @@
import Combine
import Foundation
import GRDB
import Martin
final class ClientMartinDiscoManager {
private(set) var features: [ServerFeature] = []
private var cancellables: Set<AnyCancellable> = []
init(_ xmppConnection: XMPPClient) {
// subscribe to client server features
xmppConnection.module(DiscoveryModule.self).$serverDiscoResult
.sink { [weak self] disco in
let allFeatures = ServerFeature.allFeatures
let features = disco.features
.compactMap { featureId in
allFeatures.first(where: { $0.xmppId == featureId })
}
self?.features = features
}
.store(in: &cancellables)
}
}

View file

@ -21,6 +21,15 @@ final class ClientMartinMessagesManager {
} }
.store(in: &cancellables) .store(in: &cancellables)
// subscribe to archived messages
xmppConnection.module(.mam).archivedMessagesPublisher
.sink(receiveValue: { [weak self] archived in
let message = archived.message
message.attribute("archived_date", newValue: "\(archived.timestamp.timeIntervalSince1970)")
self?.handleMessage(message)
})
.store(in: &cancellables)
// enable carbons if available // enable carbons if available
xmppConnection.module(.messageCarbons).$isAvailable.filter { $0 } xmppConnection.module(.messageCarbons).$isAvailable.filter { $0 }
.sink(receiveValue: { [weak xmppConnection] _ in .sink(receiveValue: { [weak xmppConnection] _ in

View file

@ -25,12 +25,14 @@ final class Client: ObservableObject {
private var rosterManager = ClientMartinRosterManager() private var rosterManager = ClientMartinRosterManager()
private var chatsManager = ClientMartinChatsManager() private var chatsManager = ClientMartinChatsManager()
private var messageManager: ClientMartinMessagesManager private var messageManager: ClientMartinMessagesManager
private var discoManager: ClientMartinDiscoManager
init(credentials: Credentials) { init(credentials: Credentials) {
self.credentials = credentials self.credentials = credentials
state = credentials.isActive ? .enabled(.disconnected) : .disabled state = credentials.isActive ? .enabled(.disconnected) : .disabled
connection = Self.prepareConnection(credentials, rosterManager, chatsManager) connection = Self.prepareConnection(credentials, rosterManager, chatsManager)
messageManager = ClientMartinMessagesManager(connection) messageManager = ClientMartinMessagesManager(connection)
discoManager = ClientMartinDiscoManager(connection)
connectionCancellable = connection.$state connectionCancellable = connection.$state
.sink { [weak self] state in .sink { [weak self] state in
guard let self = self else { return } guard let self = self else { return }
@ -134,6 +136,16 @@ extension Client {
throw URLError(.badServerResponse) throw URLError(.badServerResponse)
} }
} }
func requestArchivedMessages(for roster: Roster) async {
if !discoManager.features.map({ $0.xep }).contains("XEP-0313") {
return
}
let module = connection.module(MessageArchiveManagementModule.self)
let endDate = Date()
let startDate = Calendar.current.date(byAdding: .day, value: -Const.mamRequestDaysLength, to: endDate) ?? Date()
let response = try? await module.queryItems(componentJid: JID(credentials.bareJid), with: JID(roster.bareJid), start: startDate, end: endDate, queryId: UUID().uuidString)
}
} }
extension Client { extension Client {
@ -163,7 +175,7 @@ private extension Client {
client.modulesManager.register(PubSubModule()) client.modulesManager.register(PubSubModule())
client.modulesManager.register(MessageModule(chatManager: chat)) client.modulesManager.register(MessageModule(chatManager: chat))
// client.modulesManager.register(MessageArchiveManagementModule()) client.modulesManager.register(MessageArchiveManagementModule())
client.modulesManager.register(MessageCarbonsModule()) client.modulesManager.register(MessageCarbonsModule())

View file

@ -0,0 +1,21 @@
import Foundation
struct ServerFeature: Identifiable & Codable {
let xep: String
let name: String
let xmppId: String?
let description: String?
var id: String { xep }
static 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
}
}

View file

@ -18,6 +18,9 @@ final class ConversationStore: ObservableObject {
self.client = client self.client = client
self.roster = roster self.roster = roster
subscribe() subscribe()
Task {
await client.requestArchivedMessages(for: roster)
}
} }
} }