XuqmGroup-iOSSDK/XuqmDemo/Sources/Views/ConversationListView.swift
XuqmGroup e7067d03cb feat(sdk): 更新 SDK 设计文档和 API 重构
- 添加 expiresAt 和 refreshUserSig 参数支持自动续签
- 修改 PushSDK 初始化方式,自动完成设备注册和厂商初始化
- 调整过期续签策略,从提前 15 分钟改为提前 5 分钟触发
- 重构 RN SDK 文档结构,简化安装和使用方式
- 更新统一登录流程,支持 profile 信息传递
- 添加 IM 数据库自动隔离功能
- 修复 Android 群消息聚合问题
- 补充自动化测试验证和错误处理机制
2026-05-01 21:27:39 +08:00

129 行
4.3 KiB
Swift

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)
}
}