add delta sync for dm-v17

This commit is contained in:
eric 2026-08-07 16:03:50 +08:00
parent fc605183d5
commit d84ba852c6

View file

@ -85,11 +85,14 @@ import androidx.compose.foundation.layout.statusBars // 如果要使用 statusBa
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.filled.ArrowDownward
import androidx.compose.material.icons.filled.Block
import androidx.compose.material.icons.filled.Call
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Wallpaper
import androidx.compose.runtime.snapshotFlow
import androidx.core.content.ContextCompat
import com.example.login_v3.home.Message.UI.Detail.Message_Component.AudioMessageBubble
@ -112,6 +115,12 @@ sealed interface BottomBarState {
object AttachmentMenu : BottomBarState // 🎯 新增:附件選單
}
// 🎯 新增:Top Bar 狀態機
sealed interface TopBarState {
object Regular : TopBarState // 預設:姓名、頭像、通話、更多
object MoreOptions : TopBarState // 點擊「更多」後:顯示功能工具列
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MessageMessaging(
@ -143,6 +152,9 @@ fun MessageMessaging(
//inspect video
var lightboxVideoUrl by remember { mutableStateOf<String?>(null) }
// 🎯 新增:Top Bar 的本地狀態
var topBarState by remember { mutableStateOf<TopBarState>(TopBarState.Regular) }
// 🌟 核心:使用 derivedStateOf 統一控管狀態權限(長按優先權通常大於單擊)
// 🎯 新增:用來控管非訊息觸發的底部狀態(例如:AttachmentMenu)
var localBottomBarState by remember { mutableStateOf<BottomBarState?>(null) }
@ -256,11 +268,17 @@ fun MessageMessaging(
val topBarShape = RoundedCornerShape(16.dp)
// 👈 使用 AnimatedContent 讓 TopBar 切換更平滑
AnimatedContent(
targetState = topBarState,
label = "TopBarSwitchAnimation"
) { currentState ->
when (currentState) {
TopBarState.Regular -> {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 4.dp)
,
.padding(horizontal = 4.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
@ -287,10 +305,10 @@ fun MessageMessaging(
.height(58.dp) // 58dp 就會是純內容的高度,內容就會完美垂直置中了!
.padding(horizontal = 12.dp)
) {
val currentState = uiState
if (currentState is MessagesUiState.Success) {
val uiStateVal = uiState
if (uiStateVal is MessagesUiState.Success) {
UserAvatar(
avatarUrl = currentState.partnerAvatarUrl,
avatarUrl = uiStateVal.partnerAvatarUrl,
modifier = Modifier.size(42.dp)
)
}
@ -309,10 +327,10 @@ fun MessageMessaging(
)
if (currentState is MessagesUiState.Success) {
if (uiStateVal is MessagesUiState.Success) {
// 拿掉原本只判斷 ONLINE 的 if,讓所有狀態(除了 UNKNOWN)都能顯示
UserStatusDot(
status = currentState.partnerStatus,
status = uiStateVal.partnerStatus,
size = 14.dp // 建議統一成 14.dp,包含白色外圈的視覺效果最好
)
}
@ -365,22 +383,110 @@ fun MessageMessaging(
) {
IconButton(
onClick = {
// 這裡觸發語音通話的邏輯,例如:viewModel.startVoiceCall(roomId)
topBarState = TopBarState.MoreOptions
},
modifier = Modifier
.size(48.dp) // 給予標準的點擊區域大小
) {
Icon(
imageVector = Icons.Default.MoreVert, // 👈 這裡使用 Material Design 的預設電話圖標,也可以換成 Icons.Rounded.Phone
contentDescription = "語音通話",
tint = Color.White, // 👈 顏色可以根據你的漸層背景調整,如果是亮色背景可改用 MaterialTheme.colorScheme.onBackground
modifier = Modifier.size(28.dp) // Icon 實際的大小
imageVector = Icons.Default.MoreVert,
contentDescription = "更多選項",
tint = Color.White,
modifier = Modifier.size(28.dp)
)
}
}
Spacer(modifier = Modifier.width(6.dp))
}
}
TopBarState.MoreOptions -> {
// 🎯 當切換到「更多選項」時顯示的 TopBar
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 4.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Spacer(modifier = Modifier.width(6.dp))
// 關閉按鈕,點擊回到 Regular 狀態
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.size(58.dp)
.background(
color = MaterialTheme.colorScheme.primary,
shape = topBarShape
)
) {
IconButton(onClick = { topBarState = TopBarState.Regular }) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "關閉更多選項",
tint = Color.White,
modifier = Modifier.size(28.dp)
)
}
}
Spacer(modifier = Modifier.width(8.dp))
// 更多選項的內容(這裡可以放置搜尋、靜音、成員清單等功能)
Box(
modifier = Modifier
.weight(1f)
.height(58.dp)
.background(
color = MaterialTheme.colorScheme.primary,
shape = topBarShape
),
contentAlignment = Alignment.Center
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier.fillMaxWidth()
) {
// 搜尋訊息
IconButton(onClick = { /* TODO */ }) {
Icon(
imageVector = Icons.Default.Search,
contentDescription = "搜尋訊息",
tint = Color.White,
modifier = Modifier.size(26.dp)
)
}
// 更換壁紙
IconButton(onClick = { /* TODO */ }) {
Icon(
imageVector = Icons.Default.Wallpaper,
contentDescription = "更換壁紙",
tint = Color.White,
modifier = Modifier.size(26.dp)
)
}
// 封鎖用戶
IconButton(onClick = { /* TODO */ }) {
Icon(
imageVector = Icons.Default.Block,
contentDescription = "封鎖用戶",
tint = Color.White,
modifier = Modifier.size(26.dp)
)
}
}
}
Spacer(modifier = Modifier.width(6.dp))
}
}
}
}
Spacer(modifier = Modifier.height(6.dp))
}