|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
import KordophoneKit
|
|
|
|
|
|
|
|
struct ConversationView : View {
|
|
|
|
var conversation: Conversation
|
|
|
|
var messages: [Message]
|
|
|
|
var sendAction: (String) -> Void
|
|
|
|
|
|
|
|
@State private var inputText = ""
|
|
|
|
|
|
|
|
@ViewBuilder
|
|
|
|
private var transcript: some View {
|
|
|
|
ScrollViewReader { proxy in
|
|
|
|
ScrollView {
|
|
|
|
LazyVStack {
|
|
|
|
ForEach(messages) { message in
|
|
|
|
if message.sentByMe {
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
MessageViewWrapper(message: message)
|
|
|
|
.id(message)
|
|
|
|
if !message.sentByMe {
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.onChange(of: messages) { newValue in
|
|
|
|
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 {
|
|
|
|
var conversation: Conversation
|
|
|
|
@State private var messages = [Message]()
|
|
|
|
@EnvironmentObject private var connection: Connection
|
|
|
|
@StateObject private var updater = IntervalUpdater(5)
|
|
|
|
|
|
|
|
private func refresh() {
|
|
|
|
Task {
|
|
|
|
self.messages = await connection.messages(in: conversation) ?? .init()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
ConversationView(conversation: conversation, messages: messages) { sent in
|
|
|
|
Task {
|
|
|
|
await connection.send(text: sent, in: conversation)
|
|
|
|
}
|
|
|
|
refresh()
|
|
|
|
}
|
|
|
|
.onChange(of: conversation, perform: { newValue in
|
|
|
|
refresh()
|
|
|
|
})
|
|
|
|
.onAppear {
|
|
|
|
refresh()
|
|
|
|
}
|
|
|
|
.onChange(of: updater.seed) { newValue in
|
|
|
|
refresh()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|