Эх сурвалжийг харах

open files from media view

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 3 жил өмнө
parent
commit
912bc3c8fe

+ 15 - 3
app/src/main/java/com/nextcloud/talk/adapters/SharedItemsAdapter.kt

@@ -1,18 +1,18 @@
 package com.nextcloud.talk.adapters
 
 import android.net.Uri
-import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.RecyclerView
 import com.facebook.drawee.backends.pipeline.Fresco
 import com.facebook.drawee.interfaces.DraweeController
+import com.facebook.drawee.view.SimpleDraweeView
 import com.facebook.imagepipeline.common.RotationOptions
 import com.facebook.imagepipeline.request.ImageRequestBuilder
-import com.nextcloud.talk.activities.SharedItemsActivity
 import com.nextcloud.talk.databinding.AttachmentItemBinding
 import com.nextcloud.talk.repositories.SharedItem
+import com.nextcloud.talk.utils.FileViewerUtils
 
 class SharedItemsAdapter : RecyclerView.Adapter<SharedItemsAdapter.ViewHolder>() {
 
@@ -50,7 +50,19 @@ class SharedItemsAdapter : RecyclerView.Adapter<SharedItemsAdapter.ViewHolder>()
             holder.binding.image.controller = draweeController
 
             holder.binding.image.setOnClickListener {
-                Log.d(TAG, "clicked " + currentItem.name)
+                val fileViewerUtils = FileViewerUtils(it.context, currentItem.userEntity)
+
+                fileViewerUtils.openFile(
+                    currentItem.id,
+                    currentItem.name,
+                    currentItem.fileSize,
+                    currentItem.path,
+                    currentItem.link,
+                    currentItem.mimeType,
+                    null,
+                    null,
+                    it as SimpleDraweeView
+                )
             }
         }
     }

+ 17 - 41
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java

@@ -41,7 +41,6 @@ import android.widget.PopupMenu;
 import android.widget.ProgressBar;
 
 import com.facebook.drawee.view.SimpleDraweeView;
-import com.google.common.util.concurrent.ListenableFuture;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
@@ -59,16 +58,14 @@ import com.stfalcon.chatkit.messages.MessageHolders;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
 
 import javax.inject.Inject;
 
 import androidx.appcompat.view.ContextThemeWrapper;
 import androidx.core.content.ContextCompat;
 import androidx.emoji.widget.EmojiTextView;
-import androidx.work.WorkInfo;
-import androidx.work.WorkManager;
 import autodagger.AutoInjector;
 import io.reactivex.Single;
 import io.reactivex.SingleObserver;
@@ -112,7 +109,6 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
     public MagicPreviewMessageViewHolder(View itemView, Object payload) {
         super(itemView, payload);
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
-        fileViewerUtils = new FileViewerUtils(context);
     }
 
     @SuppressLint("SetTextI18n")
@@ -154,6 +150,8 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
 
         if (message.getMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
 
+            fileViewerUtils = new FileViewerUtils(context, message.activeUser);
+
             String fileName = message.getSelectedIndividualHashMap().get(KEY_NAME);
             getMessageText().setText(fileName);
             if (message.getSelectedIndividualHashMap().containsKey(KEY_CONTACT_NAME)) {
@@ -183,52 +181,26 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
             }
 
             if (message.activeUser != null && message.activeUser.getUsername() != null && message.activeUser.getBaseUrl() != null) {
-                String accountString =
-                    message.activeUser.getUsername() + "@" +
-                        message.activeUser.getBaseUrl()
-                            .replace("https://", "")
-                            .replace("http://", "");
-
                 clickView.setOnClickListener(v -> {
                     fileViewerUtils.openFile(message, progressBar, getMessageText(), image);
                 });
 
                 clickView.setOnLongClickListener(l -> {
-                    onMessageViewLongClick(message, accountString);
+                    onMessageViewLongClick(message);
                     return true;
                 });
             } else {
                 Log.e(TAG, "failed to set click listener because activeUser, username or baseUrl were null");
             }
 
+            fileViewerUtils.resumeToUpdateViewsByProgress(
+                Objects.requireNonNull(message.getSelectedIndividualHashMap().get(MagicPreviewMessageViewHolder.KEY_NAME)),
+                Objects.requireNonNull(message.getSelectedIndividualHashMap().get(MagicPreviewMessageViewHolder.KEY_ID)),
+                Objects.requireNonNull(message.getSelectedIndividualHashMap().get(MagicPreviewMessageViewHolder.KEY_MIMETYPE)),
+                progressBar,
+                getMessageText(),
+                image);
 
-            // check if download worker is already running
-            String fileId = message.getSelectedIndividualHashMap().get(KEY_ID);
-            ListenableFuture<List<WorkInfo>> workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId);
-
-            try {
-                for (WorkInfo workInfo : workers.get()) {
-                    if (workInfo.getState() == WorkInfo.State.RUNNING ||
-                        workInfo.getState() == WorkInfo.State.ENQUEUED) {
-                        progressBar.setVisibility(View.VISIBLE);
-
-                        String mimetype = message.getSelectedIndividualHashMap().get(KEY_MIMETYPE);
-
-                        WorkManager
-                            .getInstance(context)
-                            .getWorkInfoByIdLiveData(workInfo.getId())
-                            .observeForever(info -> fileViewerUtils.updateViewsByProgress(
-                                fileName,
-                                mimetype,
-                                info,
-                                progressBar,
-                                getMessageText(),
-                                image));
-                    }
-                }
-            } catch (ExecutionException | InterruptedException e) {
-                Log.e(TAG, "Error when checking if worker already exists", e);
-            }
         } else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {
             getMessageText().setText("GIPHY");
             DisplayUtils.setClickableString("GIPHY", "https://giphy.com", getMessageText());
@@ -279,7 +251,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
         return drawable;
     }
 
-    private void onMessageViewLongClick(ChatMessage message, String accountString) {
+    private void onMessageViewLongClick(ChatMessage message) {
         if (fileViewerUtils.isSupportedForInternalViewer(message.getSelectedIndividualHashMap().get(KEY_MIMETYPE))) {
             previewMessageInterface.onPreviewMessageLongClick(message);
             return;
@@ -301,7 +273,11 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
         popupMenu.inflate(R.menu.chat_preview_message_menu);
 
         popupMenu.setOnMenuItemClickListener(item -> {
-            fileViewerUtils.openFileInFilesApp(message, accountString);
+            if (item.getItemId()== R.id.openInFiles){
+                String keyID = message.getSelectedIndividualHashMap().get(KEY_ID);
+                String link = message.getSelectedIndividualHashMap().get("link");
+                fileViewerUtils.openFileInFilesApp(link, keyID);
+            }
             return true;
         });
 

+ 3 - 0
app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java

@@ -156,6 +156,9 @@ public class ChatMessage implements MessageContentType, MessageContentType.Image
                 if (MessageDigest.isEqual(
                     Objects.requireNonNull(individualHashMap.get("type")).getBytes(Charsets.UTF_8),
                     ("file").getBytes(Charsets.UTF_8))) {
+
+                    // TODO: this selectedIndividualHashMap stuff needs to be analyzed and most likely be refactored!
+                    //  it just feels wrong to fill this here inside getImageUrl()
                     selectedIndividualHashMap = individualHashMap;
                     if (!isVoiceMessage()) {
                         if (getActiveUser() != null && getActiveUser().getBaseUrl() != null) {

+ 7 - 2
app/src/main/java/com/nextcloud/talk/repositories/SharedItem.kt

@@ -1,10 +1,15 @@
 package com.nextcloud.talk.repositories
 
+import com.nextcloud.talk.models.database.UserEntity
+
 data class SharedItem(
     val id: String,
     val name: String,
-    val mimeType: String,
+    val fileSize: Int,
+    val path: String,
     val link: String,
+    val mimeType: String,
     val previewAvailable: Boolean,
-    val previewLink: String
+    val previewLink: String,
+    val userEntity: UserEntity,
 )

+ 2 - 0
app/src/main/java/com/nextcloud/talk/repositories/SharedItemsRepository.kt

@@ -4,6 +4,7 @@ import autodagger.AutoInjector
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
+import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.chat.ChatShareOverall
 import com.nextcloud.talk.utils.ApiUtils
 import io.reactivex.Observable
@@ -48,6 +49,7 @@ class SharedItemsRepository {
         val userName: String,
         val userToken: String,
         val baseUrl: String,
+        val userEntity: UserEntity,
         val roomToken: String
     )
 }

+ 168 - 56
app/src/main/java/com/nextcloud/talk/utils/FileViewerUtils.kt

@@ -27,23 +27,68 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACCOUNT
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_ID
 import androidx.emoji.widget.EmojiTextView
 import com.facebook.drawee.view.SimpleDraweeView
+import com.nextcloud.talk.models.database.UserEntity
 import java.io.File
 import java.util.concurrent.ExecutionException
 
-class FileViewerUtils(private val context: Context) {
-    fun openFile(message: ChatMessage, progressBar: ProgressBar, messageText: EmojiTextView, previewImage: SimpleDraweeView) {
-        val accountString = message.activeUser.username + "@" +
-            message.activeUser.baseUrl
-                .replace("https://", "")
-                .replace("http://", "")
+class FileViewerUtils(private val context: Context, private val userEntity: UserEntity) {
 
+    fun openFile(
+        message: ChatMessage,
+        progressBar: ProgressBar?,
+        messageText: EmojiTextView?,
+        previewImage: SimpleDraweeView
+    ) {
         val fileName = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]!!
         val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]!!
+        val link = message.getSelectedIndividualHashMap()["link"]!!
 
+        val fileId = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_ID]!!
+        val path = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_PATH]!!
+
+        var size = message.getSelectedIndividualHashMap()["size"]
+        if (size == null) {
+            size = "-1"
+        }
+        val fileSize = Integer.valueOf(size)
+
+        openFile(
+            fileId,
+            fileName,
+            fileSize,
+            path,
+            link,
+            mimetype,
+            progressBar,
+            messageText,
+            previewImage
+        )
+    }
+
+    fun openFile(
+        fileId: String,
+        fileName: String,
+        fileSize: Int,
+        path: String,
+        link: String,
+        mimetype: String,
+        progressBar: ProgressBar?,
+        messageText: EmojiTextView?,
+        previewImage: SimpleDraweeView
+    ) {
         if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileName)) {
-            openOrDownloadFile(message, progressBar, messageText, previewImage)
+            openOrDownloadFile(
+                fileName,
+                fileId,
+                path,
+                fileSize,
+                mimetype,
+                progressBar,
+                messageText,
+                previewImage
+            )
         } else {
-            openFileInFilesApp(message, accountString)
+            openFileInFilesApp(link, fileId)
         }
     }
 
@@ -55,26 +100,51 @@ class FileViewerUtils(private val context: Context) {
         return intent.resolveActivity(context.packageManager) != null
     }
 
-    private fun openOrDownloadFile(message: ChatMessage, progressBar: ProgressBar, messageText: EmojiTextView, previewImage: SimpleDraweeView) {
-        val filename = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]
-        val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]
-        val file = File(context.cacheDir, filename)
+    private fun openOrDownloadFile(
+        fileName: String,
+        fileId: String,
+        path: String,
+        fileSize: Int,
+        mimetype: String,
+        progressBar: ProgressBar?,
+        messageText: EmojiTextView?,
+        previewImage: SimpleDraweeView
+    ) {
+        val file = File(context.cacheDir, fileName)
         if (file.exists()) {
-            openFile(filename!!, mimetype!!)
+            openFileByMimetype(fileName!!, mimetype!!)
         } else {
-            downloadFileToCache(message, progressBar, messageText, previewImage)
+            downloadFileToCache(
+                fileName,
+                fileId,
+                path,
+                fileSize,
+                mimetype,
+                progressBar,
+                messageText,
+                previewImage
+            )
         }
     }
 
-    private fun openFile(filename: String, mimetype: String) {
+    private fun openFileByMimetype(filename: String, mimetype: String) {
         when (mimetype) {
-            "audio/mpeg", "audio/wav", "audio/ogg", "video/mp4", "video/quicktime", "video/ogg" -> openMediaView(
-                filename,
-                mimetype
-            )
-            "image/png", "image/jpeg", "image/gif" -> openImageView(filename, mimetype)
-            "text/markdown", "text/plain" -> openTextView(filename, mimetype)
-            else -> openFileByExternalApp(filename, mimetype)
+            "audio/mpeg",
+            "audio/wav",
+            "audio/ogg",
+            "video/mp4",
+            "video/quicktime",
+            "video/ogg"
+            -> openMediaView(filename, mimetype)
+            "image/png",
+            "image/jpeg",
+            "image/gif"
+            -> openImageView(filename, mimetype)
+            "text/markdown",
+            "text/plain"
+            -> openTextView(filename, mimetype)
+            else
+            -> openFileByExternalApp(filename, mimetype)
         }
     }
 
@@ -106,7 +176,12 @@ class FileViewerUtils(private val context: Context) {
         }
     }
 
-    fun openFileInFilesApp(message: ChatMessage, accountString: String) {
+    fun openFileInFilesApp(link: String, keyID: String) {
+        val accountString = userEntity.username + "@" +
+            userEntity.baseUrl
+                .replace("https://", "")
+                .replace("http://", "")
+
         if (canWeOpenFilesApp(context, accountString)) {
             val filesAppIntent = Intent(Intent.ACTION_VIEW, null)
             val componentName = ComponentName(
@@ -117,15 +192,12 @@ class FileViewerUtils(private val context: Context) {
             filesAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
             filesAppIntent.setPackage(context.getString(R.string.nc_import_accounts_from))
             filesAppIntent.putExtra(KEY_ACCOUNT, accountString)
-            filesAppIntent.putExtra(
-                KEY_FILE_ID,
-                message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_ID]
-            )
+            filesAppIntent.putExtra(KEY_FILE_ID, keyID)
             context.startActivity(filesAppIntent)
         } else {
             val browserIntent = Intent(
                 Intent.ACTION_VIEW,
-                Uri.parse(message.getSelectedIndividualHashMap()["link"])
+                Uri.parse(link)
             )
             browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
             context.startActivity(browserIntent)
@@ -176,20 +248,16 @@ class FileViewerUtils(private val context: Context) {
     }
 
     @SuppressLint("LongLogTag")
-    private fun downloadFileToCache(message: ChatMessage, progressBar: ProgressBar, messageText: EmojiTextView, previewImage: SimpleDraweeView) {
-        val baseUrl = message.activeUser.baseUrl
-        val userId = message.activeUser.userId
-        val attachmentFolder = CapabilitiesUtil.getAttachmentFolder(message.activeUser)
-        val fileName = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]!!
-        val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]!!
-        var size = message.getSelectedIndividualHashMap()["size"]
-        if (size == null) {
-            size = "-1"
-        }
-        val fileSize = Integer.valueOf(size)
-        val fileId = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_ID]
-        val path = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_PATH]
-
+    private fun downloadFileToCache(
+        fileName: String,
+        fileId: String,
+        path: String,
+        fileSize: Int,
+        mimetype: String,
+        progressBar: ProgressBar?,
+        messageText: EmojiTextView?,
+        previewImage: SimpleDraweeView
+    ) {
         // check if download worker is already running
         val workers = WorkManager.getInstance(context).getWorkInfosByTag(
             fileId!!
@@ -208,9 +276,12 @@ class FileViewerUtils(private val context: Context) {
         }
         val downloadWorker: OneTimeWorkRequest
         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_BASE_URL, userEntity.baseUrl)
+            .putString(DownloadFileToCacheWorker.KEY_USER_ID, userEntity.userId)
+            .putString(
+                DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER,
+                CapabilitiesUtil.getAttachmentFolder(userEntity)
+            )
             .putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileName)
             .putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
             .putInt(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileSize)
@@ -220,7 +291,7 @@ class FileViewerUtils(private val context: Context) {
             .addTag(fileId)
             .build()
         WorkManager.getInstance().enqueue(downloadWorker)
-        progressBar.visibility = View.VISIBLE
+        progressBar?.visibility = View.VISIBLE
         WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.id)
             .observeForever { workInfo: WorkInfo? ->
                 updateViewsByProgress(
@@ -234,19 +305,19 @@ class FileViewerUtils(private val context: Context) {
             }
     }
 
-    fun updateViewsByProgress(
+    private fun updateViewsByProgress(
         fileName: String,
         mimetype: String,
         workInfo: WorkInfo,
-        progressBar: ProgressBar,
-        messageText: EmojiTextView,
+        progressBar: ProgressBar?,
+        messageText: EmojiTextView?,
         previewImage: SimpleDraweeView
     ) {
         when (workInfo.state) {
             WorkInfo.State.RUNNING -> {
                 val progress = workInfo.progress.getInt(DownloadFileToCacheWorker.PROGRESS, -1)
                 if (progress > -1) {
-                    messageText.text = String.format(
+                    messageText?.text = String.format(
                         context.resources.getString(R.string.filename_progress),
                         fileName,
                         progress
@@ -255,25 +326,66 @@ class FileViewerUtils(private val context: Context) {
             }
             WorkInfo.State.SUCCEEDED -> {
                 if (previewImage.isShown) {
-                    openFile(fileName, mimetype)
+                    openFileByMimetype(fileName, mimetype)
                 } else {
-                    Log.d(TAG, "file " + fileName +
+                    Log.d(
+                        TAG, "file " + fileName +
                             " was downloaded but it's not opened because view is not shown on screen"
                     )
                 }
-                messageText.text = fileName
-                progressBar.visibility = View.GONE
+                messageText?.text = fileName
+                progressBar?.visibility = View.GONE
             }
             WorkInfo.State.FAILED -> {
-                messageText.text = fileName
-                progressBar.visibility = View.GONE
+                messageText?.text = fileName
+                progressBar?.visibility = View.GONE
             }
             else -> {
             }
         }
     }
 
+    fun resumeToUpdateViewsByProgress(
+        fileName: String,
+        fileId: String,
+        mimeType: String,
+        progressBar: ProgressBar,
+        messageText: EmojiTextView?,
+        previewImage: SimpleDraweeView
+    ) {
+        val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId)
+
+        try {
+            for (workInfo in workers.get()) {
+                if (workInfo.state == WorkInfo.State.RUNNING ||
+                    workInfo.state == WorkInfo.State.ENQUEUED
+                ) {
+                    progressBar.visibility = View.VISIBLE
+                    WorkManager
+                        .getInstance(context)
+                        .getWorkInfoByIdLiveData(workInfo.id)
+                        .observeForever { info: WorkInfo? ->
+                            updateViewsByProgress(
+                                fileName,
+                                mimeType,
+                                info!!,
+                                progressBar,
+                                messageText,
+                                previewImage
+                            )
+                        }
+                }
+            }
+        } catch (e: ExecutionException) {
+            Log.e(TAG, "Error when checking if worker already exists", e)
+        } catch (e: InterruptedException) {
+            Log.e(TAG, "Error when checking if worker already exists", e)
+        }
+    }
+
     companion object {
         private val TAG = FileViewerUtils::class.simpleName
+
+        const val KEY_ID = "id"
     }
 }

+ 9 - 3
app/src/main/java/com/nextcloud/talk/viewmodels/SharedItemsViewModel.kt

@@ -51,10 +51,15 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository) : View
                         val previewAvailable = "yes".equals(fileParameters["preview-available"]!!, ignoreCase = true)
 
                         items[it.value.id] = SharedItem(
-                            fileParameters["id"]!!, fileParameters["name"]!!,
-                            fileParameters["mimetype"]!!, fileParameters["link"]!!,
+                            fileParameters["id"]!!,
+                            fileParameters["name"]!!,
+                            fileParameters["size"]!!.toInt(),
+                            fileParameters["path"]!!,
+                            fileParameters["link"]!!,
+                            fileParameters["mimetype"]!!,
                             previewAvailable,
-                            repository.previewLink(fileParameters["id"])
+                            repository.previewLink(fileParameters["id"]),
+                            repository.parameters!!.userEntity
                         )
                     }
                 }
@@ -84,6 +89,7 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository) : View
                     userEntity.userId,
                     userEntity.token,
                     userEntity.baseUrl,
+                    userEntity,
                     roomToken
                 )