Also use Coil to extract image from video + fixed contact matching issue in chat room creation

This commit is contained in:
Sylvain Berfini 2022-04-20 15:47:29 +02:00
parent 5ce69e63cd
commit a1f9b95432
11 changed files with 17 additions and 43 deletions

View file

@ -235,6 +235,7 @@ dependencies {
implementation("io.coil-kt:coil:$coil_version")
implementation("io.coil-kt:coil-gif:$coil_version")
implementation("io.coil-kt:coil-svg:$coil_version")
implementation("io.coil-kt:coil-video:$coil_version")
// https://github.com/Baseflow/PhotoView/blob/master/LICENSE Apache v2.0
implementation 'com.github.chrisbanes:PhotoView:2.3.0'

View file

@ -27,6 +27,7 @@ import coil.ImageLoaderFactory
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder
import coil.decode.VideoFrameDecoder
import coil.disk.DiskCache
import coil.memory.MemoryCache
import org.linphone.core.*
@ -86,6 +87,7 @@ class LinphoneApplication : Application(), ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.components {
add(VideoFrameDecoder.Factory())
add(SvgDecoder.Factory())
if (Version.sdkAboveOrEqual(Version.API28_PIE_90)) {
add(ImageDecoderDecoder.Factory())

View file

@ -19,11 +19,7 @@
*/
package org.linphone.activities.main.chat.data
import android.graphics.Bitmap
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.*
import org.linphone.utils.FileUtils
import org.linphone.utils.ImageUtils
class ChatMessageAttachmentData(
val path: String,
@ -34,23 +30,6 @@ class ChatMessageAttachmentData(
val isVideo: Boolean = FileUtils.isExtensionVideo(path)
val isAudio: Boolean = FileUtils.isExtensionAudio(path)
val isPdf: Boolean = FileUtils.isExtensionPdf(path)
val videoPreview = MutableLiveData<Bitmap>()
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
init {
if (isVideo) {
scope.launch {
withContext(Dispatchers.IO) {
videoPreview.postValue(ImageUtils.getVideoPreview(path))
}
}
}
}
fun destroy() {
scope.cancel()
}
fun delete() {
deleteCallback(this)

View file

@ -19,7 +19,6 @@
*/
package org.linphone.activities.main.chat.data
import android.graphics.Bitmap
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
@ -43,7 +42,6 @@ import org.linphone.core.*
import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils
import org.linphone.utils.FileUtils
import org.linphone.utils.ImageUtils
import org.linphone.utils.TimestampUtils
class ChatMessageContentData(
@ -57,7 +55,6 @@ class ChatMessageContentData(
val isImage = MutableLiveData<Boolean>()
val isVideo = MutableLiveData<Boolean>()
val isAudio = MutableLiveData<Boolean>()
val videoPreview = MutableLiveData<Bitmap>()
val isPdf = MutableLiveData<Boolean>()
val isGenericFile = MutableLiveData<Boolean>()
val isVoiceRecording = MutableLiveData<Boolean>()
@ -264,12 +261,6 @@ class ChatMessageContentData(
} else if (isConferenceIcs) {
parseConferenceInvite(content)
}
if (isVideo.value == true) {
scope.launch {
videoPreview.postValue(ImageUtils.getVideoPreview(path))
}
}
} else if (isConferenceIcs) {
Log.i("[Content] Found content with icalendar file")
parseConferenceInvite(content)

View file

@ -140,7 +140,6 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
}
override fun onCleared() {
attachments.value.orEmpty().forEach(ChatMessageAttachmentData::destroy)
pendingChatMessageToReplyTo.value?.destroy()
if (recorder.state != RecorderState.Closed) {
@ -191,7 +190,6 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
val list = arrayListOf<ChatMessageAttachmentData>()
list.addAll(attachments.value.orEmpty())
list.remove(attachment)
attachment.destroy()
attachments.value = list
sendMessageEnabled.value = textToSend.value.orEmpty().isNotEmpty() || list.isNotEmpty() || isPendingVoiceRecord.value == true
@ -266,7 +264,6 @@ class ChatMessageSendingViewModel(private val chatRoom: ChatRoom) : ViewModel()
}
cancelReply()
attachments.value.orEmpty().forEach(ChatMessageAttachmentData::destroy)
attachments.value = arrayListOf()
textToSend.value = ""

View file

@ -40,6 +40,7 @@ import androidx.constraintlayout.widget.Guideline
import androidx.databinding.*
import coil.load
import coil.request.CachePolicy
import coil.request.videoFrameMillis
import coil.transform.CircleCropTransformation
import com.google.android.material.switchmaterial.SwitchMaterial
import org.linphone.BR
@ -356,6 +357,15 @@ fun loadAvatarWithGlide(imageView: ImageView, path: String?) {
}
}
@BindingAdapter("coilVideoPreview")
fun loadVideoPreview(imageView: ImageView, path: String?) {
if (path != null && path.isNotEmpty() && FileUtils.isExtensionVideo(path)) {
imageView.load(path) {
videoFrameMillis(0)
}
}
}
@BindingAdapter("showSecurityLevel")
fun ContactAvatarView.setShowAvatarSecurityLevel(visible: Boolean) {
this.binding.securityBadgeVisibility = visible

View file

@ -21,9 +21,7 @@ package org.linphone.utils
import android.content.Context
import android.graphics.*
import android.media.ThumbnailUtils
import android.net.Uri
import android.provider.MediaStore
import org.linphone.compatibility.Compatibility
import org.linphone.core.tools.Log
@ -63,10 +61,6 @@ class ImageUtils {
return rotatedBitmap
}
fun getVideoPreview(path: String): Bitmap? {
return ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND)
}
private fun getRoundBitmap(bitmap: Bitmap): Bitmap? {
val output =
Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)

View file

@ -35,7 +35,7 @@
android:layout_alignParentLeft="true"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@{data.videoPreview}"/>
app:coilVideoPreview="@{data.path}"/>
<ImageView
android:visibility="@{data.video ? View.VISIBLE : View.GONE, default=gone}"

View file

@ -39,7 +39,7 @@
android:layout_height="wrap_content"
android:maxHeight="@dimen/chat_message_bubble_image_height_big"
android:layout_size="@{data.alone ? 0f : @dimen/chat_message_bubble_file_size}"
android:src="@{data.videoPreview}"
app:coilVideoPreview="@{data.filePath}"
android:visibility="@{!data.downloadable &amp;&amp; data.video ? View.VISIBLE : View.GONE}"
android:scaleType="@{data.alone ? ScaleType.FIT_CENTER : ScaleType.CENTER_CROP}"
android:adjustViewBounds="true" />

View file

@ -32,7 +32,7 @@
android:layout_height="wrap_content"
android:maxHeight="@dimen/chat_message_bubble_image_height_small"
android:layout_size="@{data.alone ? 0f : @dimen/chat_message_small_bubble_file_size}"
android:src="@{data.videoPreview}"
app:coilVideoPreview="@{data.filePath}"
android:visibility="@{data.video ? View.VISIBLE : View.GONE}"
android:scaleType="@{ScaleType.CENTER_CROP}"
android:adjustViewBounds="true" />

View file

@ -29,7 +29,7 @@
android:layout_width="@dimen/chat_message_small_bubble_file_size"
android:layout_height="@dimen/chat_message_small_bubble_file_size"
android:layout_margin="5dp"
android:src="@{data.videoPreview}"
app:coilVideoPreview="@{data.filePath}"
android:visibility="@{data.video ? View.VISIBLE : View.GONE}"
android:scaleType="@{ScaleType.CENTER_CROP}"
android:adjustViewBounds="true" />