dm-138
This commit is contained in:
parent
f753659a6e
commit
37d7eb6528
2 changed files with 95 additions and 3 deletions
|
|
@ -0,0 +1,48 @@
|
|||
package com.example.login_v3.home.Message.UI.Detail.Message_Component
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import coil.compose.AsyncImage
|
||||
|
||||
@Composable
|
||||
fun ImageLightbox(
|
||||
imageUrl: String,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
// 使用 Dialog 才能真正做到全螢幕蓋住 TopBar 與 BottomBar
|
||||
Dialog(
|
||||
onDismissRequest = onDismiss,
|
||||
properties = DialogProperties(
|
||||
usePlatformDefaultWidth = false // 關閉預設寬度限制,達到真正全螢幕
|
||||
)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black.copy(alpha = 0.9f)) // 質感黑半透明背景
|
||||
.clickable { onDismiss() }, // 點擊背景任何地方都能關閉
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
AsyncImage(
|
||||
model = imageUrl,
|
||||
contentDescription = "放大檢視圖片",
|
||||
contentScale = ContentScale.Fit, // 確保整張圖片能完整塞進螢幕
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxHeight(0.85f) // 留一點上下操作空間
|
||||
.clickable(enabled = false) { } // 阻止點擊圖片本身時觸發關閉
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -77,6 +77,7 @@ import androidx.compose.material.icons.filled.Call
|
|||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import com.example.login_v3.data.api.api_class.CallLogInfo
|
||||
import com.example.login_v3.home.Message.UI.Detail.Message_Component.CallLogBubble
|
||||
import com.example.login_v3.home.Message.UI.Detail.Message_Component.ImageLightbox
|
||||
import com.example.login_v3.home.Message.UI.Detail.Message_Component.UserStatusDot
|
||||
|
||||
|
||||
|
|
@ -112,6 +113,9 @@ fun MessageMessaging(
|
|||
|
||||
var emojiTargetMessage by remember { mutableStateOf<Message?>(null) }
|
||||
|
||||
//inspect image
|
||||
var lightboxImageUrl by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
// 🌟 核心:使用 derivedStateOf 統一控管狀態權限(長按優先權通常大於單擊)
|
||||
val bottomBarState by remember {
|
||||
derivedStateOf {
|
||||
|
|
@ -236,7 +240,7 @@ fun MessageMessaging(
|
|||
style = MaterialTheme.typography.titleMedium,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color(0xFF333333),
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.weight(1f)
|
||||
|
|
@ -425,8 +429,41 @@ fun MessageMessaging(
|
|||
},
|
||||
// 💡 單擊事件:開啟 Emoji 選單,同時清空長按選單
|
||||
onRowClick = { message ->
|
||||
val isAttachmentImage = message.attachment?.mimeType?.startsWith("image/") == true
|
||||
val contentLowerCase = (message.content ?: "").lowercase()
|
||||
val imageExtensions = listOf(".jpg", ".jpeg", ".png", ".webp", ".heic", ".heif")
|
||||
val isLegacyImage = imageExtensions.any { contentLowerCase.contains(it) }
|
||||
|
||||
if (isAttachmentImage || isLegacyImage) {
|
||||
// 🎯 A 狀態:這是圖片,計算圖片完整 URL 並塞入 lightbox 狀態觸發放大
|
||||
val rawPath = if (isAttachmentImage && !message.attachment?.filename.isNullOrBlank()) {
|
||||
message.attachment!!.filename
|
||||
} else {
|
||||
message.content ?: ""
|
||||
}
|
||||
val baseUrl = "https://tg.technologia-tw.com"
|
||||
val finalUrl = when {
|
||||
rawPath.isBlank() -> ""
|
||||
rawPath.startsWith("http") -> rawPath
|
||||
else -> {
|
||||
val cleanPath = rawPath.removePrefix("/").removePrefix("uploads/")
|
||||
if (cleanPath.startsWith("attachment/")) {
|
||||
"$baseUrl/uploads/$cleanPath"
|
||||
} else {
|
||||
"$baseUrl/uploads/attachment/$cleanPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 關閉可能開啟的選單,並打開大圖
|
||||
viewModel.clearActionMessage()
|
||||
emojiTargetMessage = null
|
||||
lightboxImageUrl = finalUrl
|
||||
} else {
|
||||
// 🎯 B 狀態:一般文字或通話,維持原本點擊叫出 Emoji Bar 的邏輯
|
||||
viewModel.clearActionMessage()
|
||||
emojiTargetMessage = message
|
||||
}
|
||||
},
|
||||
onReactionClick = { message, emoji ->
|
||||
// 這是訊息氣泡下方既有 Reaction 小標籤的點擊事件,保持原樣即可
|
||||
|
|
@ -452,6 +489,13 @@ fun MessageMessaging(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
lightboxImageUrl?.let { url ->
|
||||
ImageLightbox(
|
||||
imageUrl = url,
|
||||
onDismiss = { lightboxImageUrl = null }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
Loading…
Reference in a new issue