消息列表和聊天时调整
This commit is contained in:
@@ -8,6 +8,7 @@ import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
@@ -49,6 +50,7 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
@@ -229,7 +231,8 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
|
||||
modifier = Modifier
|
||||
.size(28.dp)
|
||||
.noRippleClickable {
|
||||
isMenuExpanded = true
|
||||
// 跳转到群聊信息页面
|
||||
navController.navigate("GroupChatInfo/$groupId")
|
||||
},
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(AppColors.text)
|
||||
@@ -276,9 +279,8 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(1.dp)
|
||||
.background(AppColors.decentBackground)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
GroupChatInput(
|
||||
onSendImage = { uri ->
|
||||
uri?.let {
|
||||
@@ -294,7 +296,7 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(AppColors.decentBackground)
|
||||
.background(AppColors.background)
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
LazyColumn(
|
||||
@@ -306,23 +308,31 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
|
||||
val chatList = groupMessagesByTime(viewModel.getDisplayChatList(), viewModel)
|
||||
items(chatList.size, key = { index -> chatList[index].msgId + UUID.randomUUID().toString()}) { index ->
|
||||
val item = chatList[index]
|
||||
if (item.showTimeDivider) {
|
||||
val calendar = java.util.Calendar.getInstance()
|
||||
calendar.timeInMillis = item.timestamp
|
||||
Text(
|
||||
text = calendar.time.formatChatTime(context),
|
||||
style = TextStyle(
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 14.sp,
|
||||
textAlign = TextAlign.Center
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp)
|
||||
Column {
|
||||
if (item.showTimeDivider) {
|
||||
val calendar = java.util.Calendar.getInstance()
|
||||
calendar.timeInMillis = item.timestamp
|
||||
Text(
|
||||
text = calendar.time.formatChatTime(context),
|
||||
style = TextStyle(
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 11.sp,
|
||||
textAlign = TextAlign.Center
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp)
|
||||
)
|
||||
}
|
||||
// 获取上一个item的userId,用于判断是否显示头像和昵称
|
||||
val previousItem = if (index < chatList.size - 1) chatList[index + 1] else null
|
||||
val showAvatarAndNickname = previousItem?.userId != item.userId
|
||||
GroupChatItem(
|
||||
item = item,
|
||||
currentUserId = viewModel.myProfile?.trtcUserId!!,
|
||||
showAvatarAndNickname = showAvatarAndNickname
|
||||
)
|
||||
}
|
||||
|
||||
GroupChatItem(item = item, viewModel.myProfile?.trtcUserId!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +355,7 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
|
||||
text = "${goToNewCount} 条新消息",
|
||||
style = TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 16.sp,
|
||||
fontSize = 12.sp,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -390,7 +400,7 @@ fun GroupChatSelfItem(item: ChatItem) {
|
||||
vertical = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 8.dp else 0.dp),
|
||||
horizontal = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 16.dp else 0.dp)
|
||||
)
|
||||
.padding(bottom = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 3.dp else 0.dp))
|
||||
|
||||
) {
|
||||
when (item.messageType) {
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
|
||||
@@ -441,7 +451,7 @@ fun GroupChatSelfItem(item: ChatItem) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GroupChatOtherItem(item: ChatItem) {
|
||||
fun GroupChatOtherItem(item: ChatItem, showAvatarAndNickname: Boolean = true) {
|
||||
val AppColors = LocalAppTheme.current
|
||||
|
||||
Column(
|
||||
@@ -451,30 +461,27 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.clip(RoundedCornerShape(24.dp))
|
||||
) {
|
||||
CustomAsyncImage(
|
||||
imageUrl = item.avatar.replace("storage/avatars/", "/avatar/"),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "avatar"
|
||||
)
|
||||
if (showAvatarAndNickname) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.clip(RoundedCornerShape(24.dp))
|
||||
) {
|
||||
CustomAsyncImage(
|
||||
imageUrl = item.avatar.replace("storage/avatars/", "/avatar/"),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "avatar"
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
} else {
|
||||
// 当不显示头像时,添加左边距以保持消息对齐
|
||||
Spacer(modifier = Modifier.width(36.dp))
|
||||
}
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = item.nickname,
|
||||
style = TextStyle(
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 12.sp,
|
||||
),
|
||||
modifier = Modifier.padding(bottom = 2.dp)
|
||||
)
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.widthIn(
|
||||
@@ -487,7 +494,6 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
vertical = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 8.dp else 0.dp),
|
||||
horizontal = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 16.dp else 0.dp)
|
||||
)
|
||||
.padding(bottom = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 3.dp else 0.dp))
|
||||
) {
|
||||
when (item.messageType) {
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
|
||||
@@ -520,13 +526,24 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showAvatarAndNickname) {
|
||||
Text(
|
||||
text = item.nickname,
|
||||
style = TextStyle(
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 12.sp,
|
||||
),
|
||||
modifier = Modifier.padding(top = 2.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GroupChatItem(item: ChatItem, currentUserId: String) {
|
||||
fun GroupChatItem(item: ChatItem, currentUserId: String, showAvatarAndNickname: Boolean = true) {
|
||||
val isCurrentUser = item.userId == currentUserId
|
||||
|
||||
// 管理员消息显示特殊布局
|
||||
@@ -538,7 +555,7 @@ fun GroupChatItem(item: ChatItem, currentUserId: String) {
|
||||
// 根据是否是当前用户显示不同样式
|
||||
when (item.userId) {
|
||||
currentUserId -> GroupChatSelfItem(item)
|
||||
else -> GroupChatOtherItem(item)
|
||||
else -> GroupChatOtherItem(item, showAvatarAndNickname)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,20 +632,21 @@ fun GroupChatInput(
|
||||
onSendImage(uri)
|
||||
}
|
||||
}
|
||||
Box( modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp),){
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = inputBarHeight)
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.background(appColors.decentBackground)
|
||||
.padding(start = 16.dp, end = 8.dp, top = 2.dp, bottom = 2.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(appColors.background)
|
||||
.padding(horizontal = 16.dp),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
BasicTextField(
|
||||
value = text,
|
||||
@@ -640,6 +658,7 @@ fun GroupChatInput(
|
||||
fontSize = 16.sp
|
||||
),
|
||||
cursorBrush = SolidColor(appColors.text),
|
||||
singleLine = true,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp)
|
||||
@@ -662,44 +681,32 @@ fun GroupChatInput(
|
||||
)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.rider_pro_camera),
|
||||
contentDescription = "发送图片",
|
||||
modifier = Modifier
|
||||
.size(30.dp)
|
||||
.noRippleClickable {
|
||||
imagePickUpLauncher.launch(
|
||||
Intent.createChooser(
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
type = "image/*"
|
||||
},
|
||||
"选择图片"
|
||||
)
|
||||
)
|
||||
},
|
||||
tint = appColors.chatActionColor
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Crossfade(
|
||||
targetState = text.isNotEmpty(), animationSpec = tween(500),
|
||||
label = ""
|
||||
) { isNotEmpty ->
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.rider_pro_video_share),
|
||||
contentDescription = "发送消息",
|
||||
val alpha by animateFloatAsState(
|
||||
targetValue = if (isNotEmpty) 1f else 0.5f,
|
||||
animationSpec = tween(300)
|
||||
)
|
||||
Image(
|
||||
painter = painterResource(R.mipmap.rider_pro_im_send),
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.size(24.dp)
|
||||
.alpha(alpha)
|
||||
.noRippleClickable {
|
||||
if (text.isNotEmpty()) {
|
||||
onSend(text)
|
||||
text = ""
|
||||
}
|
||||
},
|
||||
tint = if (isNotEmpty) appColors.main else appColors.chatActionColor
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun groupMessagesByTime(chatList: List<ChatItem>, viewModel: GroupChatViewModel): List<ChatItem> {
|
||||
@@ -711,7 +718,7 @@ fun groupMessagesByTime(chatList: List<ChatItem>, viewModel: GroupChatViewModel)
|
||||
}
|
||||
val currentMessage = chatList[i]
|
||||
val timeDiff = currentMessage.timestamp - chatList[i - 1].timestamp
|
||||
if (-timeDiff > 30 * 60 * 1000) {
|
||||
if (-timeDiff > 10 * 60 * 1000) {
|
||||
viewModel.showTimestampMap[currentMessage.msgId] = true
|
||||
currentMessage.showTimeDivider = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user