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 <juliuslinus1@gmail.com>
This commit is contained in:
rapterjet2004 2024-07-29 11:29:03 -05:00
parent 42a25443ce
commit 02e4b491a8
No known key found for this signature in database
GPG Key ID: 3AA5FDFED7944099
4 changed files with 100 additions and 23 deletions

View File

@ -22,21 +22,28 @@ import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.emoji2.widget.EmojiTextView 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 autodagger.AutoInjector
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication 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.models.BrowserFile
import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
import com.nextcloud.talk.extensions.loadChangelogBotAvatar import com.nextcloud.talk.extensions.loadChangelogBotAvatar
import com.nextcloud.talk.extensions.loadFederatedUserAvatar import com.nextcloud.talk.extensions.loadFederatedUserAvatar
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType import com.nextcloud.talk.utils.DrawableUtils.getDrawableResourceIdForMimeType
@ -50,8 +57,11 @@ import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import pl.droidsonroids.gif.GifDrawable
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.File
import java.io.IOException import java.io.IOException
import java.util.concurrent.ExecutionException
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
@ -102,10 +112,25 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) :
viewThemeUtils!!.platform.colorCircularProgressBar(progressBar!!, ColorRole.PRIMARY) viewThemeUtils!!.platform.colorCircularProgressBar(progressBar!!, ColorRole.PRIMARY)
clickView = image clickView = image
messageText.visibility = View.VISIBLE messageText.visibility = View.VISIBLE
if (message.getCalculateMessageType() === ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) { if (message.getCalculateMessageType() === ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
fileViewerUtils = FileViewerUtils(context!!, message.activeUser!!) fileViewerUtils = FileViewerUtils(context!!, message.activeUser!!)
val fileName = message.selectedIndividualHashMap!![KEY_NAME] 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 messageText.text = fileName
if (message.activeUser != null && 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) { private fun longClickOnReaction(chatMessage: ChatMessage) {
commonMessageInterface.onLongClickReactions(chatMessage) commonMessageInterface.onLongClickReactions(chatMessage)
} }
@ -318,6 +352,70 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) :
this.previewMessageInterface = previewMessageInterface 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 messageText: EmojiTextView
abstract val messageCaption: EmojiTextView abstract val messageCaption: EmojiTextView
abstract val previewContainer: View abstract val previewContainer: View

View File

@ -50,7 +50,6 @@ import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
@ -188,7 +187,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import pl.droidsonroids.gif.GifDrawable
import retrofit2.HttpException import retrofit2.HttpException
import retrofit2.Response import retrofit2.Response
import java.io.File import java.io.File
@ -1077,27 +1075,10 @@ class ChatActivity :
initMessageHolders(), initMessageHolders(),
ImageLoader { imageView, url, data -> ImageLoader { imageView, url, data ->
try { try {
if ((data is ChatMessage)) { // It's a GIF if ((data !is ChatMessage)) { // It's Not 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?) imageView.loadAvatarOrImagePreview(url!!, conversationUser!!, data as Drawable?)
} }
} catch (e: java.lang.IllegalStateException) { } catch (e: Exception) {
Log.e(TAG, "Error in ImageLoading in initAdapter $e") Log.e(TAG, "Error in ImageLoading in initAdapter $e")
} }

View File

@ -67,7 +67,6 @@
android:id="@id/image" android:id="@id/image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="200dp"
tools:src="@drawable/ic_call_black_24dp" tools:src="@drawable/ic_call_black_24dp"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />

View File

@ -42,7 +42,6 @@
<pl.droidsonroids.gif.GifImageView <pl.droidsonroids.gif.GifImageView
android:id="@id/image" android:id="@id/image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:minHeight="200dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:src="@drawable/ic_call_black_24dp" tools:src="@drawable/ic_call_black_24dp"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />