import SwiftUI import XuqmSDK struct ConversationListView: View { @StateObject private var viewModel = ConversationViewModel() @Binding var path: NavigationPath var body: some View { List { if viewModel.totalUnreadCount > 0 { Text("总未读 \(viewModel.totalUnreadCount)") .font(.caption) .foregroundStyle(.secondary) } ForEach(viewModel.filteredConversations, id: \.targetId) { conversation in ConversationRow(conversation: conversation) .contentShape(Rectangle()) .onTapGesture { path.append(AppRoute.chat(targetId: conversation.targetId, targetName: conversation.targetId)) } .swipeActions(edge: .trailing) { Button(role: .destructive) { viewModel.deleteConversation(conversation) } label: { Text("删除") } } .swipeActions(edge: .leading) { Button { viewModel.togglePinned(conversation) } label: { Text(conversation.isPinned ? "取消置顶" : "置顶") } .tint(.orange) Button { viewModel.toggleMuted(conversation) } label: { Text(conversation.isMuted ? "取消静音" : "静音") } .tint(.indigo) } } } .listStyle(.plain) .searchable(text: $viewModel.query, prompt: "搜索会话") .navigationTitle("会话") .toolbar { #if os(iOS) ToolbarItem(placement: .navigationBarTrailing) { Button { viewModel.refresh() } label: { Image(systemName: "arrow.clockwise") } } #endif } .refreshable { viewModel.refresh() } .onAppear { if viewModel.conversations.isEmpty { viewModel.load() } } } } struct ConversationRow: View { let conversation: ConversationData var body: some View { HStack(spacing: 12) { ZStack { Circle() .fill(Color.accentColor.opacity(0.15)) .frame(width: 48, height: 48) Text(String(conversation.targetId.prefix(1).uppercased())) .font(.headline) .foregroundStyle(Color.accentColor) } VStack(alignment: .leading, spacing: 4) { HStack { Text(conversation.targetId) .font(.subheadline) .fontWeight(.semibold) .lineLimit(1) Spacer() if conversation.isPinned { Text("置顶") .font(.caption2) .foregroundStyle(.orange) } Text(formatConversationTime(conversation.lastMsgTime)) .font(.caption) .foregroundStyle(.secondary) } HStack { Text(conversationPreview(conversation)) .font(.caption) .foregroundStyle(.secondary) .lineLimit(1) Spacer() if conversation.unreadCount > 0 && !conversation.isMuted { Text("\(conversation.unreadCount)") .font(.caption2) .fontWeight(.bold) .foregroundStyle(.white) .padding(.horizontal, 6) .padding(.vertical, 2) .background(Color.red) .clipShape(Capsule()) } } } } .padding(.vertical, 4) } }