diff --git a/ConversationsClassic/AppCore/Actions/AppActions.swift b/ConversationsClassic/AppCore/Actions/AppActions.swift index ea4abb5..2cb786d 100644 --- a/ConversationsClassic/AppCore/Actions/AppActions.swift +++ b/ConversationsClassic/AppCore/Actions/AppActions.swift @@ -10,7 +10,6 @@ enum AppAction: Codable { case rostersAction(_ action: RostersAction) case chatsAction(_ action: ChatsAction) case conversationAction(_ action: ConversationAction) - case messagesAction(_ action: MessagesAction) case sharingAction(_ action: SharingAction) case fileAction(_ action: FileAction) } diff --git a/ConversationsClassic/AppCore/Actions/MessagesActions.swift b/ConversationsClassic/AppCore/Actions/MessagesActions.swift deleted file mode 100644 index d4e3895..0000000 --- a/ConversationsClassic/AppCore/Actions/MessagesActions.swift +++ /dev/null @@ -1,3 +0,0 @@ -enum MessagesAction: Codable { - case currentConversationMessagesUpdated(messages: [Message]) -} diff --git a/ConversationsClassic/AppCore/Actions/XMPPActions.swift b/ConversationsClassic/AppCore/Actions/XMPPActions.swift index 7a397e0..8876ad3 100644 --- a/ConversationsClassic/AppCore/Actions/XMPPActions.swift +++ b/ConversationsClassic/AppCore/Actions/XMPPActions.swift @@ -1,3 +1,5 @@ +import Foundation + enum XMPPAction: Codable { case clientConnectionChanged(jid: String, state: ConnectionStatus) case xmppMessageReceived(Message) @@ -10,4 +12,6 @@ enum XMPPAction: Codable { case xmppSharingUploadFailed(msgId: String, reason: String) case xmppSharingUploadSuccess(msgId: String, attachmentRemotePath: String) case serverFeaturesLoaded(jid: String, features: [String]) + + case xmppLoadArchivedMessages(jid: String, to: String?, fromDate: Date) } diff --git a/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift index 1be36df..3aa6353 100644 --- a/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/DatabaseMiddleware.swift @@ -488,7 +488,7 @@ private extension DatabaseMiddleware { } receiveValue: { messages in // messages DispatchQueue.main.async { - store.dispatch(.messagesAction(.currentConversationMessagesUpdated(messages: messages))) + store.dispatch(.conversationAction(.messagesUpdated(messages: messages))) } } .store(in: &conversationCancellables) diff --git a/ConversationsClassic/AppCore/Middlewares/MessagesMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/MessagesMiddleware.swift index 37be04e..5ee63ca 100644 --- a/ConversationsClassic/AppCore/Middlewares/MessagesMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/MessagesMiddleware.swift @@ -4,11 +4,24 @@ import Foundation final class MessagesMiddleware { static let shared = MessagesMiddleware() - func middleware(state _: AppState, action: AppAction) -> AnyPublisher { + func middleware(state: AppState, action: AppAction) -> AnyPublisher { switch action { - case .messagesAction(.currentConversationMessagesUpdated(let messages)): - return Just(.conversationAction(.messagesUpdated(messages: messages))) - .eraseToAnyPublisher() + case .conversationAction(.makeConversationActive(let chat, let roster)): + return Future { promise in + if let currentClient = state.accountsState.accounts.first(where: { $0.bareJid == chat.account }) { + let features = state.accountsState.discoFeatures[currentClient.bareJid] ?? [] + if features.map({ $0.xep }).contains("XEP-0313") { + let oldestMessageDate = state.conversationsState.currentMessages.first?.date ?? Date() + let archivesRequestDate = Calendar.current.date(byAdding: .day, value: -7, to: oldestMessageDate) ?? Date() + promise(.success(.xmppAction(.xmppLoadArchivedMessages(jid: currentClient.bareJid, to: roster?.bareJid, fromDate: archivesRequestDate)))) + } else { + promise(.success(.info("MessageMiddleware: XEP-0313 not supported for client \(currentClient.bareJid)"))) + } + } else { + promise(.success(.info("MessageMiddleware: No client found for account \(chat.account), probably some error here"))) + } + } + .eraseToAnyPublisher() default: return Empty().eraseToAnyPublisher() diff --git a/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift b/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift index 95bc587..83393a4 100644 --- a/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift +++ b/ConversationsClassic/AppCore/Middlewares/XMPPMiddleware.swift @@ -129,6 +129,13 @@ final class XMPPMiddleware { } .eraseToAnyPublisher() + case .xmppAction(.xmppLoadArchivedMessages(let jid, let to, let fromDate)): + return Future { [weak self] promise in + self?.service.requestArchivedMessages(jid: jid, to: to, fromDate: fromDate) + promise(.success(.info("XMPPMiddleware: archived messages requested for \(jid) from \(fromDate)"))) + } + .eraseToAnyPublisher() + default: return Empty().eraseToAnyPublisher() } diff --git a/ConversationsClassic/AppCore/Reducers/AppReducer.swift b/ConversationsClassic/AppCore/Reducers/AppReducer.swift index 3ee765b..ff67556 100644 --- a/ConversationsClassic/AppCore/Reducers/AppReducer.swift +++ b/ConversationsClassic/AppCore/Reducers/AppReducer.swift @@ -13,7 +13,7 @@ extension AppState { case .startAction(let action): StartState.reducer(state: &state.startState, action: action) - case .databaseAction, .xmppAction, .fileAction, .info, .messagesAction: + case .databaseAction, .xmppAction, .fileAction, .info: break // this actions are processed by other middlewares case .accountsAction(let action): diff --git a/ConversationsClassic/AppCore/XMPP/XMPPService.swift b/ConversationsClassic/AppCore/XMPP/XMPPService.swift index 1c59e4b..c753409 100644 --- a/ConversationsClassic/AppCore/XMPP/XMPPService.swift +++ b/ConversationsClassic/AppCore/XMPP/XMPPService.swift @@ -250,4 +250,19 @@ final class XMPPService: ObservableObject { } } } + + func requestArchivedMessages(jid: String, to: String?, fromDate: Date) { + guard let client = getClient(for: jid) else { + return + } + client.module(.mam).queryItems(componentJid: JID(jid), with: JID(to), start: fromDate, end: Date(), queryId: UUID().uuidString) { result in + switch result { + case .success(let response): + print("MAM response: \(response)") + + case .failure(let error): + print("MAM error: \(error)") + } + } + } } diff --git a/ConversationsClassic/Helpers/Const.swift b/ConversationsClassic/Helpers/Const.swift index d1cf5a7..465e812 100644 --- a/ConversationsClassic/Helpers/Const.swift +++ b/ConversationsClassic/Helpers/Const.swift @@ -43,4 +43,7 @@ enum Const { // Size for attachment preview static let attachmentPreviewSize = UIScreen.main.bounds.width * 0.5 + + // Lenght in days for MAM request + static let mamRequestLength = 7 }