dm-132
This commit is contained in:
parent
944d91e3d9
commit
e98eb1706d
3 changed files with 73 additions and 59 deletions
|
|
@ -112,8 +112,18 @@ data class Message(
|
|||
|
||||
// 🌟 核心新增:讓 UI 可以辨識訊息發送狀態!
|
||||
@kotlin.jvm.Transient // 👈 告訴 Moshi 這個欄位不需要解析 JSON,這是我們本地維護的
|
||||
val status: MessageStatus = MessageStatus.SUCCESS
|
||||
)
|
||||
val status: MessageStatus = MessageStatus.SUCCESS,
|
||||
|
||||
@kotlin.jvm.Transient
|
||||
var callLogInfo: CallLogInfo? = null
|
||||
|
||||
){
|
||||
init {
|
||||
if (type == "system" || type.startsWith("call")) {
|
||||
callLogInfo = CallLogInfo.parseContent(content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//send message
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
|
@ -134,26 +144,24 @@ data class MessageReactionUsersResponse(
|
|||
//voice call
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CallLogInfo(
|
||||
@Json(name = "type") val type: String, // 例如: call, call_log, call_missed, call_rejected 等
|
||||
@Json(name = "initiator_id") val initiator_id: String,
|
||||
@Json(name = "has_video") val has_video: Boolean
|
||||
@Json(name = "type") val type: String, // 例如: call_missed, call_rejected
|
||||
@Json(name = "initiator_id") val initiatorId: String, // 順便改成 Kotlin 的駝峰命名規範
|
||||
@Json(name = "has_video") val hasVideo: Boolean
|
||||
) {
|
||||
companion object {
|
||||
private val moshi = Moshi.Builder()
|
||||
.addLast(KotlinJsonAdapterFactory())
|
||||
.addLast(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
|
||||
private val adapter = moshi.adapter(CallLogInfo::class.java)
|
||||
|
||||
fun parse(message: Message): CallLogInfo? {
|
||||
// 🌟 修正:只要是 call 開頭的 type 都允許解析,避免 call_missed 被擋掉
|
||||
if (message.type == null || !message.type.startsWith("call")) return null
|
||||
|
||||
val content = message.content?.trim() ?: return null
|
||||
if (!content.startsWith("{") || !content.endsWith("}")) return null
|
||||
// 🌟 改成只單純解析 String
|
||||
fun parseContent(content: String?): CallLogInfo? {
|
||||
val json = content?.trim() ?: return null
|
||||
if (!json.startsWith("{") || !json.endsWith("}")) return null
|
||||
|
||||
return try {
|
||||
adapter.fromJson(content)
|
||||
adapter.fromJson(json)
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.e("CallLogInfo", "解析通話 JSON 失敗: ${e.message}")
|
||||
null
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Call
|
||||
import androidx.compose.material.icons.filled.CallMissed
|
||||
import androidx.compose.material.icons.filled.VideoCall
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -27,13 +29,13 @@ import com.example.login_v3.data.api.api_class.CallLogInfo
|
|||
@Composable
|
||||
fun CallLogBubble(
|
||||
callLog: CallLogInfo,
|
||||
isMe: Boolean,
|
||||
isMe: Boolean, // 這一則訊息是不是「我」發送的
|
||||
currentUserId: String,
|
||||
partnerDisplayName: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
// 判斷這通電話是不是「我」撥打的
|
||||
val isIInitiated = callLog.initiator_id == currentUserId
|
||||
// 🎯 改造 1:配合方案 A 的變數名稱修正 (initiator_id -> initiatorId)
|
||||
val isIInitiated = callLog.initiatorId == currentUserId
|
||||
|
||||
// 根據通話狀態決定圖示、顏色與顯示主標題
|
||||
val (icon, iconColor, titleText) = when (callLog.type) {
|
||||
|
|
@ -45,26 +47,31 @@ fun CallLogBubble(
|
|||
)
|
||||
}
|
||||
else -> {
|
||||
val callTypeStr = if (callLog.has_video) "視訊通話" else "語音通話"
|
||||
// 🎯 改造 2:配合方案 A 的變數名稱修正 (has_video -> hasVideo)
|
||||
val callTypeStr = if (callLog.hasVideo) "視訊通話" else "語音通話"
|
||||
Triple(
|
||||
if (callLog.has_video) Icons.Default.VideoCall else Icons.Default.Call,
|
||||
if (callLog.hasVideo) Icons.Default.VideoCall else Icons.Default.Call,
|
||||
if (isMe) Color(0xFF4CAF50) else Color(0xFF1976D2),
|
||||
if (isIInitiated) "撥出$callTypeStr" else "已接聽$callTypeStr"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 🌟 新增:來電顯示副標題邏輯
|
||||
val callTypeLabel = if (callLog.has_video) "視訊" else "語音"
|
||||
// 來電顯示副標題邏輯
|
||||
val callTypeLabel = if (callLog.hasVideo) "視訊" else "語音"
|
||||
val subText = when {
|
||||
// 我撥出去的 -> 顯示「撥給 某某」
|
||||
isIInitiated -> "$callTypeLabel • 撥給 $partnerDisplayName"
|
||||
// 對方撥進來的 -> 顯示「來自 某某」
|
||||
else -> "$callTypeLabel • 來自 $partnerDisplayName"
|
||||
}
|
||||
|
||||
// 🎯 改造 3:外層加上氣泡背景與剪裁,讓它看起來更像聊天氣泡
|
||||
Surface(
|
||||
modifier = modifier.padding(vertical = 4.dp),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f) // 給予淡淡的灰色氣泡背景
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.padding(vertical = 2.dp),
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
|
|
@ -93,7 +100,6 @@ fun CallLogBubble(
|
|||
)
|
||||
)
|
||||
Text(
|
||||
// 🌟 改用動態組合的來電顯示文字
|
||||
text = subText,
|
||||
style = MaterialTheme.typography.bodySmall.copy(
|
||||
fontSize = 12.sp,
|
||||
|
|
@ -102,4 +108,5 @@ fun CallLogBubble(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -517,7 +517,7 @@ fun MessageRow(
|
|||
val isImage = isAttachmentImage || isLegacyImage
|
||||
val rawContent = message.content ?: ""
|
||||
|
||||
val callLog = remember(message.id, message.content) { CallLogInfo.parse(message) }
|
||||
val callLog = message.callLogInfo
|
||||
|
||||
val finalImageModel = remember(message) {
|
||||
val rawPath = if (isAttachmentImage && !message.attachment?.filename.isNullOrBlank()) {
|
||||
|
|
@ -625,17 +625,16 @@ fun MessageRow(
|
|||
)
|
||||
}
|
||||
} else if (callLog != null) {
|
||||
// 🌟 通話紀錄渲染
|
||||
// 🌟 🎯 改造 2:通話紀錄渲染優化
|
||||
// 移除原本包裹在外層、帶有背景與 Padding 的 Box,改由長按/點擊事件的容器包住 CallLogBubble
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.widthIn(max = 280.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
// 讓通話紀錄一樣能響應點擊與長按(如刪除、回覆)
|
||||
.combinedClickable(
|
||||
onLongClick = { onReplyClick(message) },
|
||||
onClick = { onRowClick(message) }
|
||||
)
|
||||
.background(color = finalBubbleColor)
|
||||
.padding(horizontal = 14.dp, vertical = 10.dp)
|
||||
) {
|
||||
CallLogBubble(
|
||||
callLog = callLog,
|
||||
|
|
|
|||
Loading…
Reference in a new issue