wip
This commit is contained in:
parent
e23a312538
commit
20c89c65e9
|
@ -1,3 +1,7 @@
|
|||
enum ConversationAction: Codable {
|
||||
case makeConversationActive(chat: Chat, roster: Roster?)
|
||||
|
||||
case sendMessage(from: String, to: String, body: String)
|
||||
|
||||
case messagesUpdated(messages: [Message])
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ final class DatabaseMiddleware {
|
|||
static let shared = DatabaseMiddleware()
|
||||
private let database = Database.shared
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
private var conversationCancellables: Set<AnyCancellable> = []
|
||||
|
||||
private init() {
|
||||
// Database changes
|
||||
|
@ -35,6 +36,7 @@ final class DatabaseMiddleware {
|
|||
|
||||
func middleware(state _: AppState, action: AppAction) -> AnyPublisher<AppAction, Never> {
|
||||
switch action {
|
||||
// MARK: Accounts
|
||||
case .startAction(.loadStoredAccounts):
|
||||
return Future<AppAction, Never> { promise in
|
||||
Task(priority: .background) { [weak self] in
|
||||
|
@ -81,6 +83,7 @@ final class DatabaseMiddleware {
|
|||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
// MARK: Rosters
|
||||
case .rostersAction(.markRosterAsLocallyDeleted(let ownerJID, let contactJID)):
|
||||
return Future<AppAction, Never> { promise in
|
||||
Task(priority: .background) { [weak self] in
|
||||
|
@ -125,6 +128,7 @@ final class DatabaseMiddleware {
|
|||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
// MARK: Chats
|
||||
case .chatsAction(.createNewChat(let accountJid, let participantJid)):
|
||||
return Future<AppAction, Never> { promise in
|
||||
Task(priority: .background) { [weak self] in
|
||||
|
@ -150,11 +154,60 @@ final class DatabaseMiddleware {
|
|||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
case .xmppAction(.xmppMessageReceived(let message)):
|
||||
if message.type != .chat {
|
||||
return Empty().eraseToAnyPublisher()
|
||||
// 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
|
||||
}
|
||||
// TODO: Store msg here!
|
||||
// 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)):
|
||||
return Future<AppAction, Never> { promise in
|
||||
Task(priority: .background) { [weak self] in
|
||||
guard let database = self?.database else {
|
||||
promise(.success(.empty))
|
||||
return
|
||||
}
|
||||
do {
|
||||
try database._db.write { db in
|
||||
try message.insert(db)
|
||||
promise(.success(.empty))
|
||||
}
|
||||
} catch {
|
||||
promise(.success(.databaseAction(.updateAccountFailed)))
|
||||
}
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
case .conversationAction(.sendMessage(let from, let to, let body)):
|
||||
return Empty().eraseToAnyPublisher()
|
||||
|
||||
default:
|
||||
|
|
|
@ -14,7 +14,7 @@ enum MessageContentType: String, Codable, DatabaseValueConvertible {
|
|||
case invite
|
||||
}
|
||||
|
||||
struct Message: Stateable, Identifiable, DatabaseValueConvertible {
|
||||
struct Message: DBStorable, Equatable {
|
||||
let id: String
|
||||
let type: MessageType
|
||||
let contentType: MessageContentType
|
||||
|
|
|
@ -7,6 +7,9 @@ extension ConversationState {
|
|||
state.currentChat = chat
|
||||
state.currentRoster = roster
|
||||
|
||||
case .messagesUpdated(let messages):
|
||||
state.currentMessages = messages
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
@ -70,13 +70,13 @@ struct ConversationScreenTextInput: View {
|
|||
.padding(.trailing, 8)
|
||||
.tappablePadding(.symmetric(8)) {
|
||||
if !messageStr.isEmpty {
|
||||
// guard let acc = store.state.conversationsState.currentChat?.account else { return }
|
||||
// guard let contact = store.state.conversationsState.currentChat?.participant else { return }
|
||||
// store.dispatch(.conversationAction(.sendMessage(
|
||||
// from: acc,
|
||||
// to: contact,
|
||||
// body: messageStr
|
||||
// )))
|
||||
guard let acc = store.state.conversationsState.currentChat?.account else { return }
|
||||
guard let contact = store.state.conversationsState.currentChat?.participant else { return }
|
||||
store.dispatch(.conversationAction(.sendMessage(
|
||||
from: acc,
|
||||
to: contact,
|
||||
body: messageStr
|
||||
)))
|
||||
messageStr = ""
|
||||
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue