Chat video messages: add thumbnail preview card with play overlay
This commit is contained in:
@@ -102,6 +102,7 @@ dependencies {
|
||||
implementation("io.coil-kt:coil:2.7.0")
|
||||
implementation("io.coil-kt:coil-compose:2.7.0")
|
||||
implementation("io.coil-kt:coil-gif:2.7.0")
|
||||
implementation("io.coil-kt:coil-video:2.7.0")
|
||||
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
||||
implementation("androidx.media3:media3-datasource:1.4.1")
|
||||
implementation("androidx.media3:media3-datasource-okhttp:1.4.1")
|
||||
|
||||
@@ -152,6 +152,8 @@ import androidx.compose.material.icons.filled.VisibilityOff
|
||||
import androidx.compose.material.icons.automirrored.filled.Reply
|
||||
import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import coil.request.videoFrameMillis
|
||||
import ru.daemonlord.messenger.R
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -2590,6 +2592,14 @@ private fun VideoAttachmentCard(
|
||||
fileType: String,
|
||||
onOpenViewer: () -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val previewRequest = remember(url) {
|
||||
ImageRequest.Builder(context)
|
||||
.data(url)
|
||||
.crossfade(true)
|
||||
.videoFrameMillis(1000)
|
||||
.build()
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -2597,13 +2607,41 @@ private fun VideoAttachmentCard(
|
||||
.clickable(onClick = onOpenViewer)
|
||||
.padding(8.dp),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(186.dp)
|
||||
.clip(RoundedCornerShape(10.dp)),
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.Movie, contentDescription = "Video")
|
||||
Text(text = "Video", style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.SemiBold)
|
||||
AsyncImage(
|
||||
model = previewRequest,
|
||||
contentDescription = stringResource(id = R.string.chat_media_badge_video),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(42.dp)
|
||||
.clip(CircleShape)
|
||||
.background(Color.Black.copy(alpha = 0.45f)),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PlayArrow,
|
||||
contentDescription = stringResource(id = R.string.chat_media_badge_video),
|
||||
tint = Color.White,
|
||||
modifier = Modifier.size(28.dp),
|
||||
)
|
||||
}
|
||||
MediaTypeBadge(
|
||||
label = stringResource(id = R.string.chat_media_badge_video),
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(8.dp),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
Text(text = extractFileName(url), style = MaterialTheme.typography.bodySmall, maxLines = 1)
|
||||
Text(text = fileType, style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user