wip
This commit is contained in:
parent
20c89c65e9
commit
995d627fde
|
@ -5,4 +5,6 @@ enum DatabaseAction: Codable {
|
||||||
|
|
||||||
case storedRostersLoaded(rosters: [Roster])
|
case storedRostersLoaded(rosters: [Roster])
|
||||||
case storedChatsLoaded(chats: [Chat])
|
case storedChatsLoaded(chats: [Chat])
|
||||||
|
|
||||||
|
case storeMessageFailed(reason: String)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,6 @@ final class ConversationMiddleware {
|
||||||
case .conversationAction(.makeConversationActive):
|
case .conversationAction(.makeConversationActive):
|
||||||
return Just(AppAction.changeFlow(.conversation)).eraseToAnyPublisher()
|
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:
|
default:
|
||||||
return Empty().eraseToAnyPublisher()
|
return Empty().eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ final class DatabaseMiddleware {
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable:next function_body_length
|
||||||
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
||||||
switch action {
|
switch action {
|
||||||
// MARK: Accounts
|
// MARK: Accounts
|
||||||
|
@ -156,52 +157,27 @@ final class DatabaseMiddleware {
|
||||||
|
|
||||||
// MARK: Conversation and messages
|
// MARK: Conversation and messages
|
||||||
case .conversationAction(.makeConversationActive(let chat, _)):
|
case .conversationAction(.makeConversationActive(let chat, _)):
|
||||||
return Future<AppAction, Never> { [weak self] promise in
|
subscribeToMessages(chat: chat)
|
||||||
guard let wSelf = self else {
|
return Empty().eraseToAnyPublisher()
|
||||||
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()
|
|
||||||
|
|
||||||
case .xmppAction(.xmppMessageReceived(let message)):
|
case .xmppAction(.xmppMessageReceived(let message)):
|
||||||
return Future<AppAction, Never> { promise in
|
return Future<AppAction, Never> { promise in
|
||||||
Task(priority: .background) { [weak self] in
|
Task(priority: .background) { [weak self] in
|
||||||
guard let database = self?.database else {
|
guard let database = self?.database else {
|
||||||
|
promise(.success(.databaseAction(.storeMessageFailed(reason: L10n.Global.Error.genericDbError))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard message.contentType != .typing else {
|
||||||
promise(.success(.empty))
|
promise(.success(.empty))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
try database._db.write { db in
|
try database._db.write { db in
|
||||||
try message.insert(db)
|
try message.insert(db)
|
||||||
promise(.success(.empty))
|
|
||||||
}
|
}
|
||||||
|
promise(.success(.empty))
|
||||||
} catch {
|
} 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Combine
|
import Combine
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
let isConsoleLoggingEnabled = false
|
let isConsoleLoggingEnabled = false
|
||||||
|
|
||||||
|
@ -13,7 +14,8 @@ let isConsoleLoggingEnabled = false
|
||||||
var stateStr = "\(state)"
|
var stateStr = "\(state)"
|
||||||
stateStr = String(stateStr.prefix(prefixLength)) + " ..."
|
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)
|
print(str)
|
||||||
if isConsoleLoggingEnabled {
|
if isConsoleLoggingEnabled {
|
||||||
NSLog(str)
|
NSLog(str)
|
||||||
|
@ -30,9 +32,9 @@ let isConsoleLoggingEnabled = false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum LogLevels: String {
|
enum LogLevels: String {
|
||||||
case info = "ℹ️"
|
case info = "\u{F449}"
|
||||||
case warning = "⚠️"
|
case warning = "\u{F071}"
|
||||||
case error = "❌"
|
case error = "\u{EA76}"
|
||||||
}
|
}
|
||||||
|
|
||||||
// For database errors logging
|
// For database errors logging
|
||||||
|
|
|
@ -15,6 +15,8 @@ enum MessageContentType: String, Codable, DatabaseValueConvertible {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Message: DBStorable, Equatable {
|
struct Message: DBStorable, Equatable {
|
||||||
|
static let databaseTableName = "messages"
|
||||||
|
|
||||||
let id: String
|
let id: String
|
||||||
let type: MessageType
|
let type: MessageType
|
||||||
let contentType: MessageContentType
|
let contentType: MessageContentType
|
||||||
|
|
Loading…
Reference in a new issue