UI调整,群聊开发
This commit is contained in:
@@ -83,6 +83,7 @@ import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
|
||||
|
||||
@Composable
|
||||
@@ -280,7 +281,7 @@ fun ChatAiScreen(userId: String) {
|
||||
verticalArrangement = Arrangement.Top
|
||||
) {
|
||||
val chatList = groupMessagesByTime(viewModel.getDisplayChatList(), viewModel)
|
||||
items(chatList.size, key = { index -> chatList[index].msgId }) { index ->
|
||||
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()
|
||||
|
||||
@@ -68,11 +68,22 @@ class ChatAiViewModel(
|
||||
textMessageListener = object : V2TIMAdvancedMsgListener() {
|
||||
override fun onRecvNewMessage(msg: V2TIMMessage?) {
|
||||
super.onRecvNewMessage(msg)
|
||||
msg?.let {
|
||||
val chatItem = ChatItem.convertToChatItem(msg, context, avatar = userProfile?.avatar)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
goToNew = true
|
||||
msg?.let { message ->
|
||||
// 只处理当前聊天对象的消息
|
||||
val currentChatUserId = userProfile?.trtcUserId
|
||||
val currentUserId = com.aiosman.ravenow.AppState.profile?.trtcUserId
|
||||
|
||||
if (currentChatUserId != null && currentUserId != null) {
|
||||
// 检查消息是否来自当前聊天对象,且不是自己发送的消息
|
||||
if ((message.userID == currentChatUserId || message.userID == currentUserId) &&
|
||||
message.sender != currentUserId) {
|
||||
val chatItem = ChatItem.convertToChatItem(message, context, avatar = userProfile?.avatar)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
goToNew = true
|
||||
android.util.Log.i("ChatAiViewModel", "收到来自 ${message.sender} 的消息,更新AI聊天列表")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -260,7 +271,7 @@ class ChatAiViewModel(
|
||||
message: String,
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
val response = ApiClient.api.sendChatAiMessage(SendChatAiRequestBody(fromTrtcUserId = fromTrtcUserId,toTrtcUserId = toTrtcUserId,message = message,skipTrtc = true))
|
||||
val response = ApiClient.api.sendChatAiMessage(SendChatAiRequestBody(fromTrtcUserId = fromTrtcUserId,toTrtcUserId = toTrtcUserId,message = message))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
|
||||
|
||||
@Composable
|
||||
@@ -280,7 +281,7 @@ fun ChatScreen(userId: String) {
|
||||
verticalArrangement = Arrangement.Top
|
||||
) {
|
||||
val chatList = groupMessagesByTime(viewModel.getDisplayChatList(), viewModel)
|
||||
items(chatList.size, key = { index -> chatList[index].msgId }) { index ->
|
||||
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()
|
||||
|
||||
@@ -65,11 +65,22 @@ class ChatViewModel(
|
||||
textMessageListener = object : V2TIMAdvancedMsgListener() {
|
||||
override fun onRecvNewMessage(msg: V2TIMMessage?) {
|
||||
super.onRecvNewMessage(msg)
|
||||
msg?.let {
|
||||
val chatItem = ChatItem.convertToChatItem(msg, context, avatar = userProfile?.avatar)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
goToNew = true
|
||||
msg?.let { message ->
|
||||
// 只处理当前聊天对象的消息
|
||||
val currentChatUserId = userProfile?.trtcUserId
|
||||
val currentUserId = com.aiosman.ravenow.AppState.profile?.trtcUserId
|
||||
|
||||
if (currentChatUserId != null && currentUserId != null) {
|
||||
// 检查消息是否来自当前聊天对象,且不是自己发送的消息
|
||||
if ((message.userID == currentChatUserId || message.userID == currentUserId) &&
|
||||
message.sender != currentUserId) {
|
||||
val chatItem = ChatItem.convertToChatItem(message, context, avatar = userProfile?.avatar)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
goToNew = true
|
||||
android.util.Log.i("ChatViewModel", "收到来自 ${message.sender} 的消息,更新聊天列表")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.ViewModel
|
||||
@@ -83,9 +84,10 @@ import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
|
||||
@Composable
|
||||
fun GroupChatScreen(groupId: String) {
|
||||
fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
|
||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
||||
val navController = LocalNavController.current
|
||||
val context = LocalNavController.current.context
|
||||
@@ -96,7 +98,7 @@ fun GroupChatScreen(groupId: String) {
|
||||
key = "GroupChatViewModel_$groupId",
|
||||
factory = object : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return GroupChatViewModel(groupId) as T
|
||||
return GroupChatViewModel(groupId,name,avatar) as T
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -167,7 +169,7 @@ fun GroupChatScreen(groupId: String) {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.rider_pro_back_icon),
|
||||
modifier = Modifier
|
||||
.size(28.dp)
|
||||
.size(24.dp)
|
||||
.noRippleClickable {
|
||||
navController.navigateUp()
|
||||
},
|
||||
@@ -180,7 +182,7 @@ fun GroupChatScreen(groupId: String) {
|
||||
CustomAsyncImage(
|
||||
imageUrl = viewModel.groupAvatar,
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.size(32.dp)
|
||||
.clip(RoundedCornerShape(8.dp)),
|
||||
contentDescription = "群聊头像"
|
||||
)
|
||||
@@ -193,12 +195,16 @@ fun GroupChatScreen(groupId: String) {
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = viewModel.groupName.take(1),
|
||||
text = viewModel.groupName,
|
||||
style = TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 16.sp,
|
||||
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
|
||||
)
|
||||
fontSize = 18.sp,
|
||||
|
||||
fontWeight = androidx.compose.ui.text.font.FontWeight.W700
|
||||
),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -213,13 +219,7 @@ fun GroupChatScreen(groupId: String) {
|
||||
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
|
||||
)
|
||||
)
|
||||
Text(
|
||||
text = "${viewModel.memberCount}人",
|
||||
style = TextStyle(
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 14.sp
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
@@ -304,7 +304,7 @@ fun GroupChatScreen(groupId: String) {
|
||||
verticalArrangement = Arrangement.Top
|
||||
) {
|
||||
val chatList = groupMessagesByTime(viewModel.getDisplayChatList(), viewModel)
|
||||
items(chatList.size, key = { index -> chatList[index].msgId }) { index ->
|
||||
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()
|
||||
@@ -369,7 +369,7 @@ fun GroupChatSelfItem(item: ChatItem) {
|
||||
Column(
|
||||
horizontalAlignment = androidx.compose.ui.Alignment.End,
|
||||
) {
|
||||
Text(
|
||||
/* Text(
|
||||
text = item.nickname,
|
||||
style = TextStyle(
|
||||
color = Color.Gray,
|
||||
@@ -377,15 +377,15 @@ fun GroupChatSelfItem(item: ChatItem) {
|
||||
),
|
||||
modifier = Modifier.padding(bottom = 2.dp)
|
||||
)
|
||||
|
||||
*/
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.widthIn(
|
||||
min = 20.dp,
|
||||
max = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 250.dp else 150.dp)
|
||||
)
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.background(Color(0xFF000000))
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.background(Color(0xFF6246FF))
|
||||
.padding(
|
||||
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)
|
||||
@@ -398,7 +398,7 @@ fun GroupChatSelfItem(item: ChatItem) {
|
||||
text = item.message,
|
||||
style = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 16.sp,
|
||||
fontSize = 14.sp,
|
||||
),
|
||||
textAlign = TextAlign.Start
|
||||
)
|
||||
@@ -417,25 +417,25 @@ fun GroupChatSelfItem(item: ChatItem) {
|
||||
text = "不支持的消息类型",
|
||||
style = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 16.sp,
|
||||
fontSize = 14.sp,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
/*Spacer(modifier = Modifier.width(12.dp))
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.clip(RoundedCornerShape(40.dp))
|
||||
.size(24.dp)
|
||||
.clip(RoundedCornerShape(24.dp))
|
||||
) {
|
||||
CustomAsyncImage(
|
||||
imageUrl = item.avatar,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "avatar"
|
||||
)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,11 +455,11 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.clip(RoundedCornerShape(40.dp))
|
||||
.size(24.dp)
|
||||
.clip(RoundedCornerShape(24.dp))
|
||||
) {
|
||||
CustomAsyncImage(
|
||||
imageUrl = item.avatar,
|
||||
imageUrl = item.avatar.replace("storage/avatars/", "/avatar/"),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "avatar"
|
||||
)
|
||||
@@ -481,8 +481,8 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
min = 20.dp,
|
||||
max = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 250.dp else 150.dp)
|
||||
)
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.background(AppColors.background)
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.background(AppColors.bubbleBackground)
|
||||
.padding(
|
||||
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)
|
||||
@@ -495,7 +495,7 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
text = item.message,
|
||||
style = TextStyle(
|
||||
color = AppColors.text,
|
||||
fontSize = 16.sp,
|
||||
fontSize = 14.sp,
|
||||
),
|
||||
textAlign = TextAlign.Start
|
||||
)
|
||||
@@ -528,10 +528,47 @@ fun GroupChatOtherItem(item: ChatItem) {
|
||||
@Composable
|
||||
fun GroupChatItem(item: ChatItem, currentUserId: String) {
|
||||
val isCurrentUser = item.userId == currentUserId
|
||||
if (isCurrentUser) {
|
||||
GroupChatSelfItem(item)
|
||||
} else {
|
||||
GroupChatOtherItem(item)
|
||||
|
||||
// 管理员消息显示特殊布局
|
||||
if (item.userId == "administrator") {
|
||||
GroupChatAdminItem(item)
|
||||
return
|
||||
}
|
||||
|
||||
// 根据是否是当前用户显示不同样式
|
||||
when (item.userId) {
|
||||
currentUserId -> GroupChatSelfItem(item)
|
||||
else -> GroupChatOtherItem(item)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GroupChatAdminItem(item: ChatItem) {
|
||||
val AppColors = LocalAppTheme.current
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 50.dp, vertical = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.padding(vertical = 8.dp, horizontal = 16.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = item.message,
|
||||
style = TextStyle(
|
||||
color = AppColors.secondaryText,
|
||||
fontSize = 12.sp,
|
||||
textAlign = TextAlign.Center
|
||||
),
|
||||
maxLines = Int.MAX_VALUE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@ import com.aiosman.ravenow.data.AccountService
|
||||
import com.aiosman.ravenow.data.AccountServiceImpl
|
||||
import com.aiosman.ravenow.data.UserService
|
||||
import com.aiosman.ravenow.data.UserServiceImpl
|
||||
import com.aiosman.ravenow.data.api.ApiClient
|
||||
import com.aiosman.ravenow.data.api.GroupChatRequestBody
|
||||
import com.aiosman.ravenow.data.api.SendChatAiRequestBody
|
||||
import com.aiosman.ravenow.data.api.SingleChatRequestBody
|
||||
import com.aiosman.ravenow.entity.AccountProfileEntity
|
||||
import com.aiosman.ravenow.entity.ChatItem
|
||||
import com.aiosman.ravenow.entity.ChatNotification
|
||||
@@ -31,6 +35,8 @@ import java.io.InputStream
|
||||
|
||||
class GroupChatViewModel(
|
||||
val groupId: String,
|
||||
val name: String,
|
||||
val avatar: String,
|
||||
) : ViewModel() {
|
||||
var chatData by mutableStateOf<List<ChatItem>>(emptyList())
|
||||
var groupInfo by mutableStateOf<GroupInfo?>(null)
|
||||
@@ -77,8 +83,8 @@ class GroupChatViewModel(
|
||||
// 简化群组信息获取,使用默认信息
|
||||
groupInfo = GroupInfo(
|
||||
groupId = groupId,
|
||||
groupName = "群聊 $groupId",
|
||||
groupAvatar = "",
|
||||
groupName = name,
|
||||
groupAvatar = avatar,
|
||||
memberCount = 0,
|
||||
ownerId = ""
|
||||
)
|
||||
@@ -156,8 +162,8 @@ class GroupChatViewModel(
|
||||
val v2TIMMessage = V2TIMManager.getMessageManager().createTextMessage(message)
|
||||
V2TIMManager.getMessageManager().sendMessage(
|
||||
v2TIMMessage,
|
||||
groupId,
|
||||
null,
|
||||
groupId,
|
||||
V2TIMMessage.V2TIM_PRIORITY_NORMAL,
|
||||
false,
|
||||
null,
|
||||
@@ -167,6 +173,7 @@ class GroupChatViewModel(
|
||||
Log.e("GroupChatViewModel", "发送群聊消息失败: $p1")
|
||||
}
|
||||
override fun onSuccess(p0: V2TIMMessage?) {
|
||||
sendChatAiMessage(message = message, trtcGroupId = groupId)
|
||||
val chatItem = ChatItem.convertToChatItem(p0!!, context, avatar = myProfile?.avatar)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
@@ -177,6 +184,18 @@ class GroupChatViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun sendChatAiMessage(
|
||||
trtcGroupId: String,
|
||||
message: String,
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
val response = ApiClient.api.sendChatAiMessage(SendChatAiRequestBody(trtcGroupId = trtcGroupId,message = message))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun sendImageMessage(imageUri: Uri, context: Context) {
|
||||
val tempFile = createTempFile(context, imageUri)
|
||||
val imagePath = tempFile?.path
|
||||
|
||||
Reference in New Issue
Block a user