diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 6c47e45..ab59450 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -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") diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt index 929cd7f..4a898c0 100644 --- a/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt +++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt @@ -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) }