Improved file display in chat bubble
This commit is contained in:
parent
a29314bc5e
commit
f19b546dd7
8 changed files with 123 additions and 35 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
BIN
app/src/main/res/drawable-xhdpi/audio.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/audio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue