Improved file display in chat bubble

This commit is contained in:
Sylvain Berfini 2021-01-28 12:56:12 +01:00
parent a29314bc5e
commit f19b546dd7
8 changed files with 123 additions and 35 deletions

View file

@ -29,6 +29,7 @@ import kotlinx.coroutines.withContext
import org.linphone.core.ChatMessage import org.linphone.core.ChatMessage
import org.linphone.core.Content import org.linphone.core.Content
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils
import org.linphone.utils.FileUtils import org.linphone.utils.FileUtils
import org.linphone.utils.ImageUtils import org.linphone.utils.ImageUtils
@ -39,8 +40,13 @@ class ChatMessageContentViewModel(
) : ViewModel() { ) : ViewModel() {
val isImage = MutableLiveData<Boolean>() val isImage = MutableLiveData<Boolean>()
val isVideo = MutableLiveData<Boolean>() val isVideo = MutableLiveData<Boolean>()
val isAudio = MutableLiveData<Boolean>()
val videoPreview = MutableLiveData<Bitmap>() val videoPreview = MutableLiveData<Bitmap>()
val fileName = MutableLiveData<String>()
val fileSize = MutableLiveData<String>()
val downloadable = MutableLiveData<Boolean>() val downloadable = MutableLiveData<Boolean>()
val downloadEnabled = MutableLiveData<Boolean>() val downloadEnabled = MutableLiveData<Boolean>()
@ -57,6 +63,13 @@ class ChatMessageContentViewModel(
} }
init { 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)) { if (content.isFile || (content.isFileTransfer && chatMessage.isOutgoing)) {
val filePath = content.filePath ?: "" val filePath = content.filePath ?: ""
downloadable.value = filePath.isEmpty() downloadable.value = filePath.isEmpty()
@ -65,6 +78,7 @@ class ChatMessageContentViewModel(
Log.i("[Content] Found displayable content: $filePath") Log.i("[Content] Found displayable content: $filePath")
isImage.value = FileUtils.isExtensionImage(filePath) isImage.value = FileUtils.isExtensionImage(filePath)
isVideo.value = FileUtils.isExtensionVideo(filePath) isVideo.value = FileUtils.isExtensionVideo(filePath)
isAudio.value = FileUtils.isExtensionAudio(filePath)
if (isVideo.value == true) { if (isVideo.value == true) {
viewModelScope.launch { viewModelScope.launch {
@ -77,6 +91,7 @@ class ChatMessageContentViewModel(
Log.w("[Content] Found content with empty path...") Log.w("[Content] Found content with empty path...")
isImage.value = false isImage.value = false
isVideo.value = false isVideo.value = false
isAudio.value = false
} }
} else { } else {
if (chatMessage.isFileTransferInProgress) { if (chatMessage.isFileTransferInProgress) {
@ -89,6 +104,7 @@ class ChatMessageContentViewModel(
downloadable.value = true downloadable.value = true
isImage.value = false isImage.value = false
isVideo.value = false isVideo.value = false
isAudio.value = false
} }
} }

View file

@ -21,6 +21,7 @@ package org.linphone.utils
import android.app.Activity import android.app.Activity
import android.content.* import android.content.*
import android.text.format.Formatter.formatShortFileSize
import android.util.TypedValue import android.util.TypedValue
import androidx.emoji.text.EmojiCompat import androidx.emoji.text.EmojiCompat
import java.util.* 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) { fun shareUploadedLogsUrl(activity: Activity, info: String) {
val appName = activity.getString(R.string.app_name) val appName = activity.getString(R.string.app_name)
val intent = Intent(Intent.ACTION_SEND) val intent = Intent(Intent.ACTION_SEND)

View file

@ -137,6 +137,13 @@ fun setLayoutToLeftOf(view: View, oldTargetId: Int, newTargetId: Int) {
view.layoutParams = layoutParams 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") @BindingAdapter("layout_constraintGuide_percent")
fun setLayoutConstraintGuidePercent(guideline: Guideline, percent: Float) { fun setLayoutConstraintGuidePercent(guideline: Guideline, percent: Float) {
val params = guideline.layoutParams as ConstraintLayout.LayoutParams val params = guideline.layoutParams as ConstraintLayout.LayoutParams

View file

@ -71,6 +71,12 @@ class FileUtils {
return type?.startsWith("video/") ?: false 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 { fun getFileStorageDir(isPicture: Boolean = false): File {
var path: File? = null var path: File? = null
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) { if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -47,43 +47,83 @@
android:layout_centerInParent="true"/> android:layout_centerInParent="true"/>
<TextView <TextView
style="@style/chat_file_attachment_font"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
android:padding="10dp"
android:gravity="center_vertical"
android:text="@{data.fileName}"
android:onClick="@{() -> data.openFile()}" android:onClick="@{() -> data.openFile()}"
android:onLongClick="@{longClickListener}" android:onLongClick="@{longClickListener}"
android:textColor="?attr/secondaryTextColor" android:visibility="@{data.downloadable || data.image || data.video || !data.alone ? View.GONE : View.VISIBLE, default=gone}"
android:textSize="12sp" android:drawablePadding="10dp"
android:fontFamily="sans-serif" app:drawableTint="@color/dark_grey_color"
android:textStyle="normal" android:drawableLeft="@{data.isAudio ? @drawable/audio : @drawable/file}"/>
android:drawableTop="@drawable/file"
android:drawableTint="?attr/drawableTintColor2" <TextView
android:drawablePadding="5dp" style="@style/chat_file_attachment_font"
android:padding="5dp"
android:text="@{data.content.name}"
android:visibility="@{data.downloadable || data.image || data.video ? View.GONE : View.VISIBLE, default=gone}"
android:layout_width="150dp" android:layout_width="150dp"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:maxHeight="100dp" android:maxHeight="100dp"
android:layout_margin="5dp" android:layout_margin="5dp"
android:background="@color/chat_bubble_text_color"
android:ellipsize="end" android:ellipsize="end"
android:padding="10dp"
android:gravity="center" android:gravity="center"
android:textAlignment="center" /> android:textAlignment="center"
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:drawableTop="@{data.isAudio ? @drawable/audio : @drawable/file}"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:background="@drawable/resizable_assistant_button"
android:visibility="@{data.downloadable ? View.VISIBLE : View.GONE}"
android:onClick="@{() -> data.download()}"
android:onLongClick="@{longClickListener}"
android:enabled="@{data.downloadEnabled}">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/download"
android:padding="10dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:padding="10dp">
<TextView
style="@style/button_small_font"
android:text="@{data.fileName + ` (` + data.fileSize + `)`}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textColor="@drawable/assistant_button_text_color" />
<TextView <TextView
style="@style/button_font" style="@style/button_font"
android:onClick="@{() -> data.download()}"
android:onLongClick="@{longClickListener}"
android:enabled="@{data.downloadEnabled}"
android:text="@string/chat_message_download_file" android:text="@string/chat_message_download_file"
android:visibility="@{data.downloadable ? View.VISIBLE : View.GONE}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textColor="@drawable/assistant_button_text_color" android:textColor="@drawable/assistant_button_text_color"
android:background="@drawable/resizable_assistant_button" android:layout_marginTop="5dp"
android:drawableLeft="@drawable/download" android:ellipsize="end" />
android:drawablePadding="10dp"
android:ellipsize="end" </LinearLayout>
android:padding="10dp" />
</LinearLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -6,6 +6,7 @@
<data> <data>
<import type="android.view.View"/> <import type="android.view.View"/>
<import type="android.view.Gravity"/> <import type="android.view.Gravity"/>
<import type="com.google.android.flexbox.JustifyContent"/>
<variable <variable
name="contextMenuClickListener" name="contextMenuClickListener"
type="android.view.View.OnLongClickListener"/> type="android.view.View.OnLongClickListener"/>
@ -126,7 +127,7 @@
app:layout="@{@layout/chat_message_content_cell}" app:layout="@{@layout/chat_message_content_cell}"
app:onLongClick="@{contextMenuClickListener}" app:onLongClick="@{contextMenuClickListener}"
app:flexWrap="wrap" app:flexWrap="wrap"
app:justifyContent="center"/> app:justifyContent="@{viewModel.chatMessage.outgoing ? JustifyContent.FLEX_END : JustifyContent.FLEX_START}"/>
<org.linphone.activities.main.chat.views.MultiLineWrapContentWidthTextView <org.linphone.activities.main.chat.views.MultiLineWrapContentWidthTextView
android:onClick="@{clickListener}" android:onClick="@{clickListener}"
@ -134,6 +135,7 @@
android:text="@{viewModel.text}" android:text="@{viewModel.text}"
android:visibility="@{viewModel.text.length > 0 ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.text.length > 0 ? View.VISIBLE : View.GONE}"
android:autoLink="web" android:autoLink="web"
android:layout_gravity="@{viewModel.chatMessage.outgoing ? Gravity.RIGHT : Gravity.LEFT}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"

View file

@ -224,6 +224,12 @@
<item name="android:textSize">18sp</item> <item name="android:textSize">18sp</item>
</style> </style>
<style name="chat_file_attachment_font" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">@color/dark_grey_color</item>
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">sans-serif</item>
</style>
<style name="standard_text_font" parent="@android:style/TextAppearance.Medium"> <style name="standard_text_font" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">?attr/primaryTextColor</item> <item name="android:textColor">?attr/primaryTextColor</item>
<item name="android:textSize">18sp</item> <item name="android:textSize">18sp</item>
@ -235,6 +241,11 @@
<item name="android:textSize">16sp</item> <item name="android:textSize">16sp</item>
</style> </style>
<style name="button_small_font" parent="@android:style/TextAppearance.Small">
<item name="android:textColor">?attr/primaryTextColor</item>
<item name="android:textSize">13sp</item>
</style>
<style name="standard_small_text_font" parent="@android:style/TextAppearance.Medium"> <style name="standard_small_text_font" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">?attr/primarySubtextDarkColor</item> <item name="android:textColor">?attr/primarySubtextDarkColor</item>
<item name="android:textSize">15sp</item> <item name="android:textSize">15sp</item>
@ -244,4 +255,5 @@
<item name="android:textColor">@color/white_color</item> <item name="android:textColor">@color/white_color</item>
<item name="android:textSize">10sp</item> <item name="android:textSize">10sp</item>
</style> </style>
</resources> </resources>