Skip to content
Snippets Groups Projects
Commit 2d709642 authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Implement message sending

parent e2cf40af
No related branches found
No related tags found
2 merge requests!102Release 1.0.0,!87Messenger example - chat
......@@ -70,6 +70,11 @@ extension AppEnvironment {
ChatEnvironment(
messenger: messenger,
db: dbManager.getDB,
sendMessage: .live(
messenger: messenger,
db: dbManager.getDB,
now: Date.init
),
mainQueue: mainQueue,
bgQueue: bgQueue
)
......
import AppCore
import Combine
import ComposableArchitecture
import Foundation
import XCTestDynamicOverlay
......@@ -34,40 +35,48 @@ public struct ChatState: Equatable, Identifiable {
id: ID,
myContactId: Data? = nil,
messages: IdentifiedArrayOf<Message> = [],
failure: String? = nil
failure: String? = nil,
text: String = ""
) {
self.id = id
self.myContactId = myContactId
self.messages = messages
self.failure = failure
self.text = text
}
public var id: ID
public var myContactId: Data?
public var messages: IdentifiedArrayOf<Message>
public var failure: String?
@BindableState public var text: String
}
public enum ChatAction: Equatable {
public enum ChatAction: Equatable, BindableAction {
case start
case didFetchMessages(IdentifiedArrayOf<ChatState.Message>)
case sendTapped
case binding(BindingAction<ChatState>)
}
public struct ChatEnvironment {
public init(
messenger: Messenger,
db: DBManagerGetDB,
sendMessage: SendMessage,
mainQueue: AnySchedulerOf<DispatchQueue>,
bgQueue: AnySchedulerOf<DispatchQueue>
) {
self.messenger = messenger
self.db = db
self.sendMessage = sendMessage
self.mainQueue = mainQueue
self.bgQueue = bgQueue
}
public var messenger: Messenger
public var db: DBManagerGetDB
public var sendMessage: SendMessage
public var mainQueue: AnySchedulerOf<DispatchQueue>
public var bgQueue: AnySchedulerOf<DispatchQueue>
}
......@@ -77,6 +86,7 @@ extension ChatEnvironment {
public static let unimplemented = ChatEnvironment(
messenger: .unimplemented,
db: .unimplemented,
sendMessage: .unimplemented,
mainQueue: .unimplemented,
bgQueue: .unimplemented
)
......@@ -126,5 +136,32 @@ public let chatReducer = Reducer<ChatState, ChatAction, ChatEnvironment>
case .didFetchMessages(let messages):
state.messages = messages
return .none
case .sendTapped:
let text = state.text
let chatId = state.id
state.text = ""
return Effect.run { subscriber in
switch chatId {
case .contact(let recipientId):
env.sendMessage(
text: text,
to: recipientId,
onError: { error in
// TODO: handle error
print("^^^ ERROR: \(error)")
}
)
}
subscriber.send(completion: .finished)
return AnyCancellable {}
}
.subscribe(on: env.bgQueue)
.receive(on: env.mainQueue)
.eraseToEffect()
case .binding(_):
return .none
}
}
.binding()
......@@ -13,11 +13,13 @@ public struct ChatView: View {
var myContactId: Data?
var messages: IdentifiedArrayOf<ChatState.Message>
var failure: String?
var text: String
init(state: ChatState) {
myContactId = state.myContactId
messages = state.messages
failure = state.failure
text = state.text
}
}
......@@ -52,11 +54,14 @@ public struct ChatView: View {
VStack(spacing: 0) {
Divider()
HStack {
TextField("Text", text: .constant(""))
.textFieldStyle(.roundedBorder)
TextField("Text", text: viewStore.binding(
get: \.text,
send: { ChatAction.set(\.$text, $0) }
))
.textFieldStyle(.roundedBorder)
Button {
viewStore.send(.sendTapped)
} label: {
Image(systemName: "paperplane.fill")
}
......
......@@ -130,4 +130,36 @@ final class ChatFeatureTests: XCTestCase {
$0.failure = error.localizedDescription
}
}
func testSend() {
struct SendMessageParams: Equatable {
var text: String
var recipientId: Data
}
var didSendMessageWithParams: [SendMessageParams] = []
let store = TestStore(
initialState: ChatState(id: .contact("contact-id".data(using: .utf8)!)),
reducer: chatReducer,
environment: .unimplemented
)
store.environment.mainQueue = .immediate
store.environment.bgQueue = .immediate
store.environment.sendMessage.run = { text, recipientId, _ in
didSendMessageWithParams.append(.init(text: text, recipientId: recipientId))
}
store.send(.set(\.$text, "Hello")) {
$0.text = "Hello"
}
store.send(.sendTapped) {
$0.text = ""
}
XCTAssertNoDifference(didSendMessageWithParams, [
.init(text: "Hello", recipientId: "contact-id".data(using: .utf8)!)
])
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment