From 42a25443ce114bae2034c72de7e0949ef417372a Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Fri, 26 Jul 2024 11:39:53 -0500 Subject: [PATCH 1/3] WIP Getting Gif to Work Signed-off-by: rapterjet2004 --- .../messages/PreviewMessageViewHolder.kt | 5 +++ .../com/nextcloud/talk/chat/ChatActivity.kt | 34 +++++++++++++++---- .../item_custom_incoming_preview_message.xml | 4 +-- .../item_custom_outcoming_preview_message.xml | 4 +-- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt index 7ff68e9519..89d3da756e 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt @@ -42,6 +42,7 @@ import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType import com.nextcloud.talk.utils.FileViewerUtils import com.nextcloud.talk.utils.FileViewerUtils.ProgressUi +import com.nextcloud.talk.utils.MimetypeUtils.isGif import com.nextcloud.talk.utils.message.MessageUtils import com.stfalcon.chatkit.messages.MessageHolders.IncomingImageMessageViewHolder import io.reactivex.Single @@ -232,6 +233,10 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) : if (message.selectedIndividualHashMap!!.containsKey(KEY_MIMETYPE)) { val mimetype = message.selectedIndividualHashMap!![KEY_MIMETYPE] + if (isGif(mimetype!!)) { + return message + } + val drawableResourceId = getDrawableResourceIdForMimeType(mimetype) var drawable = ContextCompat.getDrawable(context!!, drawableResourceId) if (drawable != null && diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index daec274265..bb7d3566d1 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -50,6 +50,7 @@ import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.view.ContextThemeWrapper +import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.PERMISSION_GRANTED @@ -187,6 +188,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode +import pl.droidsonroids.gif.GifDrawable import retrofit2.HttpException import retrofit2.Response import java.io.File @@ -1073,8 +1075,32 @@ class ChatActivity : adapter = TalkMessagesListAdapter( senderId, initMessageHolders(), - ImageLoader { imageView, url, placeholder -> - imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, placeholder as Drawable?) + ImageLoader { imageView, url, data -> + try { + if ((data is ChatMessage)) { // It's a GIF + val filename = data.selectedIndividualHashMap!!["name"] + val path = context.cacheDir.absolutePath + "/" + filename + val file = File(context.cacheDir, filename!!) + if (file.exists()) { + val gifFromUri = GifDrawable(path) + imageView.setImageDrawable(gifFromUri) + } else { + // TODO download file to cache can't be called here -_-, need to figure out another way + // to get this preloaded, likely in PreviewMessageViewHolder + val placeholder = ContextCompat.getDrawable(context, R.drawable.ic_mimetype_file) + imageView.setImageDrawable(placeholder) + downloadFileToCache(data, false) { + val gifFromUri = GifDrawable(path) + imageView.setImageDrawable(gifFromUri) + } + } + } else { // Not a GIF + imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, data as Drawable?) + } + } catch (e: java.lang.IllegalStateException) { + Log.e(TAG, "Error in ImageLoading in initAdapter $e") + } + }, this ) @@ -3384,10 +3410,6 @@ class ChatActivity : val messageTemp = message as ChatMessage messageTemp.lastEditTimestamp = message.lastEditTimestamp - val index = adapter?.getMessagePositionById(messageTemp.id) ?: 0 - val adapterMsg = adapter?.items?.get(index)?.item as ChatMessage - - messageTemp.parentMessage = adapterMsg.parentMessage messageTemp.isOneToOneConversation = currentConversation?.type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL messageTemp.activeUser = conversationUser diff --git a/app/src/main/res/layout/item_custom_incoming_preview_message.xml b/app/src/main/res/layout/item_custom_incoming_preview_message.xml index d55d065b1a..ae87f04e7e 100644 --- a/app/src/main/res/layout/item_custom_incoming_preview_message.xml +++ b/app/src/main/res/layout/item_custom_incoming_preview_message.xml @@ -63,11 +63,11 @@ app:layout_wrapBefore="true" tools:visibility="gone"> - diff --git a/app/src/main/res/layout/item_custom_outcoming_preview_message.xml b/app/src/main/res/layout/item_custom_outcoming_preview_message.xml index 886241975f..b2cb6bf4cc 100644 --- a/app/src/main/res/layout/item_custom_outcoming_preview_message.xml +++ b/app/src/main/res/layout/item_custom_outcoming_preview_message.xml @@ -39,11 +39,11 @@ app:layout_flexGrow="1" app:layout_wrapBefore="true"> - From 02e4b491a849e3a4917b1889448c2cdecba0445a Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Mon, 29 Jul 2024 11:29:03 -0500 Subject: [PATCH 2/3] WIP Got Gif to work and size up - now need to fix glitches when I add images to the chat - something wrong with the placeholder logic - I should check the adapter Signed-off-by: rapterjet2004 --- .../messages/PreviewMessageViewHolder.kt | 98 +++++++++++++++++++ .../com/nextcloud/talk/chat/ChatActivity.kt | 23 +---- .../item_custom_incoming_preview_message.xml | 1 - .../item_custom_outcoming_preview_message.xml | 1 - 4 files changed, 100 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt index 89d3da756e..1be8fe7fa5 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/PreviewMessageViewHolder.kt @@ -22,21 +22,28 @@ import android.widget.ImageView import android.widget.ProgressBar import androidx.core.content.ContextCompat import androidx.emoji2.widget.EmojiTextView +import androidx.work.Data +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkInfo +import androidx.work.WorkManager import autodagger.AutoInjector import com.google.android.material.card.MaterialCardView import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication +import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.components.filebrowser.models.BrowserFile import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding import com.nextcloud.talk.extensions.loadChangelogBotAvatar import com.nextcloud.talk.extensions.loadFederatedUserAvatar +import com.nextcloud.talk.jobs.DownloadFileToCacheWorker import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.users.UserManager +import com.nextcloud.talk.utils.CapabilitiesUtil import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType @@ -50,8 +57,11 @@ import io.reactivex.SingleObserver import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import okhttp3.OkHttpClient +import pl.droidsonroids.gif.GifDrawable import java.io.ByteArrayInputStream +import java.io.File import java.io.IOException +import java.util.concurrent.ExecutionException import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) @@ -102,10 +112,25 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) : viewThemeUtils!!.platform.colorCircularProgressBar(progressBar!!, ColorRole.PRIMARY) clickView = image messageText.visibility = View.VISIBLE + if (message.getCalculateMessageType() === ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) { fileViewerUtils = FileViewerUtils(context!!, message.activeUser!!) val fileName = message.selectedIndividualHashMap!![KEY_NAME] + if (message.selectedIndividualHashMap!!.containsKey(KEY_MIMETYPE)) { + val mimetype = message.selectedIndividualHashMap!![KEY_MIMETYPE] + if (isGif(mimetype!!)) { + val file = File(context!!.cacheDir, fileName!!) + if (file.exists()) { + setGif(fileName) + } else { + // downloads the file to cache + downloadFileToCache(message, openWhenDownloaded = false) { + setGif(fileName) + } + } + } + } messageText.text = fileName if (message.activeUser != null && @@ -193,6 +218,15 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) : } } + private fun setGif(fileName: String?) { + val path = context!!.cacheDir.absolutePath + "/" + fileName + val gifFromUri = GifDrawable(path) + (clickView as ImageView).setImageDrawable(gifFromUri) + (clickView as ImageView).scaleType = ImageView.ScaleType.CENTER_CROP + (clickView as ImageView).layoutParams.width = 800 + (clickView as ImageView).layoutParams.height = 800 + } + private fun longClickOnReaction(chatMessage: ChatMessage) { commonMessageInterface.onLongClickReactions(chatMessage) } @@ -318,6 +352,70 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) : this.previewMessageInterface = previewMessageInterface } + private fun downloadFileToCache( + message: ChatMessage, + openWhenDownloaded: Boolean, + funToCallWhenDownloadSuccessful: (() -> Unit) + ) { + message.isDownloadingVoiceMessage = true + message.openWhenDownloaded = openWhenDownloaded + + val baseUrl = message.activeUser!!.baseUrl + val userId = message.activeUser!!.userId + val attachmentFolder = CapabilitiesUtil.getAttachmentFolder( + message.activeUser!!.capabilities!! + .spreedCapability!! + ) + val fileName = message.selectedIndividualHashMap!!["name"] + var size = message.selectedIndividualHashMap!!["size"] + if (size == null) { + size = "-1" + } + val fileSize = size.toLong() + val fileId = message.selectedIndividualHashMap!!["id"] + val path = message.selectedIndividualHashMap!!["path"] + + // check if download worker is already running + val workers = WorkManager.getInstance( + context!! + ).getWorkInfosByTag(fileId!!) + try { + for (workInfo in workers.get()) { + if (workInfo.state == WorkInfo.State.RUNNING || workInfo.state == WorkInfo.State.ENQUEUED) { + Log.d(ChatActivity.TAG, "Download worker for $fileId is already running or scheduled") + return + } + } + } catch (e: ExecutionException) { + Log.e(ChatActivity.TAG, "Error when checking if worker already exists", e) + } catch (e: InterruptedException) { + Log.e(ChatActivity.TAG, "Error when checking if worker already exists", e) + } + + val data: Data = Data.Builder() + .putString(DownloadFileToCacheWorker.KEY_BASE_URL, baseUrl) + .putString(DownloadFileToCacheWorker.KEY_USER_ID, userId) + .putString(DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER, attachmentFolder) + .putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileName) + .putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path) + .putLong(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileSize) + .build() + + val downloadWorker: OneTimeWorkRequest = OneTimeWorkRequest.Builder(DownloadFileToCacheWorker::class.java) + .setInputData(data) + .addTag(fileId) + .build() + + WorkManager.getInstance().enqueue(downloadWorker) + + WorkManager.getInstance(context!!).getWorkInfoByIdLiveData(downloadWorker.id) + .observeForever { workInfo: WorkInfo -> + if (workInfo.state == WorkInfo.State.SUCCEEDED) { + funToCallWhenDownloadSuccessful() + } + } + } + abstract val messageText: EmojiTextView abstract val messageCaption: EmojiTextView abstract val previewContainer: View diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index bb7d3566d1..c5eea32549 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -50,7 +50,6 @@ import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.view.ContextThemeWrapper -import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.PERMISSION_GRANTED @@ -188,7 +187,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode -import pl.droidsonroids.gif.GifDrawable import retrofit2.HttpException import retrofit2.Response import java.io.File @@ -1077,27 +1075,10 @@ class ChatActivity : initMessageHolders(), ImageLoader { imageView, url, data -> try { - if ((data is ChatMessage)) { // It's a GIF - val filename = data.selectedIndividualHashMap!!["name"] - val path = context.cacheDir.absolutePath + "/" + filename - val file = File(context.cacheDir, filename!!) - if (file.exists()) { - val gifFromUri = GifDrawable(path) - imageView.setImageDrawable(gifFromUri) - } else { - // TODO download file to cache can't be called here -_-, need to figure out another way - // to get this preloaded, likely in PreviewMessageViewHolder - val placeholder = ContextCompat.getDrawable(context, R.drawable.ic_mimetype_file) - imageView.setImageDrawable(placeholder) - downloadFileToCache(data, false) { - val gifFromUri = GifDrawable(path) - imageView.setImageDrawable(gifFromUri) - } - } - } else { // Not a GIF + if ((data !is ChatMessage)) { // It's Not a GIF imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, data as Drawable?) } - } catch (e: java.lang.IllegalStateException) { + } catch (e: Exception) { Log.e(TAG, "Error in ImageLoading in initAdapter $e") } diff --git a/app/src/main/res/layout/item_custom_incoming_preview_message.xml b/app/src/main/res/layout/item_custom_incoming_preview_message.xml index ae87f04e7e..50ab19740f 100644 --- a/app/src/main/res/layout/item_custom_incoming_preview_message.xml +++ b/app/src/main/res/layout/item_custom_incoming_preview_message.xml @@ -67,7 +67,6 @@ android:id="@id/image" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="200dp" tools:src="@drawable/ic_call_black_24dp" tools:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/item_custom_outcoming_preview_message.xml b/app/src/main/res/layout/item_custom_outcoming_preview_message.xml index b2cb6bf4cc..54fcd00b4c 100644 --- a/app/src/main/res/layout/item_custom_outcoming_preview_message.xml +++ b/app/src/main/res/layout/item_custom_outcoming_preview_message.xml @@ -42,7 +42,6 @@ From ede40fdb2f4d3f41a798487ba0e69f4947fc636f Mon Sep 17 00:00:00 2001 From: rapterjet2004 Date: Wed, 31 Jul 2024 09:10:49 -0500 Subject: [PATCH 3/3] lint Signed-off-by: rapterjet2004 --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index c5eea32549..e2ea8b8725 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1081,7 +1081,6 @@ class ChatActivity : } catch (e: Exception) { Log.e(TAG, "Error in ImageLoading in initAdapter $e") } - }, this )