This commit is contained in:
fmodf 2024-06-26 11:29:30 +02:00
parent 20c89c65e9
commit 995d627fde
5 changed files with 45 additions and 56 deletions

View file

@ -5,4 +5,6 @@ enum DatabaseAction: Codable {
case storedRostersLoaded(rosters: [Roster])
case storedChatsLoaded(chats: [Chat])
case storeMessageFailed(reason: String)
}

View file

@ -16,25 +16,6 @@ final class ConversationMiddleware {
case .conversationAction(.makeConversationActive):
return Just(AppAction.changeFlow(.conversation)).eraseToAnyPublisher()
// case .xmppAction(.xmppMessageReceived(let message)):
// return Future<AppAction, Never> { promise in
// let currentChat = state.conversationsState.currentChat
// if message.from == currentChat?.participant, message.to == currentChat?.account, message.contentType != .typing {
// promise(.success(.conversationAction(.messageForCurrentConversationReceived(message))))
// } else {
// promise(.success(.empty))
// }
// }
// .eraseToAnyPublisher()
//
// case .conversationAction(.messageForCurrentConversationReceived(let message)):
// return Future<AppAction, Never> { promise in
// var currentMessages = state.conversationsState.currentMessages
// currentMessages.append(message)
// promise(.success(.conversationAction(.messagesUpdated(messages: currentMessages))))
// }
// .eraseToAnyPublisher()
default:
return Empty().eraseToAnyPublisher()
}

View file

@ -34,6 +34,7 @@ final class DatabaseMiddleware {
.store(in: &cancellables)
}
// swiftlint:disable:next function_body_length
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
switch action {
// MARK: Accounts
@ -156,52 +157,27 @@ final class DatabaseMiddleware {
// MARK: Conversation and messages
case .conversationAction(.makeConversationActive(let chat, _)):
return Future<AppAction, Never> { [weak self] promise in
guard let wSelf = self else {
promise(.success(.empty))
return
}
// Observe changes for current conversation
wSelf.conversationCancellables = []
ValueObservation
.tracking(
Message
.filter(
Column("from") == chat.account ||
Column("from") == chat.participant ||
Column("to") == chat.participant ||
Column("to") == chat.participant
)
.order(Column("timestamp").asc)
.fetchAll
)
.publisher(in: wSelf.database._db, scheduling: .immediate)
.sink { _ in
// Handle completion
} receiveValue: { messages in
DispatchQueue.main.async {
store.dispatch(.conversationAction(.messagesUpdated(messages: messages)))
}
}
.store(in: &wSelf.conversationCancellables)
promise(.success(.empty))
}
.eraseToAnyPublisher()
subscribeToMessages(chat: chat)
return Empty().eraseToAnyPublisher()
case .xmppAction(.xmppMessageReceived(let message)):
return Future<AppAction, Never> { promise in
Task(priority: .background) { [weak self] in
guard let database = self?.database else {
promise(.success(.databaseAction(.storeMessageFailed(reason: L10n.Global.Error.genericDbError))))
return
}
guard message.contentType != .typing else {
promise(.success(.empty))
return
}
do {
try database._db.write { db in
try message.insert(db)
promise(.success(.empty))
}
promise(.success(.empty))
} catch {
promise(.success(.databaseAction(.updateAccountFailed)))
promise(.success(.databaseAction(.storeMessageFailed(reason: error.localizedDescription))))
}
}
}
@ -215,3 +191,29 @@ final class DatabaseMiddleware {
}
}
}
private extension DatabaseMiddleware {
func subscribeToMessages(chat: Chat) {
conversationCancellables = []
ValueObservation
.tracking(
Message
.filter(
Column("to") == chat.account ||
(Column("from") == chat.account && Column("to") == chat.participant)
)
.order(Column("date").asc)
.fetchAll
)
.publisher(in: database._db, scheduling: .immediate)
.sink { res in
print("!!!---Messages received: \(res)")
// Handle completion
} receiveValue: { messages in
DispatchQueue.main.async {
store.dispatch(.conversationAction(.messagesUpdated(messages: messages)))
}
}
.store(in: &conversationCancellables)
}
}

View file

@ -1,5 +1,6 @@
import Combine
import Foundation
import SwiftUI
let isConsoleLoggingEnabled = false
@ -13,7 +14,8 @@ let isConsoleLoggingEnabled = false
var stateStr = "\(state)"
stateStr = String(stateStr.prefix(prefixLength)) + " ..."
let str = "\(timeStr) ➡️ \(actionStr)\n\(timeStr)\(stateStr)\n"
let str = "\(timeStr) \u{EA86} \(actionStr)\n\(timeStr) \u{F129} \(stateStr)\n"
print(str)
if isConsoleLoggingEnabled {
NSLog(str)
@ -30,9 +32,9 @@ let isConsoleLoggingEnabled = false
#endif
enum LogLevels: String {
case info = ""
case warning = "⚠️"
case error = ""
case info = "\u{F449}"
case warning = "\u{F071}"
case error = "\u{EA76}"
}
// For database errors logging

View file

@ -15,6 +15,8 @@ enum MessageContentType: String, Codable, DatabaseValueConvertible {
}
struct Message: DBStorable, Equatable {
static let databaseTableName = "messages"
let id: String
let type: MessageType
let contentType: MessageContentType