Browse Source

Add the ability to send messages

master
Peter Hajas 3 years ago
parent
commit
1540937d69
  1. 47
      Kordophone/Shared/ConversationView.swift
  2. 24
      KordophoneKit/Sources/KordophoneKit/Connection.swift

47
Kordophone/Shared/ConversationView.swift

@ -5,8 +5,12 @@ import KordophoneKit
struct ConversationView : View { struct ConversationView : View {
var conversation: Conversation var conversation: Conversation
var messages: [Message] var messages: [Message]
var sendAction: (String) -> Void
var body: some View { @State private var inputText = ""
@ViewBuilder
private var transcript: some View {
ScrollViewReader { proxy in ScrollViewReader { proxy in
ScrollView { ScrollView {
LazyVStack { LazyVStack {
@ -22,12 +26,33 @@ struct ConversationView : View {
} }
} }
} }
.navigationTitle(conversation.effectiveDisplayName)
.onChange(of: messages) { newValue in .onChange(of: messages) { newValue in
proxy.scrollTo(newValue.last, anchor: .bottom) proxy.scrollTo(newValue.last, anchor: .bottom)
} }
} }
} }
@ViewBuilder
private var inputView: some View {
TextField.init(text: $inputText) {
Text("Message")
}
.padding()
.onSubmit {
if inputText.count > 0 {
sendAction(inputText)
inputText = ""
}
}
}
var body: some View {
VStack(spacing: 0) {
transcript
inputView
}
.navigationTitle(conversation.effectiveDisplayName)
}
} }
struct ConversationViewWrapper : View { struct ConversationViewWrapper : View {
@ -36,19 +61,23 @@ struct ConversationViewWrapper : View {
@EnvironmentObject private var connection: Connection @EnvironmentObject private var connection: Connection
private func refresh() { private func refresh() {
messages.removeAll()
Task { Task {
self.messages = await connection.messages(in: conversation) ?? .init() self.messages = await connection.messages(in: conversation) ?? .init()
} }
} }
var body: some View { var body: some View {
ConversationView(conversation: conversation, messages: messages) ConversationView(conversation: conversation, messages: messages) { sent in
.onChange(of: conversation, perform: { newValue in Task {
refresh() await connection.send(text: sent, in: conversation)
})
.onAppear {
refresh()
} }
refresh()
}
.onChange(of: conversation, perform: { newValue in
refresh()
})
.onAppear {
refresh()
}
} }
} }

24
KordophoneKit/Sources/KordophoneKit/Connection.swift

@ -9,8 +9,10 @@ public class Connection {
public init() { } public init() { }
private func authenticatedGET(service: String, private func authenticatedRequest(service: String,
queryItems: [String : String] = .init()) method: String = "GET",
body: Data? = nil,
queryItems: [String : String] = .init())
async -> Data? { async -> Data? {
guard let token = token else { guard let token = token else {
return nil return nil
@ -24,7 +26,8 @@ public class Connection {
let finalURL = urlComponents.url! let finalURL = urlComponents.url!
var request = URLRequest(url: finalURL) var request = URLRequest(url: finalURL)
request.httpMethod = "GET" request.httpMethod = method
request.httpBody = body
request.setValue("Bearer: \(token)", forHTTPHeaderField: "Authorization") request.setValue("Bearer: \(token)", forHTTPHeaderField: "Authorization")
return try? await URLSession.shared.data(for: request).0 return try? await URLSession.shared.data(for: request).0
@ -55,7 +58,7 @@ public class Connection {
} }
public func conversations() async -> [Conversation]? { public func conversations() async -> [Conversation]? {
if let data = await authenticatedGET(service: "conversations") { if let data = await authenticatedRequest(service: "conversations") {
if let conversations = try? JSONDecoder().decode([RawConversation].self, from: data) { if let conversations = try? JSONDecoder().decode([RawConversation].self, from: data) {
return conversations.map { return conversations.map {
$0.conversation $0.conversation
@ -67,7 +70,7 @@ public class Connection {
} }
public func messages(in conversation: Conversation) async -> [Message]? { public func messages(in conversation: Conversation) async -> [Message]? {
if let data = await authenticatedGET(service: "messages", queryItems: ["guid" : conversation.guid]) { if let data = await authenticatedRequest(service: "messages", queryItems: ["guid" : conversation.guid]) {
if let messages = try? JSONDecoder().decode([RawMessage].self, from: data) { if let messages = try? JSONDecoder().decode([RawMessage].self, from: data) {
return messages.map { return messages.map {
$0.message $0.message
@ -77,6 +80,17 @@ public class Connection {
return nil return nil
} }
public func send(text: String, in conversation: Conversation) async {
var body = [String : String]()
body["guid"] = conversation.guid
body["body"] = text
let bodyData = try! JSONEncoder().encode(body)
let _ = await authenticatedRequest(service: "sendMessage",
method: "POST",
body: bodyData)
}
} }
extension Connection { extension Connection {

Loading…
Cancel
Save