Updated chat bubbles to display images grid

This commit is contained in:
Sylvain Berfini 2023-11-03 11:06:02 +01:00
parent cafa301ea8
commit b585ba7a8b
7 changed files with 50 additions and 20 deletions

View file

@ -90,6 +90,9 @@ dependencies {
implementation "androidx.emoji2:emoji2:$emoji_version"
implementation "androidx.emoji2:emoji2-emojipicker:$emoji_version"
// https://github.com/google/flexbox-layout/blob/main/LICENSE Apache v2.0
implementation 'com.google.android.flexbox:flexbox:3.0.0'
// https://github.com/material-components/material-components-android/blob/master/LICENSE Apache v2.0
implementation 'com.google.android.material:material:1.10.0'

View file

@ -77,9 +77,8 @@ class GridBoxLayout : GridLayout {
val maxChild = placementMatrix[0].size
if (childCount > maxChild) {
val maxMosaicParticipants = 6
Log.e(
"$TAG $childCount children but placementMatrix only knows how to display $maxChild (max allowed participants for grid layout in settings is $maxMosaicParticipants)"
"$TAG $childCount children but placementMatrix only knows how to display $maxChild (max allowed participants for grid layout in settings is 6)"
)
return
}

View file

@ -65,8 +65,6 @@ class ChatMessageModel @WorkerThread constructor(
val text = MutableLiveData<Spannable>()
val imagesList = MutableLiveData<ArrayList<String>>()
val timestamp = chatMessage.time
val time = TimestampUtils.toString(timestamp)
@ -75,6 +73,10 @@ class ChatMessageModel @WorkerThread constructor(
val reactions = MutableLiveData<String>()
val imagesList = MutableLiveData<ArrayList<String>>()
val firstImage = MutableLiveData<String>()
val dismissLongPressMenuEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
@ -125,6 +127,9 @@ class ChatMessageModel @WorkerThread constructor(
when (content.type) {
"image", "video" -> {
imagesPath.add(path)
if (filesContentCount == 1) {
firstImage.postValue(path)
}
displayableContentFound = true
}
"audio" -> {

View file

@ -52,6 +52,7 @@ import androidx.lifecycle.lifecycleScope
import coil.dispose
import coil.load
import coil.request.videoFrameMillis
import coil.transform.RoundedCornersTransformation
import com.google.android.material.imageview.ShapeableImageView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
@ -210,9 +211,13 @@ fun AppCompatTextView.setColor(@ColorRes color: Int) {
@BindingAdapter("coilBubble")
fun ImageView.loadImageForChatBubble(file: String?) {
if (!file.isNullOrEmpty()) {
val radius = context.resources.getDimension(
R.dimen.chat_bubble_images_rounded_corner_radius
)
if (FileUtils.isExtensionVideo(file)) {
load(file) {
videoFrameMillis(0)
transformations(RoundedCornersTransformation(radius))
listener(
onError = { _, result ->
Log.e(
@ -227,6 +232,7 @@ fun ImageView.loadImageForChatBubble(file: String?) {
}
} else {
load(file) {
transformations(RoundedCornersTransformation(radius))
listener(
onError = { _, result ->
Log.e(

View file

@ -1,29 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<import type="com.google.android.flexbox.JustifyContent" />
<variable
name="model"
type="org.linphone.ui.main.chat.model.ChatMessageModel" />
</data>
<RelativeLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<GridLayout
android:id="@+id/grid"
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/images_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:stretchMode="none"
android:gravity="start"
android:visibility="@{model.imagesList.size() >= 2 ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintWidth_max="271dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/single_image"
app:alignItems="center"
app:flexWrap="wrap"
app:justifyContent="@{model.outgoing ? JustifyContent.FLEX_END : JustifyContent.FLEX_START}"
entries="@{model.imagesList}"
layout="@{@layout/chat_bubble_content_grid_cell}"/>
<ImageView
android:id="@+id/single_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:visibility="@{model.imagesList.size() > 1 || model.firstImage.length() == 0 ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toBottomOf="@id/images_grid"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/text_content"
app:layout_constraintHeight_max="@dimen/chat_bubble_big_image_max_size"
coilBubble="@{model.firstImage}"/>
<org.linphone.ui.main.chat.view.ChatBubbleTextView
style="@style/default_text_style"
android:id="@+id/text_content"
@ -33,9 +51,10 @@
android:textSize="14sp"
android:textColor="@color/gray_main2_700"
android:gravity="center_vertical|start"
android:layout_below="@id/grid"
android:visibility="@{model.text.length() > 0 ? View.VISIBLE : View.GONE}"/>
android:visibility="@{model.text.length() > 0 ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/single_image"/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View" />
@ -10,13 +9,11 @@
</data>
<ImageView
android:id="@+id/big_image"
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_margin="1dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/smiley"
coilBubble="@{model}"/>
</layout>

View file

@ -67,6 +67,7 @@
<dimen name="chat_bubble_text_padding_with_status">5dp</dimen>
<dimen name="chat_bubble_long_press_emoji_reaction_size">30sp</dimen>
<dimen name="chat_bubble_big_image_max_size">200dp</dimen>
<dimen name="chat_bubble_images_rounded_corner_radius">5dp</dimen>
<dimen name="chat_room_emoji_picker_height">290dp</dimen>
<dimen name="chat_bubble_emoji_picker_height">425dp</dimen>