Implements signals
This commit is contained in:
@@ -11,6 +11,8 @@ struct ChatTranscriptView: View
|
||||
{
|
||||
@Binding var model: ViewModel
|
||||
|
||||
@Environment(\.xpcClient) private var xpcClient
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack(spacing: 17.0) {
|
||||
@@ -18,11 +20,26 @@ struct ChatTranscriptView: View
|
||||
MessageCellView(message: message)
|
||||
.id(message.id)
|
||||
.scaleEffect(CGSize(width: 1.0, height: -1.0))
|
||||
.transition(
|
||||
.push(from: .bottom)
|
||||
.combined(with: .opacity)
|
||||
)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.scaleEffect(CGSize(width: 1.0, height: -1.0))
|
||||
.task { await watchForMessageListChanges() }
|
||||
}
|
||||
|
||||
private func watchForMessageListChanges() async {
|
||||
for await event in xpcClient.eventStream() {
|
||||
if case let .messagesUpdated(conversationId) = event {
|
||||
if conversationId == model.displayedConversation {
|
||||
model.setNeedsReload()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Types
|
||||
@@ -32,7 +49,8 @@ struct ChatTranscriptView: View
|
||||
{
|
||||
var messages: [Display.Message]
|
||||
var displayedConversation: Display.Conversation.ID? = nil
|
||||
|
||||
var needsReload: Bool = true
|
||||
|
||||
init(messages: [Display.Message] = []) {
|
||||
self.messages = messages
|
||||
observeDisplayedConversation()
|
||||
@@ -45,21 +63,37 @@ struct ChatTranscriptView: View
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self else { return }
|
||||
|
||||
await loadMessages()
|
||||
setNeedsReload()
|
||||
observeDisplayedConversation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setNeedsReload() {
|
||||
needsReload = true
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self else { return }
|
||||
await reloadMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private func loadMessages() async {
|
||||
self.messages = []
|
||||
func reloadMessages() async {
|
||||
guard needsReload else { return }
|
||||
needsReload = false
|
||||
|
||||
guard let displayedConversation else { return }
|
||||
|
||||
do {
|
||||
let client = XPCClient()
|
||||
let messages = try await client.getMessages(conversationId: displayedConversation)
|
||||
self.messages = messages.map { Display.Message(from: $0) }
|
||||
let clientMessages = try await client.getMessages(conversationId: displayedConversation)
|
||||
.map { Display.Message(from: $0) }
|
||||
|
||||
let newMessages = Set(clientMessages).subtracting(Set(self.messages))
|
||||
|
||||
let animation: Animation? = newMessages.count == 1 ? .default : nil
|
||||
withAnimation(animation) {
|
||||
self.messages = clientMessages
|
||||
}
|
||||
} catch {
|
||||
print("Message fetch error: \(error)")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user