群聊创建失败提示弹窗问题

This commit is contained in:
2025-09-05 14:17:09 +08:00
parent 9f14b35847
commit 9dceb99a98
2 changed files with 425 additions and 393 deletions

View File

@@ -95,403 +95,424 @@ fun CreateGroupChatScreen() {
systemUiController.setNavigationBarColor(Color.Transparent) systemUiController.setNavigationBarColor(Color.Transparent)
} }
Column( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(AppColors.background) .background(AppColors.background)
) { ) {
// 错误提示 Column(
CreateGroupChatViewModel.errorMessage?.let { error -> 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( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(AppColors.error.copy(alpha = 0.1f)) .padding(horizontal = 16.dp, vertical = 8.dp)
.padding(16.dp) .background(
color = AppColors.inputBackground,
shape = RoundedCornerShape(8.dp)
)
.padding(horizontal = 16.dp, vertical = 13.dp)
) { ) {
Text( Row(
text = error, verticalAlignment = Alignment.CenterVertically
color = AppColors.error, ) {
fontSize = 14.sp Image(
) painter = painterResource(id = R.drawable.rider_pro_nav_search),
} contentDescription = stringResource(R.string.search),
} modifier = Modifier.size(16.dp),
StatusBarSpacer() colorFilter = ColorFilter.tint(AppColors.secondaryText)
)
// 头部 Spacer(modifier = Modifier.width(8.dp))
Row( BasicTextField(
modifier = Modifier value = searchText,
.fillMaxWidth() onValueChange = { searchText = it },
.padding(horizontal = 16.dp, vertical = 12.dp), textStyle = androidx.compose.ui.text.TextStyle(
verticalAlignment = Alignment.CenterVertically color = AppColors.text,
) { fontSize = 14.sp
// 返回按钮 ),
Image( modifier = Modifier.weight(1f),
painter = painterResource(id = R.drawable.rider_pro_back_icon), singleLine = true,
contentDescription = "back", cursorBrush = SolidColor(AppColors.text),
modifier = Modifier decorationBox = { innerTextField ->
.size(24.dp) Box {
.noRippleClickable { if (searchText.text.isEmpty()) {
navController.popBackStack() Text(
}, text = stringResource(R.string.search),
colorFilter = ColorFilter.tint(AppColors.text) color = AppColors.secondaryText,
) fontSize = 14.sp
)
// 标题 }
Text( innerTextField()
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( // Box(
modifier = Modifier // modifier = Modifier
.fillMaxWidth() // .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp) // .padding(horizontal = 16.dp, vertical = 8.dp)
.background( // .background(
color = AppColors.inputBackground, // color = AppColors.inputBackground,
shape = RoundedCornerShape(8.dp) // shape = RoundedCornerShape(8.dp)
) // )
.padding(horizontal = 16.dp, vertical = 13.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))
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()
}
}
)
}
}
// // 搜索栏 // Row(
// Box( // verticalAlignment = Alignment.CenterVertically
// modifier = Modifier // ) {
// .fillMaxWidth() // Image(
// .padding(horizontal = 16.dp, vertical = 8.dp) // painter = painterResource(id = R.drawable.rider_pro_nav_search),
// .background( // contentDescription = stringResource(R.string.search),
// color = AppColors.inputBackground, // modifier = Modifier.size(16.dp),
// shape = RoundedCornerShape(8.dp) // colorFilter = ColorFilter.tint(AppColors.secondaryText)
// ) // )
// .padding(horizontal = 12.dp, vertical = 8.dp) // 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 Box(
// ) {
// 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,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp), .padding(horizontal = 16.dp, vertical = 8.dp)
horizontalArrangement = Arrangement.spacedBy(8.dp) .background(
color = AppColors.inputBackground,
shape = RoundedCornerShape(8.dp)
)
.padding(horizontal = 12.dp, vertical = 8.dp)
) { ) {
items(selectedMembers) { member -> Row(
Column( modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.CenterVertically
modifier = Modifier.width(48.dp) ) {
) { Text(
Box { text = stringResource(R.string.group_name),
CustomAsyncImage( fontSize = 14.sp,
context = context, color = AppColors.text,
imageUrl = member.avatar, modifier = Modifier.width(80.dp)
contentDescription = member.name, )
defaultRes = R.drawable.default_avatar, BasicTextField(
placeholderRes = R.drawable.default_avatar, value = groupName,
errorRes = R.drawable.default_avatar, onValueChange = { groupName = it },
modifier = Modifier textStyle = androidx.compose.ui.text.TextStyle(
.size(48.dp) color = AppColors.text,
.clip(CircleShape) fontSize = 14.sp
) ),
modifier = Modifier
// 删除按钮 .weight(1f),
Box( singleLine = true,
modifier = Modifier cursorBrush = SolidColor(AppColors.text),
.size(20.dp) decorationBox = { innerTextField ->
.background(AppColors.error, CircleShape) Box(Modifier.fillMaxWidth()) {
.align(Alignment.TopEnd) if (groupName.text.isEmpty()) {
.noRippleClickable { Text(
// 删除成员时同时更新选中状态 text = stringResource(R.string.group_name_hint),
val (newSelectedMemberIds, newSelectedMembers) = CreateGroupChatViewModel.removeSelectedMember( color = AppColors.inputHint,
member, selectedMemberIds, selectedMembers fontSize = 14.sp
) )
selectedMemberIds = newSelectedMemberIds }
selectedMembers = newSelectedMembers innerTextField()
},
contentAlignment = Alignment.Center
) {
Text(
text = "×",
color = AppColors.mainText,
fontSize = 14.sp,
fontWeight = FontWeight.Bold
)
} }
} }
)
}
}
// 名称显示 // 已选成员列表
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(
text = if (member.name.length > 5) { text = error,
member.name.substring(0, 5) + "..." modifier = Modifier
} else { .padding(16.dp)
member.name .fillMaxWidth(),
}, color = Color.Red,
fontSize = 12.sp, fontSize = 14.sp,
textAlign = androidx.compose.ui.text.style.TextAlign.Center
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
)
}
}
} }
} }

View File

@@ -28,6 +28,7 @@ import com.tencent.imsdk.v2.V2TIMConversationResult
import com.tencent.imsdk.v2.V2TIMManager import com.tencent.imsdk.v2.V2TIMManager
import com.tencent.imsdk.v2.V2TIMMessage import com.tencent.imsdk.v2.V2TIMMessage
import com.tencent.imsdk.v2.V2TIMValueCallback import com.tencent.imsdk.v2.V2TIMValueCallback
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
@@ -59,16 +60,26 @@ object CreateGroupChatViewModel : ViewModel() {
true true
} else { } else {
isLoading = false isLoading = false
errorMessage = "创建群聊失败: ${response.message()}" val errorMsg = "创建群聊失败: ${response.message()}"
showToast(errorMsg)
false false
} }
} catch (e: Exception) { } catch (e: Exception) {
isLoading = false isLoading = false
errorMessage = "创建群聊失败: ${e.message}" val errorMsg = "创建群聊失败: ${e.message}"
showToast(errorMsg)
false false
} }
} }
private fun showToast(message: String) {
errorMessage = message
viewModelScope.launch {
delay(3000)
errorMessage = null
}
}
// 清除错误信息 // 清除错误信息
fun clearError() { fun clearError() {
errorMessage = null errorMessage = null