102 lines
4.4 KiB
Swift
102 lines
4.4 KiB
Swift
import SwiftUI
|
|
|
|
struct ConversationListView: View {
|
|
var appState: AppState
|
|
@Bindable var viewModel: ConversationListVM
|
|
@State private var showNewConversation = false
|
|
@State private var showProfile = false
|
|
@State private var selectedConversation: Conversation?
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
List {
|
|
// Invitations section
|
|
if !viewModel.invitations.isEmpty {
|
|
Section {
|
|
ForEach(viewModel.invitations) { invitation in
|
|
InvitationBanner(
|
|
invitation: invitation,
|
|
onAccept: {
|
|
Task {
|
|
let (success, _) = await appState.chatClient.acceptInvitation(convId: invitation.conversationId)
|
|
if success {
|
|
await viewModel.refresh(chatClient: appState.chatClient)
|
|
}
|
|
}
|
|
},
|
|
onDecline: {
|
|
Task {
|
|
_ = await appState.chatClient.declineInvitation(convId: invitation.conversationId)
|
|
await viewModel.refresh(chatClient: appState.chatClient)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
} header: {
|
|
Text("Invitations")
|
|
}
|
|
}
|
|
|
|
// Conversations section
|
|
Section {
|
|
ForEach(viewModel.conversations) { conversation in
|
|
NavigationLink(value: conversation) {
|
|
ConversationRowView(
|
|
conversation: conversation,
|
|
currentUserId: appState.currentUser?.id ?? "",
|
|
isOnline: conversation.dmPartnerId(currentUserId: appState.currentUser?.id ?? "")
|
|
.map { viewModel.onlineUsers.contains($0) } ?? false,
|
|
unreadCount: viewModel.unreadCounts[conversation.id] ?? 0,
|
|
avatarData: viewModel.avatarCache[conversation.id]
|
|
)
|
|
}
|
|
.contextMenu {
|
|
Button(conversation.isFavorite ? "Remove from Favorites" : "Add to Favorites") {
|
|
viewModel.toggleFavorite(convId: conversation.id, email: appState.email)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle("Chats")
|
|
.navigationDestination(for: Conversation.self) { conversation in
|
|
ChatView(
|
|
conversation: conversation,
|
|
appState: appState,
|
|
conversationListVM: viewModel
|
|
)
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
ConnectionIndicator(status: appState.connectionStatus)
|
|
}
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
HStack {
|
|
Button(action: { showProfile = true }) {
|
|
Image(systemName: "person.circle")
|
|
}
|
|
Button(action: { showNewConversation = true }) {
|
|
Image(systemName: "square.and.pencil")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.refreshable {
|
|
await viewModel.refresh(chatClient: appState.chatClient)
|
|
}
|
|
.sheet(isPresented: $showNewConversation) {
|
|
NewConversationSheet(appState: appState) { convId in
|
|
showNewConversation = false
|
|
await viewModel.refresh(chatClient: appState.chatClient)
|
|
}
|
|
}
|
|
.sheet(isPresented: $showProfile) {
|
|
ProfileView(appState: appState, isOwnProfile: true)
|
|
}
|
|
.task {
|
|
await viewModel.load(chatClient: appState.chatClient, email: appState.email)
|
|
}
|
|
}
|
|
}
|
|
}
|