Private
Public Access
1
0
Files
Kordophone/kordophone2/ConversationListView.swift

94 lines
2.7 KiB
Swift
Raw Normal View History

2025-08-24 16:24:21 -07:00
//
// ConversationListView.swift
// kordophone2
//
// Created by James Magahern on 8/24/25.
//
import SwiftUI
struct ConversationListView: View
{
@Binding var model: ViewModel
2025-08-24 18:41:42 -07:00
@Environment(\.xpcClient) private var xpcClient
2025-08-24 16:24:21 -07:00
var body: some View {
List($model.conversations, selection: $model.selectedConversations) { conv in
VStack(alignment: .leading) {
Text(conv.wrappedValue.displayName)
.bold()
Text(conv.wrappedValue.messagePreview)
}
2025-08-24 18:41:42 -07:00
.id(conv.id)
2025-08-24 16:24:21 -07:00
.padding(8.0)
}
.listStyle(.sidebar)
2025-08-24 18:41:42 -07:00
.task { await watchForConversationListChanges() }
}
private func watchForConversationListChanges() async {
for await event in xpcClient.eventStream() {
switch event {
case .conversationsUpdated:
model.setNeedsReload()
case .messagesUpdated(_):
model.setNeedsReload()
case .updateStreamReconnected:
model.setNeedsReload()
default:
break
}
}
2025-08-24 16:24:21 -07:00
}
// MARK: - Types
@Observable
class ViewModel
{
var conversations: [Display.Conversation]
var selectedConversations: Set<Display.Conversation.ID>
2025-08-24 18:41:42 -07:00
private var needsReload: Bool = true
2025-08-24 16:24:21 -07:00
public init(conversations: [Display.Conversation] = []) {
self.conversations = conversations
self.selectedConversations = Set()
2025-08-24 18:41:42 -07:00
setNeedsReload()
}
func setNeedsReload() {
needsReload = true
Task { @MainActor [weak self] in
guard let self else { return }
await reloadConversations()
}
}
func reloadConversations() async {
guard needsReload else { return }
needsReload = false
do {
let client = XPCClient()
let clientConversations = try await client.getConversations()
.map { Display.Conversation(from: $0) }
self.conversations = clientConversations
} catch {
print("Error reloading conversations: \(error)")
}
2025-08-24 16:24:21 -07:00
}
}
}
#Preview {
@Previewable @State var viewModel = ConversationListView.ViewModel(conversations: [
.init(id: "asdf", name: "Cool", participants: ["me"], messagePreview: "Hello there"),
.init(id: "gjkl", name: "Nice", participants: ["me"], messagePreview: "How are you"),
])
ConversationListView(model: $viewModel)
}