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