mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 03:18:06 +00:00
Reworked video preview in chat messages to prevent broken layout if thumbnail can't be extracted from video (or if picture is not displayable)
This commit is contained in:
parent
257352927d
commit
cc6ec98846
12 changed files with 193 additions and 25 deletions
|
|
@ -95,6 +95,12 @@ class MediaViewerFragment : GenericMainFragment() {
|
|||
binding.videoPlayer.setAspectRatio(width, height)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.changeFullScreenModeEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { fullScreenMode ->
|
||||
sharedViewModel.mediaViewerFullScreenMode.value = fullScreenMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ class MediaViewModel @UiThread constructor() : GenericViewModel() {
|
|||
MutableLiveData<Event<Pair<Int, Int>>>()
|
||||
}
|
||||
|
||||
val changeFullScreenModeEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
lateinit var mediaPlayer: MediaPlayer
|
||||
|
||||
private lateinit var filePath: String
|
||||
|
|
@ -172,11 +176,18 @@ class MediaViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
// Leave full screen when playback is done
|
||||
fullScreenMode.postValue(false)
|
||||
changeFullScreenModeEvent.postValue(Event(false))
|
||||
}
|
||||
setOnVideoSizeChangedListener { mediaPlayer, width, height ->
|
||||
videoSizeChangedEvent.postValue(Event(Pair(width, height)))
|
||||
}
|
||||
prepare()
|
||||
try {
|
||||
prepare()
|
||||
} catch (e: Exception) {
|
||||
fullScreenMode.postValue(false)
|
||||
changeFullScreenModeEvent.postValue(Event(false))
|
||||
Log.e("$TAG Failed to prepare video file: $e")
|
||||
}
|
||||
}
|
||||
|
||||
val durationInMillis = mediaPlayer.duration
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ package org.linphone.ui.main.chat.model
|
|||
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.media.MediaMetadataRetriever.METADATA_KEY_DURATION
|
||||
import android.media.ThumbnailUtils
|
||||
import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
import androidx.annotation.AnyThread
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
|
@ -52,6 +54,10 @@ class FileModel @AnyThread constructor(
|
|||
|
||||
val transferProgress = MutableLiveData<Int>()
|
||||
|
||||
val mediaPreview = MutableLiveData<String>()
|
||||
|
||||
val mediaPreviewAvailable = MutableLiveData<Boolean>()
|
||||
|
||||
val mimeType: FileUtils.MimeType
|
||||
|
||||
val mimeTypeString: String
|
||||
|
|
@ -79,6 +85,7 @@ class FileModel @AnyThread constructor(
|
|||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
init {
|
||||
mediaPreviewAvailable.postValue(false)
|
||||
transferProgress.postValue(-1)
|
||||
formattedFileSize.postValue(FileUtils.bytesToDisplayableSize(fileSize))
|
||||
|
||||
|
|
@ -93,6 +100,14 @@ class FileModel @AnyThread constructor(
|
|||
isImage = mimeType == FileUtils.MimeType.Image
|
||||
isVideoPreview = mimeType == FileUtils.MimeType.Video
|
||||
isAudio = mimeType == FileUtils.MimeType.Audio
|
||||
|
||||
if (isImage) {
|
||||
mediaPreview.postValue(path)
|
||||
mediaPreviewAvailable.postValue(true)
|
||||
} else if (isVideoPreview) {
|
||||
loadVideoPreview()
|
||||
}
|
||||
|
||||
if (isVideoPreview || isAudio) {
|
||||
getDuration()
|
||||
}
|
||||
|
|
@ -132,6 +147,25 @@ class FileModel @AnyThread constructor(
|
|||
FileUtils.deleteFile(path)
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
private fun loadVideoPreview() {
|
||||
try {
|
||||
Log.i("$TAG Try to create an image preview of video file [$path]")
|
||||
val previewBitmap = ThumbnailUtils.createVideoThumbnail(
|
||||
path,
|
||||
MediaStore.Images.Thumbnails.MINI_KIND
|
||||
)
|
||||
if (previewBitmap != null) {
|
||||
val previewPath = FileUtils.storeBitmap(previewBitmap, fileName)
|
||||
Log.i("$TAG Preview of video file [$path] available at [$previewPath]")
|
||||
mediaPreview.postValue(previewPath)
|
||||
mediaPreviewAvailable.postValue(true)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("$TAG Failed to get image preview for file [$path]: $e")
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
private fun getDuration() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -309,18 +309,23 @@ fun ImageView.loadFileImage(file: String?) {
|
|||
}
|
||||
|
||||
@UiThread
|
||||
@BindingAdapter("coilBubble")
|
||||
fun ImageView.loadImageForChatBubble(file: String?) {
|
||||
loadImageForChatBubble(this, file, false)
|
||||
@BindingAdapter("coilBubble", "coilBubbleFallback")
|
||||
fun ImageView.loadImageForChatBubbleSingle(file: String?, fallback: View?) {
|
||||
loadImageForChatBubble(this, file, false, fallback)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@BindingAdapter("coilBubbleGrid")
|
||||
fun ImageView.loadImageForChatBubbleGrid(file: String?) {
|
||||
loadImageForChatBubble(this, file, true)
|
||||
@BindingAdapter("coilBubbleGrid", "coilBubbleFallback")
|
||||
fun ImageView.loadImageForChatBubbleGrid(file: String?, fallback: View?) {
|
||||
loadImageForChatBubble(this, file, true, fallback)
|
||||
}
|
||||
|
||||
private fun loadImageForChatBubble(imageView: ImageView, file: String?, grid: Boolean) {
|
||||
private fun loadImageForChatBubble(
|
||||
imageView: ImageView,
|
||||
file: String?,
|
||||
grid: Boolean,
|
||||
fallback: View?
|
||||
) {
|
||||
if (file.isNullOrEmpty()) return
|
||||
|
||||
val isImage = FileUtils.isExtensionImage((file))
|
||||
|
|
@ -339,22 +344,23 @@ private fun loadImageForChatBubble(imageView: ImageView, file: String?, grid: Bo
|
|||
|
||||
if (isVideo) {
|
||||
imageView.load(file) {
|
||||
placeholder(R.drawable.image_square)
|
||||
placeholder(R.drawable.file_video)
|
||||
videoFrameMillis(0)
|
||||
transformations(RoundedCornersTransformation(radius))
|
||||
size(width, height)
|
||||
listener(
|
||||
onError = { _, result ->
|
||||
Log.e(
|
||||
"$TAG Error getting preview picture from video? [$file]: ${result.throwable}"
|
||||
"$TAG Error getting preview picture from video (?) [$file]: ${result.throwable}"
|
||||
)
|
||||
fallback?.visibility = View.VISIBLE
|
||||
imageView.visibility = View.GONE
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
imageView.load(file) {
|
||||
placeholder(R.drawable.image_square)
|
||||
placeholder(R.drawable.file_image)
|
||||
// Can't have a transformation for gif file, breaks animation
|
||||
if (FileUtils.getExtensionFromFileName(file) != "gif") {
|
||||
transformations(RoundedCornersTransformation(radius))
|
||||
|
|
@ -365,6 +371,7 @@ private fun loadImageForChatBubble(imageView: ImageView, file: String?, grid: Bo
|
|||
Log.e(
|
||||
"$TAG Error getting picture from file [$file]: ${result.throwable}"
|
||||
)
|
||||
fallback?.visibility = View.VISIBLE
|
||||
imageView.visibility = View.GONE
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ package org.linphone.utils
|
|||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.CursorIndexOutOfBoundsException
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.os.ParcelFileDescriptor
|
||||
|
|
@ -398,6 +399,19 @@ class FileUtils {
|
|||
return file.exists()
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
fun storeBitmap(bitmap: Bitmap, fileName: String): String {
|
||||
val path = getFileStorageCacheDir("$fileName.jpg", true)
|
||||
FileOutputStream(path).use { outputStream ->
|
||||
bitmap.compress(
|
||||
Bitmap.CompressFormat.JPEG,
|
||||
100,
|
||||
outputStream
|
||||
)
|
||||
}
|
||||
return path.absolutePath
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
suspend fun dumpStringToFile(data: String, to: File): Boolean {
|
||||
try {
|
||||
|
|
|
|||
9
app/src/main/res/drawable/file_image.xml
Normal file
9
app/src/main/res/drawable/file_image.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="256">
|
||||
<path
|
||||
android:pathData="M110.66,147.56a8,8 0,0 0,-13.32 0L76.49,178.85l-9.76,-15.18a8,8 0,0 0,-13.46 0l-36,56A8,8 0,0 0,24 232L152,232a8,8 0,0 0,6.66 -12.44ZM38.65,216 L60,182.79l9.63,15a8,8 0,0 0,13.39 0.11l21,-31.47L137.05,216ZM213.65,82.34 L157.65,26.34A8,8 0,0 0,152 24L56,24A16,16 0,0 0,40 40v88a8,8 0,0 0,16 0L56,40h88L144,88a8,8 0,0 0,8 8h48L200,216h-8a8,8 0,0 0,0 16h8a16,16 0,0 0,16 -16L216,88A8,8 0,0 0,213.66 82.34ZM160,51.31 L188.69,80L160,80Z"
|
||||
android:fillColor="#4e6074"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/file_video.xml
Normal file
9
app/src/main/res/drawable/file_video.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="256">
|
||||
<path
|
||||
android:pathData="M213.66,82.34l-56,-56A8,8 0,0 0,152 24L56,24A16,16 0,0 0,40 40v72a8,8 0,0 0,16 0L56,40h88L144,88a8,8 0,0 0,8 8h48L200,216h-8a8,8 0,0 0,0 16h8a16,16 0,0 0,16 -16L216,88A8,8 0,0 0,213.66 82.34ZM160,51.31 L188.69,80L160,80ZM155.88,145a8,8 0,0 0,-8.12 0.22l-19.95,12.46A16,16 0,0 0,112 144L48,144a16,16 0,0 0,-16 16v48a16,16 0,0 0,16 16h64a16,16 0,0 0,15.81 -13.68l19.95,12.46A8,8 0,0 0,160 216L160,152A8,8 0,0 0,155.88 145ZM112,208L48,208L48,160h64v48ZM144,201.57 L128,191.57L128,176.43l16,-10Z"
|
||||
android:fillColor="#4e6074"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="?attr/color_main2_200" />
|
||||
</shape>
|
||||
|
|
@ -26,6 +26,21 @@
|
|||
android:visibility="@{model.isImage || model.isVideoPreview ? View.GONE : View.VISIBLE}"
|
||||
app:constraint_referenced_ids="file_name, file_background, file_icon" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/broken_media_icon"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="@dimen/chat_bubble_grid_image_size"
|
||||
android:layout_height="@dimen/chat_bubble_grid_image_size"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="18dp"
|
||||
android:background="@drawable/shape_squircle_main2_200_5dp"
|
||||
android:visibility="@{model.mediaPreviewAvailable ? View.GONE : View.VISIBLE, default=gone}"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
android:src="@{model.isVideoPreview ? @drawable/file_video : @drawable/file_image, default=@drawable/file_video}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:tint="?attr/color_main2_600" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
|
|
@ -36,7 +51,8 @@
|
|||
android:scaleType="centerCrop"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
android:visibility="@{model.isImage || model.isVideoPreview ? View.VISIBLE : View.GONE}"
|
||||
coilBubbleGrid="@{model.path}"
|
||||
coilBubbleGrid="@{model.mediaPreview}"
|
||||
coilBubbleFallback="@{brokenMediaIcon}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
|
|
@ -50,16 +66,17 @@
|
|||
android:textColor="@{model.isVideoPreview ? @color/white : @color/main2_600}"
|
||||
android:textSize="12sp"
|
||||
android:visibility="@{model.isVideoPreview && model.audioVideoDuration.length() > 0 ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"/>
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/video_preview"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="@dimen/icon_size"
|
||||
android:layout_height="@dimen/icon_size"
|
||||
android:src="@drawable/play_fill"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="@{model.isVideoPreview ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:visibility="@{model.isVideoPreview && model.mediaPreviewAvailable ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintTop_toTopOf="@id/image"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,22 @@
|
|||
android:visibility="@{inflatedVisibility == View.VISIBLE ? View.VISIBLE : View.GONE}"
|
||||
inflatedLifecycleOwner="@{true}">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/broken_media_icon"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="@dimen/chat_bubble_grid_image_size"
|
||||
android:layout_height="@dimen/chat_bubble_grid_image_size"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="18dp"
|
||||
android:background="@drawable/shape_squircle_main2_200_5dp"
|
||||
android:visibility="@{model.mediaPreviewAvailable ? View.GONE : View.VISIBLE, default=gone}"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
android:src="@{model.isVideoPreview ? @drawable/file_video : @drawable/file_image, default=@drawable/file_video}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:tint="?attr/color_main2_600" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
|
|
@ -31,7 +47,8 @@
|
|||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
coilBubble="@{model.path}"
|
||||
coilBubble="@{model.mediaPreview}"
|
||||
coilBubbleFallback="@{brokenMediaIcon}"
|
||||
app:layout_constraintHeight_max="@dimen/chat_bubble_big_image_max_size"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
|
@ -41,6 +58,7 @@
|
|||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_600"
|
||||
android:id="@+id/video_duration"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
|
|
@ -48,16 +66,17 @@
|
|||
android:textColor="@{model.isVideoPreview ? @color/white : @color/main2_600}"
|
||||
android:textSize="12sp"
|
||||
android:visibility="@{model.isVideoPreview && model.audioVideoDuration.length() > 0 ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"/>
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/video_preview"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="@dimen/icon_size"
|
||||
android:layout_height="@dimen/icon_size"
|
||||
android:src="@drawable/play_fill"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="@{model.isVideoPreview ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:visibility="@{model.isVideoPreview && model.mediaPreviewAvailable ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintTop_toTopOf="@id/image"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,21 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_margin="1dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/broken_media_icon"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="@dimen/chat_bubble_grid_image_size"
|
||||
android:layout_height="@dimen/chat_bubble_grid_image_size"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="18dp"
|
||||
android:background="@drawable/shape_squircle_main2_200_5dp"
|
||||
android:visibility="@{model.mediaPreviewAvailable ? View.GONE : View.VISIBLE, default=gone}"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
android:src="@{model.isVideoPreview ? @drawable/file_video : @drawable/file_image, default=@drawable/file_video}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:tint="?attr/color_main2_600" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="@dimen/chat_bubble_grid_image_size"
|
||||
|
|
@ -26,7 +41,8 @@
|
|||
android:scaleType="centerCrop"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
android:visibility="@{model.isImage || model.isVideoPreview ? View.VISIBLE : View.GONE}"
|
||||
coilBubbleGrid="@{model.path}"
|
||||
coilBubbleGrid="@{model.mediaPreview}"
|
||||
coilBubbleFallback="@{brokenMediaIcon}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
|
|
@ -40,8 +56,8 @@
|
|||
android:textColor="@{model.isVideoPreview ? @color/white : @color/main2_600}"
|
||||
android:textSize="12sp"
|
||||
android:visibility="@{model.isVideoPreview && model.audioVideoDuration.length() > 0 ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"/>
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/video_preview"
|
||||
|
|
@ -49,7 +65,7 @@
|
|||
android:layout_height="@dimen/icon_size"
|
||||
android:src="@drawable/play_fill"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="@{model.isVideoPreview ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:visibility="@{model.isVideoPreview && model.mediaPreviewAvailable ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintTop_toTopOf="@id/image"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,24 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/broken_media_icon"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="1dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="18dp"
|
||||
android:background="@drawable/shape_squircle_main2_200_5dp"
|
||||
android:visibility="@{model.mediaPreviewAvailable ? View.GONE : View.VISIBLE, default=gone}"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
android:src="@{model.isVideoPreview ? @drawable/file_video : @drawable/file_image, default=@drawable/file_video}"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:tint="?attr/color_main2_600" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
|
|
@ -22,7 +40,8 @@
|
|||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:contentDescription="@{model.isVideoPreview ? @string/content_description_chat_bubble_video : @string/content_description_chat_bubble_image}"
|
||||
coilBubbleGrid="@{model.path}"
|
||||
coilBubbleGrid="@{model.mediaPreview}"
|
||||
coilBubbleFallback="@{brokenMediaIcon}"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
@ -47,6 +66,7 @@
|
|||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style_600"
|
||||
android:id="@+id/audio_video_duration"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
|
|
@ -59,11 +79,12 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/video_preview"
|
||||
android:onClick="@{() -> model.onClick()}"
|
||||
android:layout_width="@dimen/icon_size"
|
||||
android:layout_height="@dimen/icon_size"
|
||||
android:src="@drawable/play_fill"
|
||||
android:contentDescription="@null"
|
||||
android:visibility="@{model.isVideoPreview ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:visibility="@{model.isVideoPreview && model.mediaPreviewAvailable ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintTop_toTopOf="@id/image"
|
||||
app:layout_constraintBottom_toBottomOf="@id/image"
|
||||
app:layout_constraintStart_toStartOf="@id/image"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue