群聊创建失败提示弹窗问题
This commit is contained in:
@@ -55,7 +55,7 @@ fun CreateGroupChatScreen() {
|
||||
val navController = LocalNavController.current
|
||||
val systemUiController = rememberSystemUiController()
|
||||
val context = LocalContext.current
|
||||
|
||||
|
||||
// 状态管理
|
||||
var groupName by remember { mutableStateOf(TextFieldValue("")) }
|
||||
var searchText by remember { mutableStateOf(TextFieldValue("")) }
|
||||
@@ -63,23 +63,23 @@ fun CreateGroupChatScreen() {
|
||||
var selectedMemberIds by remember { mutableStateOf<Set<String>>(emptySet()) }
|
||||
var pagerState = rememberPagerState(pageCount = { 2 })
|
||||
var scope = rememberCoroutineScope()
|
||||
|
||||
|
||||
// LazyRow状态管理
|
||||
val lazyRowState = rememberLazyListState()
|
||||
|
||||
|
||||
// 清除错误信息
|
||||
LaunchedEffect(groupName.text, searchText.text) {
|
||||
if (CreateGroupChatViewModel.errorMessage != null) {
|
||||
CreateGroupChatViewModel.clearError()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 监听页面切换,清除当前tab的选中状态(但保留已选成员列表)
|
||||
LaunchedEffect(pagerState.currentPage) {
|
||||
// 不清除selectedMemberIds,因为我们需要保持跨tab的选中状态
|
||||
// 这样用户可以在AI智能体和朋友之间切换,选中的状态会保持
|
||||
}
|
||||
|
||||
|
||||
// 监听selectedMembers变化,当有新成员添加时自动滚动到最后一个
|
||||
LaunchedEffect(selectedMembers.size) {
|
||||
if (selectedMembers.isNotEmpty()) {
|
||||
@@ -88,410 +88,431 @@ fun CreateGroupChatScreen() {
|
||||
lazyRowState.animateScrollToItem(selectedMembers.size - 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val navigationBarPadding = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
|
||||
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
systemUiController.setNavigationBarColor(Color.Transparent)
|
||||
}
|
||||
|
||||
Column(
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(AppColors.background)
|
||||
) {
|
||||
// 错误提示
|
||||
CreateGroupChatViewModel.errorMessage?.let { error ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
) {
|
||||
StatusBarSpacer()
|
||||
|
||||
// 头部
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// 返回按钮
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_back_icon),
|
||||
contentDescription = "back",
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.noRippleClickable {
|
||||
navController.popBackStack()
|
||||
},
|
||||
colorFilter = ColorFilter.tint(AppColors.text)
|
||||
)
|
||||
|
||||
// 标题
|
||||
Text(
|
||||
text = stringResource(R.string.create_group_chat),
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.W700,
|
||||
color = AppColors.text,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 16.dp)
|
||||
)
|
||||
|
||||
// 一键创建按钮
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.noRippleClickable {
|
||||
// 一键创建逻辑
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
|
||||
contentDescription = "quick create",
|
||||
modifier = Modifier.size(16.dp),
|
||||
colorFilter = ColorFilter.tint(AppColors.main)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.quick_create),
|
||||
fontSize = 14.sp,
|
||||
color = AppColors.main
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索栏
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(AppColors.error.copy(alpha = 0.1f))
|
||||
.padding(16.dp)
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.background(
|
||||
color = AppColors.inputBackground,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.padding(horizontal = 16.dp, vertical = 13.dp)
|
||||
) {
|
||||
Text(
|
||||
text = error,
|
||||
color = AppColors.error,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
}
|
||||
StatusBarSpacer()
|
||||
|
||||
// 头部
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// 返回按钮
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_back_icon),
|
||||
contentDescription = "back",
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.noRippleClickable {
|
||||
navController.popBackStack()
|
||||
},
|
||||
colorFilter = ColorFilter.tint(AppColors.text)
|
||||
)
|
||||
|
||||
// 标题
|
||||
Text(
|
||||
text = stringResource(R.string.create_group_chat),
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.W700,
|
||||
color = AppColors.text,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 16.dp)
|
||||
)
|
||||
|
||||
// 一键创建按钮
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.noRippleClickable {
|
||||
// 一键创建逻辑
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
||||
contentDescription = stringResource(R.string.search),
|
||||
modifier = Modifier.size(16.dp),
|
||||
colorFilter = ColorFilter.tint(AppColors.secondaryText)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
BasicTextField(
|
||||
value = searchText,
|
||||
onValueChange = { searchText = it },
|
||||
textStyle = androidx.compose.ui.text.TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 14.sp
|
||||
),
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true,
|
||||
cursorBrush = SolidColor(AppColors.text),
|
||||
decorationBox = { innerTextField ->
|
||||
Box {
|
||||
if (searchText.text.isEmpty()) {
|
||||
Text(
|
||||
text = stringResource(R.string.search),
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
innerTextField()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
|
||||
contentDescription = "quick create",
|
||||
modifier = Modifier.size(16.dp),
|
||||
colorFilter = ColorFilter.tint(AppColors.main)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.quick_create),
|
||||
fontSize = 14.sp,
|
||||
color = AppColors.main
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索栏
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.background(
|
||||
color = AppColors.inputBackground,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.padding(horizontal = 16.dp, vertical = 13.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
||||
contentDescription = stringResource(R.string.search),
|
||||
modifier = Modifier.size(16.dp),
|
||||
colorFilter = ColorFilter.tint(AppColors.secondaryText)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
BasicTextField(
|
||||
value = searchText,
|
||||
onValueChange = { searchText = it },
|
||||
textStyle = androidx.compose.ui.text.TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 14.sp
|
||||
),
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true,
|
||||
cursorBrush = SolidColor(AppColors.text),
|
||||
decorationBox = { innerTextField ->
|
||||
Box {
|
||||
if (searchText.text.isEmpty()) {
|
||||
Text(
|
||||
text = stringResource(R.string.search),
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
innerTextField()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
// // 搜索栏
|
||||
// Box(
|
||||
// modifier = Modifier
|
||||
// .fillMaxWidth()
|
||||
// .padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
// .background(
|
||||
// color = AppColors.inputBackground,
|
||||
// shape = RoundedCornerShape(8.dp)
|
||||
// )
|
||||
// .padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
// ) {
|
||||
|
||||
// // 搜索栏
|
||||
// Box(
|
||||
// modifier = Modifier
|
||||
// .fillMaxWidth()
|
||||
// .padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
// .background(
|
||||
// color = AppColors.inputBackground,
|
||||
// shape = RoundedCornerShape(8.dp)
|
||||
// )
|
||||
// .padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
// ) {
|
||||
// Row(
|
||||
// verticalAlignment = Alignment.CenterVertically
|
||||
// ) {
|
||||
// Image(
|
||||
// painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
||||
// contentDescription = stringResource(R.string.search),
|
||||
// modifier = Modifier.size(16.dp),
|
||||
// colorFilter = ColorFilter.tint(AppColors.secondaryText)
|
||||
// )
|
||||
// Spacer(modifier = Modifier.width(8.dp))
|
||||
// if (searchText.text.isEmpty()) {
|
||||
// Text(
|
||||
// text = stringResource(R.string.search),
|
||||
// color = AppColors.secondaryText,
|
||||
// fontSize = 14.sp
|
||||
// )
|
||||
// }
|
||||
// innerTextField()
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
|
||||
// Row(
|
||||
// verticalAlignment = Alignment.CenterVertically
|
||||
// ) {
|
||||
// Image(
|
||||
// painter = painterResource(id = R.drawable.rider_pro_nav_search),
|
||||
// contentDescription = stringResource(R.string.search),
|
||||
// modifier = Modifier.size(16.dp),
|
||||
// colorFilter = ColorFilter.tint(AppColors.secondaryText)
|
||||
// )
|
||||
// Spacer(modifier = Modifier.width(8.dp))
|
||||
// if (searchText.text.isEmpty()) {
|
||||
// Text(
|
||||
// text = stringResource(R.string.search),
|
||||
// color = AppColors.secondaryText,
|
||||
// fontSize = 14.sp
|
||||
// )
|
||||
// }
|
||||
// innerTextField()
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
|
||||
// 群聊名称输入:同一圆角灰色矩形容器
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.background(
|
||||
color = AppColors.inputBackground,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.group_name),
|
||||
fontSize = 14.sp,
|
||||
color = AppColors.text,
|
||||
modifier = Modifier.width(80.dp)
|
||||
)
|
||||
BasicTextField(
|
||||
value = groupName,
|
||||
onValueChange = { groupName = it },
|
||||
textStyle = androidx.compose.ui.text.TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 14.sp
|
||||
),
|
||||
modifier = Modifier
|
||||
.weight(1f),
|
||||
singleLine = true,
|
||||
cursorBrush = SolidColor(AppColors.text),
|
||||
decorationBox = { innerTextField ->
|
||||
Box(Modifier.fillMaxWidth()) {
|
||||
if (groupName.text.isEmpty()) {
|
||||
Text(
|
||||
text = stringResource(R.string.group_name_hint),
|
||||
color = AppColors.inputHint,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
innerTextField()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 已选成员列表
|
||||
if (selectedMembers.isNotEmpty()) {
|
||||
// 显示选中成员数量
|
||||
/* Text(
|
||||
text = "已选择 ${selectedMembers.size} 个成员",
|
||||
fontSize = 14.sp,
|
||||
color = AppColors.secondaryText,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
|
||||
)*/
|
||||
LazyRow(
|
||||
state = lazyRowState,
|
||||
// 群聊名称输入:同一圆角灰色矩形容器
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.background(
|
||||
color = AppColors.inputBackground,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
) {
|
||||
items(selectedMembers) { member ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.width(48.dp)
|
||||
) {
|
||||
Box {
|
||||
CustomAsyncImage(
|
||||
context = context,
|
||||
imageUrl = member.avatar,
|
||||
contentDescription = member.name,
|
||||
defaultRes = R.drawable.default_avatar,
|
||||
placeholderRes = R.drawable.default_avatar,
|
||||
errorRes = R.drawable.default_avatar,
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
|
||||
// 删除按钮
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.background(AppColors.error, CircleShape)
|
||||
.align(Alignment.TopEnd)
|
||||
.noRippleClickable {
|
||||
// 删除成员时同时更新选中状态
|
||||
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.removeSelectedMember(
|
||||
member, selectedMemberIds, selectedMembers
|
||||
)
|
||||
selectedMemberIds = newSelectedMemberIds
|
||||
selectedMembers = newSelectedMembers
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "×",
|
||||
color = AppColors.mainText,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.group_name),
|
||||
fontSize = 14.sp,
|
||||
color = AppColors.text,
|
||||
modifier = Modifier.width(80.dp)
|
||||
)
|
||||
BasicTextField(
|
||||
value = groupName,
|
||||
onValueChange = { groupName = it },
|
||||
textStyle = androidx.compose.ui.text.TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 14.sp
|
||||
),
|
||||
modifier = Modifier
|
||||
.weight(1f),
|
||||
singleLine = true,
|
||||
cursorBrush = SolidColor(AppColors.text),
|
||||
decorationBox = { innerTextField ->
|
||||
Box(Modifier.fillMaxWidth()) {
|
||||
if (groupName.text.isEmpty()) {
|
||||
Text(
|
||||
text = stringResource(R.string.group_name_hint),
|
||||
color = AppColors.inputHint,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
}
|
||||
innerTextField()
|
||||
}
|
||||
}
|
||||
|
||||
// 名称显示
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 已选成员列表
|
||||
if (selectedMembers.isNotEmpty()) {
|
||||
// 显示选中成员数量
|
||||
/* Text(
|
||||
text = "已选择 ${selectedMembers.size} 个成员",
|
||||
fontSize = 14.sp,
|
||||
color = AppColors.secondaryText,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
|
||||
)*/
|
||||
LazyRow(
|
||||
state = lazyRowState,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
items(selectedMembers) { member ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.width(48.dp)
|
||||
) {
|
||||
Box {
|
||||
CustomAsyncImage(
|
||||
context = context,
|
||||
imageUrl = member.avatar,
|
||||
contentDescription = member.name,
|
||||
defaultRes = R.drawable.default_avatar,
|
||||
placeholderRes = R.drawable.default_avatar,
|
||||
errorRes = R.drawable.default_avatar,
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
|
||||
// 删除按钮
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.background(AppColors.error, CircleShape)
|
||||
.align(Alignment.TopEnd)
|
||||
.noRippleClickable {
|
||||
// 删除成员时同时更新选中状态
|
||||
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.removeSelectedMember(
|
||||
member, selectedMemberIds, selectedMembers
|
||||
)
|
||||
selectedMemberIds = newSelectedMemberIds
|
||||
selectedMembers = newSelectedMembers
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "×",
|
||||
color = AppColors.mainText,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 名称显示
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = if (member.name.length > 5) {
|
||||
member.name.substring(0, 5) + "..."
|
||||
} else {
|
||||
member.name
|
||||
},
|
||||
fontSize = 12.sp,
|
||||
|
||||
color = AppColors.text,
|
||||
maxLines = 1,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.wrapContentWidth(Alignment.CenterHorizontally)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tab切换
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.Bottom
|
||||
) {
|
||||
TabItem(
|
||||
text = stringResource(R.string.chat_ai),
|
||||
isSelected = pagerState.currentPage == 0,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(0)
|
||||
}
|
||||
}
|
||||
)
|
||||
TabSpacer()
|
||||
TabItem(
|
||||
text = stringResource(R.string.chat_friend),
|
||||
isSelected = pagerState.currentPage == 1,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(1)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 内容区域 - 自适应填满剩余高度
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f) // 这里让列表占据剩余空间
|
||||
) {
|
||||
when (it) {
|
||||
0 -> {
|
||||
// AI智能体列表
|
||||
AiAgentListScreen(
|
||||
searchText = searchText.text,
|
||||
selectedMemberIds = selectedMemberIds,
|
||||
onMemberSelect = { member ->
|
||||
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.toggleMemberSelection(
|
||||
member, selectedMemberIds, selectedMembers
|
||||
)
|
||||
selectedMemberIds = newSelectedMemberIds
|
||||
selectedMembers = newSelectedMembers
|
||||
}
|
||||
)
|
||||
}
|
||||
1 -> {
|
||||
// 朋友列表
|
||||
FriendListScreen(
|
||||
searchText = searchText.text,
|
||||
selectedMemberIds = selectedMemberIds,
|
||||
onMemberSelect = { member ->
|
||||
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.toggleMemberSelection(
|
||||
member, selectedMemberIds, selectedMembers
|
||||
)
|
||||
selectedMemberIds = newSelectedMemberIds
|
||||
selectedMembers = newSelectedMembers
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建群聊按钮 - 固定在底部
|
||||
Button(
|
||||
onClick = {
|
||||
// 创建群聊逻辑
|
||||
if (selectedMembers.isNotEmpty()) {
|
||||
scope.launch {
|
||||
val success = CreateGroupChatViewModel.createGroupChat(
|
||||
groupName = groupName.text,
|
||||
selectedMembers = selectedMembers,
|
||||
context = context
|
||||
)
|
||||
if (success) {
|
||||
navController.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = navigationBarPadding + 16.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = AppColors.main,
|
||||
contentColor = AppColors.mainText,
|
||||
disabledContainerColor = AppColors.disabledBackground,
|
||||
disabledContentColor = AppColors.text
|
||||
),
|
||||
shape = RoundedCornerShape(24.dp),
|
||||
enabled = groupName.text.isNotEmpty() && selectedMembers.isNotEmpty() && !CreateGroupChatViewModel.isLoading
|
||||
) {
|
||||
if (CreateGroupChatViewModel.isLoading) {
|
||||
Text(
|
||||
text = "创建中...",
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.W600
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = stringResource(R.string.create_group_chat),
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.W600
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 居中显示的错误提示弹窗
|
||||
CreateGroupChatViewModel.errorMessage?.let { error ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(24.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.Center), // 在Box中居中对齐
|
||||
horizontalAlignment = Alignment.CenterHorizontally, // 水平居中
|
||||
verticalArrangement = Arrangement.Center // 垂直居中
|
||||
) {
|
||||
androidx.compose.material3.Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.8f),
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = if (member.name.length > 5) {
|
||||
member.name.substring(0, 5) + "..."
|
||||
} else {
|
||||
member.name
|
||||
},
|
||||
fontSize = 12.sp,
|
||||
|
||||
color = AppColors.text,
|
||||
maxLines = 1,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.wrapContentWidth(Alignment.CenterHorizontally)
|
||||
text = error,
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth(),
|
||||
color = Color.Red,
|
||||
fontSize = 14.sp,
|
||||
textAlign = androidx.compose.ui.text.style.TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tab切换
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.Bottom
|
||||
) {
|
||||
TabItem(
|
||||
text = stringResource(R.string.chat_ai),
|
||||
isSelected = pagerState.currentPage == 0,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(0)
|
||||
}
|
||||
}
|
||||
)
|
||||
TabSpacer()
|
||||
TabItem(
|
||||
text = stringResource(R.string.chat_friend),
|
||||
isSelected = pagerState.currentPage == 1,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(1)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 内容区域 - 自适应填满剩余高度
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f) // 这里让列表占据剩余空间
|
||||
) {
|
||||
when (it) {
|
||||
0 -> {
|
||||
// AI智能体列表
|
||||
AiAgentListScreen(
|
||||
searchText = searchText.text,
|
||||
selectedMemberIds = selectedMemberIds,
|
||||
onMemberSelect = { member ->
|
||||
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.toggleMemberSelection(
|
||||
member, selectedMemberIds, selectedMembers
|
||||
)
|
||||
selectedMemberIds = newSelectedMemberIds
|
||||
selectedMembers = newSelectedMembers
|
||||
}
|
||||
)
|
||||
}
|
||||
1 -> {
|
||||
// 朋友列表
|
||||
FriendListScreen(
|
||||
searchText = searchText.text,
|
||||
selectedMemberIds = selectedMemberIds,
|
||||
onMemberSelect = { member ->
|
||||
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.toggleMemberSelection(
|
||||
member, selectedMemberIds, selectedMembers
|
||||
)
|
||||
selectedMemberIds = newSelectedMemberIds
|
||||
selectedMembers = newSelectedMembers
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建群聊按钮 - 固定在底部
|
||||
Button(
|
||||
onClick = {
|
||||
// 创建群聊逻辑
|
||||
if (selectedMembers.isNotEmpty()) {
|
||||
scope.launch {
|
||||
val success = CreateGroupChatViewModel.createGroupChat(
|
||||
groupName = groupName.text,
|
||||
selectedMembers = selectedMembers,
|
||||
context = context
|
||||
)
|
||||
if (success) {
|
||||
navController.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = navigationBarPadding + 16.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = AppColors.main,
|
||||
contentColor = AppColors.mainText,
|
||||
disabledContainerColor = AppColors.disabledBackground,
|
||||
disabledContentColor = AppColors.text
|
||||
),
|
||||
shape = RoundedCornerShape(24.dp),
|
||||
enabled = groupName.text.isNotEmpty() && selectedMembers.isNotEmpty() && !CreateGroupChatViewModel.isLoading
|
||||
) {
|
||||
if (CreateGroupChatViewModel.isLoading) {
|
||||
Text(
|
||||
text = "创建中...",
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.W600
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = stringResource(R.string.create_group_chat),
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.W600
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.tencent.imsdk.v2.V2TIMConversationResult
|
||||
import com.tencent.imsdk.v2.V2TIMManager
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import com.tencent.imsdk.v2.V2TIMValueCallback
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
@@ -35,11 +36,11 @@ import kotlin.coroutines.suspendCoroutine
|
||||
object CreateGroupChatViewModel : ViewModel() {
|
||||
val accountService: AccountService = AccountServiceImpl()
|
||||
val userService: UserService = UserServiceImpl()
|
||||
|
||||
|
||||
// 状态管理
|
||||
var isLoading by mutableStateOf(false)
|
||||
var errorMessage by mutableStateOf<String?>(null)
|
||||
|
||||
|
||||
// 创建群聊
|
||||
suspend fun createGroupChat(
|
||||
groupName: String,
|
||||
@@ -48,32 +49,42 @@ object CreateGroupChatViewModel : ViewModel() {
|
||||
): Boolean {
|
||||
return try {
|
||||
isLoading = true
|
||||
|
||||
|
||||
// 根据isAi属性分别获取userIds和promptIds
|
||||
val userIds = selectedMembers.filter { !it.isAi }.map { it.id }
|
||||
val promptIds = selectedMembers.filter { it.isAi }.map { it.id }
|
||||
|
||||
|
||||
val response = accountService.createGroupChat(groupName, userIds, promptIds)
|
||||
if (response.isSuccessful && response.body() != null) {
|
||||
isLoading = false
|
||||
true
|
||||
} else {
|
||||
isLoading = false
|
||||
errorMessage = "创建群聊失败: ${response.message()}"
|
||||
val errorMsg = "创建群聊失败: ${response.message()}"
|
||||
showToast(errorMsg)
|
||||
false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
isLoading = false
|
||||
errorMessage = "创建群聊失败: ${e.message}"
|
||||
val errorMsg = "创建群聊失败: ${e.message}"
|
||||
showToast(errorMsg)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun showToast(message: String) {
|
||||
errorMessage = message
|
||||
viewModelScope.launch {
|
||||
delay(3000)
|
||||
errorMessage = null
|
||||
}
|
||||
}
|
||||
|
||||
// 清除错误信息
|
||||
fun clearError() {
|
||||
errorMessage = null
|
||||
}
|
||||
|
||||
|
||||
// 添加成员到选中列表
|
||||
fun addSelectedMember(member: GroupMember, selectedMemberIds: Set<String>, selectedMembers: List<GroupMember>): Pair<Set<String>, List<GroupMember>> {
|
||||
val newSelectedMemberIds = selectedMemberIds + member.id
|
||||
@@ -84,14 +95,14 @@ object CreateGroupChatViewModel : ViewModel() {
|
||||
}
|
||||
return Pair(newSelectedMemberIds, newSelectedMembers)
|
||||
}
|
||||
|
||||
|
||||
// 从选中列表移除成员
|
||||
fun removeSelectedMember(member: GroupMember, selectedMemberIds: Set<String>, selectedMembers: List<GroupMember>): Pair<Set<String>, List<GroupMember>> {
|
||||
val newSelectedMemberIds = selectedMemberIds - member.id
|
||||
val newSelectedMembers = selectedMembers.filter { it.id != member.id }
|
||||
return Pair(newSelectedMemberIds, newSelectedMembers)
|
||||
}
|
||||
|
||||
|
||||
// 切换成员选中状态
|
||||
fun toggleMemberSelection(member: GroupMember, selectedMemberIds: Set<String>, selectedMembers: List<GroupMember>): Pair<Set<String>, List<GroupMember>> {
|
||||
return if (selectedMemberIds.contains(member.id)) {
|
||||
@@ -100,4 +111,4 @@ object CreateGroupChatViewModel : ViewModel() {
|
||||
addSelectedMember(member, selectedMemberIds, selectedMembers)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user