From f19b546dd7db974be61e3bdf4922fb1d0d7c1119 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 28 Jan 2021 12:56:12 +0100 Subject: [PATCH] Improved file display in chat bubble --- .../viewmodels/ChatMessageContentViewModel.kt | 16 +++ .../main/java/org/linphone/utils/AppUtils.kt | 5 + .../org/linphone/utils/DataBindingUtils.kt | 7 ++ .../main/java/org/linphone/utils/FileUtils.kt | 6 + app/src/main/res/drawable-xhdpi/audio.png | Bin 0 -> 11876 bytes .../res/layout/chat_message_content_cell.xml | 108 ++++++++++++------ .../res/layout/chat_message_list_cell.xml | 4 +- app/src/main/res/values/styles.xml | 12 ++ 8 files changed, 123 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/drawable-xhdpi/audio.png diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageContentViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageContentViewModel.kt index 447b3da8b..1cb2b09b2 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageContentViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatMessageContentViewModel.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.withContext import org.linphone.core.ChatMessage import org.linphone.core.Content import org.linphone.core.tools.Log +import org.linphone.utils.AppUtils import org.linphone.utils.FileUtils import org.linphone.utils.ImageUtils @@ -39,8 +40,13 @@ class ChatMessageContentViewModel( ) : ViewModel() { val isImage = MutableLiveData() val isVideo = MutableLiveData() + val isAudio = MutableLiveData() val videoPreview = MutableLiveData() + val fileName = MutableLiveData() + + val fileSize = MutableLiveData() + val downloadable = MutableLiveData() val downloadEnabled = MutableLiveData() @@ -57,6 +63,13 @@ class ChatMessageContentViewModel( } init { + fileName.value = if (content.name.isNullOrEmpty() && !content.filePath.isNullOrEmpty()) { + FileUtils.getNameFromFilePath(content.filePath!!) + } else { + content.name + } + fileSize.value = AppUtils.bytesToDisplayableSize(content.fileSize.toLong()) + if (content.isFile || (content.isFileTransfer && chatMessage.isOutgoing)) { val filePath = content.filePath ?: "" downloadable.value = filePath.isEmpty() @@ -65,6 +78,7 @@ class ChatMessageContentViewModel( Log.i("[Content] Found displayable content: $filePath") isImage.value = FileUtils.isExtensionImage(filePath) isVideo.value = FileUtils.isExtensionVideo(filePath) + isAudio.value = FileUtils.isExtensionAudio(filePath) if (isVideo.value == true) { viewModelScope.launch { @@ -77,6 +91,7 @@ class ChatMessageContentViewModel( Log.w("[Content] Found content with empty path...") isImage.value = false isVideo.value = false + isAudio.value = false } } else { if (chatMessage.isFileTransferInProgress) { @@ -89,6 +104,7 @@ class ChatMessageContentViewModel( downloadable.value = true isImage.value = false isVideo.value = false + isAudio.value = false } } diff --git a/app/src/main/java/org/linphone/utils/AppUtils.kt b/app/src/main/java/org/linphone/utils/AppUtils.kt index f646ab75a..89f072e28 100644 --- a/app/src/main/java/org/linphone/utils/AppUtils.kt +++ b/app/src/main/java/org/linphone/utils/AppUtils.kt @@ -21,6 +21,7 @@ package org.linphone.utils import android.app.Activity import android.content.* +import android.text.format.Formatter.formatShortFileSize import android.util.TypedValue import androidx.emoji.text.EmojiCompat import java.util.* @@ -79,6 +80,10 @@ class AppUtils { ) } + fun bytesToDisplayableSize(bytes: Long): String { + return formatShortFileSize(coreContext.context, bytes) + } + fun shareUploadedLogsUrl(activity: Activity, info: String) { val appName = activity.getString(R.string.app_name) val intent = Intent(Intent.ACTION_SEND) diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index bdac98df0..ae80027f1 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -137,6 +137,13 @@ fun setLayoutToLeftOf(view: View, oldTargetId: Int, newTargetId: Int) { view.layoutParams = layoutParams } +@BindingAdapter("android:layout_gravity") +fun setLayoutGravity(view: View, gravity: Int) { + val layoutParams = view.layoutParams as LinearLayout.LayoutParams + layoutParams.gravity = gravity + view.layoutParams = layoutParams +} + @BindingAdapter("layout_constraintGuide_percent") fun setLayoutConstraintGuidePercent(guideline: Guideline, percent: Float) { val params = guideline.layoutParams as ConstraintLayout.LayoutParams diff --git a/app/src/main/java/org/linphone/utils/FileUtils.kt b/app/src/main/java/org/linphone/utils/FileUtils.kt index 590a0d841..20635f276 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.kt +++ b/app/src/main/java/org/linphone/utils/FileUtils.kt @@ -71,6 +71,12 @@ class FileUtils { return type?.startsWith("video/") ?: false } + fun isExtensionAudio(path: String): Boolean { + val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault()) + val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) + return type?.startsWith("audio/") ?: false + } + fun getFileStorageDir(isPicture: Boolean = false): File { var path: File? = null if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) { diff --git a/app/src/main/res/drawable-xhdpi/audio.png b/app/src/main/res/drawable-xhdpi/audio.png new file mode 100644 index 0000000000000000000000000000000000000000..472ae2bff761458531466ddb44d1cd47367899e8 GIT binary patch literal 11876 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/chat_message_content_cell.xml b/app/src/main/res/layout/chat_message_content_cell.xml index 86f5fcd20..1bb821108 100644 --- a/app/src/main/res/layout/chat_message_content_cell.xml +++ b/app/src/main/res/layout/chat_message_content_cell.xml @@ -47,43 +47,83 @@ android:layout_centerInParent="true"/> - - + android:padding="10dp" + android:gravity="center_vertical" + android:text="@{data.fileName}" + android:onClick="@{() -> data.openFile()}" + android:onLongClick="@{longClickListener}" + android:visibility="@{data.downloadable || data.image || data.video || !data.alone ? View.GONE : View.VISIBLE, default=gone}" + android:drawablePadding="10dp" + app:drawableTint="@color/dark_grey_color" + android:drawableLeft="@{data.isAudio ? @drawable/audio : @drawable/file}"/> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/chat_message_list_cell.xml b/app/src/main/res/layout/chat_message_list_cell.xml index 29ad6e347..74bbd7a82 100644 --- a/app/src/main/res/layout/chat_message_list_cell.xml +++ b/app/src/main/res/layout/chat_message_list_cell.xml @@ -6,6 +6,7 @@ + @@ -126,7 +127,7 @@ app:layout="@{@layout/chat_message_content_cell}" app:onLongClick="@{contextMenuClickListener}" app:flexWrap="wrap" - app:justifyContent="center"/> + app:justifyContent="@{viewModel.chatMessage.outgoing ? JustifyContent.FLEX_END : JustifyContent.FLEX_START}"/> 18sp + + + + +