聊天室和群聊信息调整

This commit is contained in:
weber
2025-08-21 19:04:59 +08:00
parent 5ee1897739
commit 9fb79b3881
17 changed files with 362 additions and 262 deletions

View File

@@ -563,7 +563,7 @@ interface RaveNowAPI {
@Query("isRecommended") isRecommended: Int = 1,
): Response<ListContainer<Room>>
@GET("rooms/detail")
@GET("outside/rooms/detail")
suspend fun getRoomDetail(@Query("trtcId") trtcId: String,
): Response<DataContainer<Room>>

View File

@@ -12,5 +12,4 @@ data class GroupInfo(
val groupName: String,
val groupAvatar: String,
val memberCount: Int,
val members: List<GroupMember>
)

View File

@@ -410,11 +410,12 @@ fun NavigationController(
route = NavigationRoute.GroupChatInfo.route,
arguments = listOf(navArgument("groupId") { type = NavType.StringType })
) {
val groupId = it.arguments?.getString("groupId") ?: ""
val encodedId = it.arguments?.getString("groupId")
val decodedId = encodedId?.let { java.net.URLDecoder.decode(it, "UTF-8") }
CompositionLocalProvider(
LocalAnimatedContentScope provides this,
) {
GroupChatInfoScreen(groupId)
GroupChatInfoScreen(decodedId?:"")
}
}
@@ -528,6 +529,15 @@ fun NavHostController.navigateToGroupChat(id: String,name:String,avatar:String)
)
}
fun NavHostController.navigateToGroupInfo(id: String) {
val encodedId = java.net.URLEncoder.encode(id, "UTF-8")
navigate(
route = NavigationRoute.GroupChatInfo.route
.replace("{groupId}", encodedId)
)
}
fun NavHostController.goTo(

View File

@@ -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
@@ -175,7 +177,7 @@ fun ChatScreen(userId: String) {
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
modifier = Modifier
.size(28.dp)
.size(24.dp)
.noRippleClickable {
navController.navigateUp()
},
@@ -187,8 +189,8 @@ fun ChatScreen(userId: String) {
CustomAsyncImage(
imageUrl = viewModel.userProfile?.avatar ?: "",
modifier = Modifier
.size(40.dp)
.clip(RoundedCornerShape(40.dp)),
.size(32.dp)
.clip(RoundedCornerShape(32.dp)),
contentDescription = "avatar"
)
Spacer(modifier = Modifier.width(8.dp))
@@ -221,7 +223,7 @@ fun ChatScreen(userId: String) {
},
menuItems = listOf(
MenuItem(
title = if (viewModel.notificationStrategy == "mute") "Unmute" else "Mute",
title = if (viewModel.notificationStrategy == "mute") "" else "",
icon = if (viewModel.notificationStrategy == "mute") R.drawable.rider_pro_notice_mute else R.drawable.rider_pro_notice_active,
) {
@@ -251,8 +253,7 @@ fun ChatScreen(userId: String) {
modifier = Modifier
.fillMaxWidth()
.height(1.dp)
.background(
AppColors.decentBackground)
)
Spacer(modifier = Modifier.height(8.dp))
ChatInput(
@@ -270,13 +271,12 @@ fun ChatScreen(userId: String) {
Box(
modifier = Modifier
.fillMaxSize()
.background(AppColors.decentBackground)
.background(AppColors.background)
.padding(paddingValues)
) {
LazyColumn(
state = listState,
modifier = Modifier
.fillMaxSize(),
modifier = Modifier.fillMaxSize(),
reverseLayout = true,
verticalArrangement = Arrangement.Top
) {
@@ -340,6 +340,7 @@ fun ChatScreen(userId: String) {
@Composable
fun ChatSelfItem(item: ChatItem) {
val context = LocalContext.current
Column(
modifier = Modifier
@@ -353,19 +354,28 @@ fun ChatSelfItem(item: ChatItem) {
Column(
horizontalAlignment = androidx.compose.ui.Alignment.End,
) {
/* Text(
text = item.nickname,
style = TextStyle(
color = Color.Gray,
fontSize = 12.sp,
),
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)
)
.padding(bottom = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 3.dp else 0.dp))
) {
when (item.messageType) {
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
@@ -373,7 +383,7 @@ fun ChatSelfItem(item: ChatItem) {
text = item.message,
style = TextStyle(
color = Color.White,
fontSize = 16.sp,
fontSize = 14.sp,
),
textAlign = TextAlign.Start
)
@@ -389,28 +399,28 @@ fun ChatSelfItem(item: ChatItem) {
else -> {
Text(
text = "Unsupported message type",
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"
)
}
}*/
}
}
}
@@ -430,11 +440,11 @@ fun ChatOtherItem(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"
)
@@ -447,13 +457,12 @@ fun ChatOtherItem(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)
)
.padding(bottom = (if (item.messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) 3.dp else 0.dp))
) {
when (item.messageType) {
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
@@ -461,7 +470,7 @@ fun ChatOtherItem(item: ChatItem) {
text = item.message,
style = TextStyle(
color = AppColors.text,
fontSize = 16.sp,
fontSize = 14.sp,
),
textAlign = TextAlign.Start
)
@@ -477,7 +486,7 @@ fun ChatOtherItem(item: ChatItem) {
else -> {
Text(
text = "Unsupported message type",
text = "不支持的消息类型",
style = TextStyle(
color = AppColors.text,
fontSize = 16.sp,
@@ -486,7 +495,6 @@ fun ChatOtherItem(item: ChatItem) {
}
}
}
}
}
@@ -547,89 +555,96 @@ fun ChatInput(
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)
) {
Box(
Row(
modifier = Modifier
.weight(1f)
.clip(RoundedCornerShape(16.dp))
.background(appColors.background)
.padding(horizontal = 16.dp),
contentAlignment = Alignment.CenterStart,
.fillMaxWidth()
.clip(RoundedCornerShape(20.dp))
.background(appColors.decentBackground)
.padding(start = 16.dp, end = 8.dp, top = 2.dp, bottom = 2.dp),
verticalAlignment = Alignment.CenterVertically,
) {
BasicTextField(
value = text,
onValueChange = {
text = it
},
textStyle = TextStyle(
color = appColors.text,
fontSize = 16.sp
),
cursorBrush = SolidColor(appColors.text),
Box(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.onFocusChanged { focusState ->
isKeyboardOpen = focusState.isFocused
}
.pointerInput(Unit) {
awaitPointerEventScope {
keyboardController = softwareKeyboardController
awaitFirstDown().also {
keyboardController?.show()
.weight(1f)
) {
BasicTextField(
value = text,
onValueChange = {
text = it
},
textStyle = TextStyle(
color = appColors.text,
fontSize = 16.sp
),
cursorBrush = SolidColor(appColors.text),
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.onFocusChanged { focusState ->
isKeyboardOpen = focusState.isFocused
}
.pointerInput(Unit) {
awaitPointerEventScope {
keyboardController = softwareKeyboardController
awaitFirstDown().also {
keyboardController?.show()
}
}
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboardController?.hide()
}
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboardController?.hide()
}
)
)
}
Spacer(modifier = Modifier.width(16.dp))
Icon(
painter = painterResource(id = R.drawable.rider_pro_camera),
contentDescription = "Emoji",
modifier = Modifier
.size(30.dp)
.noRippleClickable {
imagePickUpLauncher.launch(
Intent.createChooser(
Intent(Intent.ACTION_GET_CONTENT).apply {
type = "image/*"
},
"Select 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 = "Emoji",
)
}
Spacer(modifier = Modifier.width(8.dp))
Image(
painter = painterResource(R.mipmap.rider_pro_im_image),
contentDescription = "Image",
modifier = Modifier
.size(32.dp)
.size(30.dp)
.noRippleClickable {
if (text.isNotEmpty()) {
onSend(text)
text = ""
}
imagePickUpLauncher.launch(
Intent.createChooser(
Intent(Intent.ACTION_GET_CONTENT).apply {
type = "image/*"
},
"Select Image"
)
)
},
tint = if (isNotEmpty) appColors.main else appColors.chatActionColor
)
Spacer(modifier = Modifier.width(8.dp))
Crossfade(
targetState = text.isNotEmpty(), animationSpec = tween(500),
label = ""
) { isNotEmpty ->
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(24.dp)
.alpha(alpha)
.noRippleClickable {
if (text.isNotEmpty()) {
onSend(text)
text = ""
}
},
contentDescription = null,
)
}
}
}
}

View File

@@ -191,7 +191,7 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
} else {
Box(
modifier = Modifier
.size(40.dp)
.size(24.dp)
.clip(RoundedCornerShape(8.dp))
.background(AppColors.decentBackground),
contentAlignment = Alignment.Center
@@ -231,40 +231,11 @@ fun GroupChatScreen(groupId: String,name: String,avatar: String,) {
modifier = Modifier
.size(28.dp)
.noRippleClickable {
// 跳转到群聊信息页面
navController.navigate("GroupChatInfo/$groupId")
isMenuExpanded = true
},
contentDescription = null,
colorFilter = ColorFilter.tint(AppColors.text)
)
DropdownMenu(
expanded = isMenuExpanded,
onDismissRequest = {
isMenuExpanded = false
},
menuItems = listOf(
MenuItem(
title = if (viewModel.notificationStrategy == "mute") "取消静音" else "静音",
icon = if (viewModel.notificationStrategy == "mute") R.drawable.rider_pro_notice_mute else R.drawable.rider_pro_notice_active,
) {
isMenuExpanded = false
viewModel.viewModelScope.launch {
if (viewModel.notificationStrategy == "mute") {
viewModel.updateNotificationStrategy("active")
} else {
viewModel.updateNotificationStrategy("mute")
}
}
},
MenuItem(
title = "群成员",
icon = R.drawable.rider_pro_more_horizon,
) {
isMenuExpanded = false
viewModel.getGroupMembers()
}
),
)
}
}
}
@@ -461,7 +432,6 @@ fun GroupChatOtherItem(item: ChatItem, showAvatarAndNickname: Boolean = true) {
) {
Row(
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.Bottom,
modifier = Modifier.fillMaxWidth()
) {
if (showAvatarAndNickname) {
@@ -534,7 +504,7 @@ fun GroupChatOtherItem(item: ChatItem, showAvatarAndNickname: Boolean = true) {
color = AppColors.secondaryText,
fontSize = 12.sp,
),
modifier = Modifier.padding(top = 2.dp)
modifier = Modifier.padding(bottom = 2.dp)
)
}
}

View File

@@ -48,7 +48,6 @@ class GroupChatViewModel(
var isLoading by mutableStateOf(false)
var lastMessage: V2TIMMessage? = null
val showTimestampMap = mutableMapOf<String, Boolean>()
var chatNotification by mutableStateOf<ChatNotification?>(null)
var goToNew by mutableStateOf(false)
// 群聊特有属性
@@ -71,8 +70,6 @@ class GroupChatViewModel(
myProfile = accountService.getMyAccountProfile()
RegistListener(context)
fetchHistoryMessage(context)
val notiStrategy = ChatState.getStrategyByTargetTrtcId(groupId)
chatNotification = notiStrategy
} catch (e: Exception) {
Log.e("GroupChatViewModel", "初始化失败: ${e.message}")
}
@@ -287,16 +284,4 @@ class GroupChatViewModel(
return list
}
suspend fun updateNotificationStrategy(strategy: String) {
val result = ChatState.updateChatNotification(groupId.hashCode(), strategy)
chatNotification = result
}
val notificationStrategy get() = chatNotification?.strategy ?: "default"
// 群聊特有功能
fun getGroupMembers() {
// 简化群成员获取,暂时只记录日志
Log.d("GroupChatViewModel", "获取群成员功能待实现")
}
}

View File

@@ -16,7 +16,9 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
@@ -76,10 +78,11 @@ fun GroupChatInfoScreen(groupId: String) {
Spacer(modifier = Modifier.width(16.dp))
Text(
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Start,
text = "群聊信息",
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 18.sp,
fontSize = 17.sp,
fontWeight = FontWeight.Bold
)
@@ -104,7 +107,7 @@ fun GroupChatInfoScreen(groupId: String) {
imageUrl = viewModel.groupInfo!!.groupAvatar,
modifier = Modifier
.size(80.dp)
.clip(CircleShape),
.clip(RoundedCornerShape(12.dp)),
contentDescription = "群聊头像"
)
} else {
@@ -136,19 +139,6 @@ fun GroupChatInfoScreen(groupId: String) {
fontWeight = FontWeight.Bold
)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "更改名称和图片",
style = androidx.compose.ui.text.TextStyle(
color = Color(0xFF007AFF),
fontSize = 14.sp
),
modifier = Modifier.noRippleClickable {
// TODO: 实现更改群聊名称和图片功能
}
)
}
}
@@ -169,20 +159,20 @@ fun GroupChatInfoScreen(groupId: String) {
Box(
modifier = Modifier
.size(48.dp)
.clip(CircleShape)
.background(Color(0xFF007AFF)),
.clip(CircleShape),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
painter = painterResource(R.drawable.rider_pro_add_other),
modifier = Modifier.size(24.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(Color.White)
colorFilter = ColorFilter.tint(
AppColors.text)
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "添加其他人",
text = stringResource(R.string.group_info_add_other),
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 12.sp
@@ -194,26 +184,30 @@ fun GroupChatInfoScreen(groupId: String) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.noRippleClickable {
// TODO: 实现通知设置功能
/* if (viewModel.notificationStrategy == "mute") {
viewModel.updateNotificationStrategy("active")
} else {
viewModel.updateNotificationStrategy("mute")
}*/
}
) {
Box(
modifier = Modifier
.size(48.dp)
.clip(CircleShape)
.background(Color(0xFF007AFF)),
.clip(CircleShape),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(R.drawable.rider_pro_notice_active),
painter = painterResource(if (viewModel.notificationStrategy == "mute") R.drawable.rider_pro_notice_mute else R.drawable.rider_pro_notice_active,),
modifier = Modifier.size(24.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(Color.White)
colorFilter = ColorFilter.tint(
AppColors.text)
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "通知",
text = stringResource(R.string.group_info_notice_setting),
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 12.sp
@@ -231,20 +225,21 @@ fun GroupChatInfoScreen(groupId: String) {
Box(
modifier = Modifier
.size(48.dp)
.clip(CircleShape)
.background(Color(0xFFFF3B30)),
.clip(CircleShape),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
painter = painterResource(R.drawable.group_info_exit
),
modifier = Modifier.size(24.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(Color.White)
colorFilter = ColorFilter.tint(
AppColors.text)
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "退出",
text = stringResource(R.string.group_info_exit),
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 12.sp
@@ -263,7 +258,6 @@ fun GroupChatInfoScreen(groupId: String) {
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(8.dp))
.background(AppColors.decentBackground)
.padding(16.dp)
.noRippleClickable {
// TODO: 实现设置聊天主题功能
@@ -271,14 +265,15 @@ fun GroupChatInfoScreen(groupId: String) {
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
painter = painterResource(R.drawable.group_info_edit),
modifier = Modifier.size(24.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(AppColors.text)
colorFilter = ColorFilter.tint(
AppColors.text)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = "设置聊天主题",
text = stringResource(R.string.group_info_edit),
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 16.sp
@@ -286,10 +281,9 @@ fun GroupChatInfoScreen(groupId: String) {
modifier = Modifier.weight(1f)
)
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
modifier = Modifier.size(16.dp),
painter = painterResource(R.drawable.rave_now_nav_right),
modifier = Modifier.size(18.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(AppColors.secondaryText)
)
}
@@ -300,7 +294,6 @@ fun GroupChatInfoScreen(groupId: String) {
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(8.dp))
.background(AppColors.decentBackground)
.padding(16.dp)
.noRippleClickable {
// TODO: 实现查看群聊成员功能
@@ -308,10 +301,11 @@ fun GroupChatInfoScreen(groupId: String) {
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
painter = painterResource(R.drawable.group_info_users),
modifier = Modifier.size(24.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(AppColors.text)
colorFilter = ColorFilter.tint(
AppColors.text)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
@@ -323,64 +317,12 @@ fun GroupChatInfoScreen(groupId: String) {
modifier = Modifier.weight(1f)
)
Image(
painter = painterResource(R.drawable.rider_pro_back_icon),
modifier = Modifier.size(16.dp),
painter = painterResource(R.drawable.rave_now_nav_right),
modifier = Modifier.size(18.dp),
contentDescription = null,
colorFilter = ColorFilter.tint(AppColors.secondaryText)
)
}
}
// 成员列表
if (viewModel.groupInfo?.members?.isNotEmpty() == true) {
item {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "群成员",
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
)
}
items(viewModel.groupInfo!!.members) { member ->
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
CustomAsyncImage(
imageUrl = member.avatar,
modifier = Modifier
.size(40.dp)
.clip(CircleShape),
contentDescription = "成员头像"
)
Spacer(modifier = Modifier.width(12.dp))
Column {
Text(
text = member.nickname,
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 16.sp
)
)
if (member.isOwner) {
Text(
text = "群主",
style = androidx.compose.ui.text.TextStyle(
color = AppColors.secondaryText,
fontSize = 12.sp
)
)
}
}
}
}
}
}
}
}

View File

@@ -5,7 +5,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.aiosman.ravenow.AppStore
import com.aiosman.ravenow.ChatState
import com.aiosman.ravenow.data.api.ApiClient
import com.aiosman.ravenow.entity.ChatNotification
import com.aiosman.ravenow.entity.GroupInfo
import com.aiosman.ravenow.entity.GroupMember
import kotlinx.coroutines.launch
@@ -17,13 +20,21 @@ class GroupChatInfoViewModel(
var groupInfo by mutableStateOf<GroupInfo?>(null)
var isLoading by mutableStateOf(false)
var error by mutableStateOf<String?>(null)
var chatNotification by mutableStateOf<ChatNotification?>(null)
val notificationStrategy get() = chatNotification?.strategy ?: "default"
init {
loadGroupInfo()
}
suspend fun updateNotificationStrategy(strategy: String) {
val result = ChatState.updateChatNotification(groupId.hashCode(), strategy)
chatNotification = result
}
private fun loadGroupInfo() {
viewModelScope.launch {
val notiStrategy = ChatState.getStrategyByTargetTrtcId(groupId)
chatNotification = notiStrategy
try {
isLoading = true
error = null
@@ -37,16 +48,17 @@ class GroupChatInfoViewModel(
GroupInfo(
groupId = groupId,
groupName = it.name,
groupAvatar = room.avatar,
memberCount = room.userCount,
members = listOf(
GroupMember(
userId = room.creator.userId,
nickname = room.creator.profile.nickname,
avatar = room.creator.profile.avatar,
isOwner = true
groupAvatar = if (it.avatar.isNullOrEmpty()) {
// 将 groupId 转换为 Base64
val groupIdBase64 = android.util.Base64.encodeToString(
groupId.toByteArray(),
android.util.Base64.NO_WRAP
)
)
"${ApiClient.RETROFIT_URL+"group/avatar?groupIdBase64="}${groupIdBase64}"+"&token="+"${AppStore.token}"
} else {
"${ApiClient.BASE_API_URL+"/outside/rooms/avatar/"}${it.avatar}"+"?token="+"${AppStore.token}"
},
memberCount = room.userCount,
)
}