瀏覽代碼

Merge pull request #2001 from nextcloud/bugfux/1975/fixNPEforMimetype

make attributes of file nullable and handle null values
Andy Scherzinger 3 年之前
父節點
當前提交
0c5429bd7b

+ 1 - 1
app/src/main/java/com/nextcloud/talk/adapters/SharedItemsGridAdapter.kt

@@ -40,7 +40,7 @@ class SharedItemsGridAdapter : RecyclerView.Adapter<SharedItemsGridAdapter.ViewH
 
         val currentItem = items[position]
 
-        if (currentItem.previewAvailable) {
+        if (currentItem.previewAvailable == true) {
             val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(currentItem.previewLink))
                 .setProgressiveRenderingEnabled(true)
                 .setRotationOptions(RotationOptions.autoRotate())

+ 7 - 5
app/src/main/java/com/nextcloud/talk/adapters/SharedItemsListAdapter.kt

@@ -44,15 +44,17 @@ class SharedItemsListAdapter : RecyclerView.Adapter<SharedItemsListAdapter.ViewH
         val currentItem = items[position]
 
         holder.binding.fileName.text = currentItem.name
-        holder.binding.fileSize.text = Formatter.formatShortFileSize(
-            holder.binding.fileSize.context,
-            currentItem.fileSize
-        )
+        holder.binding.fileSize.text = currentItem.fileSize?.let {
+            Formatter.formatShortFileSize(
+                holder.binding.fileSize.context,
+                it
+            )
+        }
         holder.binding.fileDate.text = DateUtils.getLocalDateTimeStringFromTimestamp(
             currentItem.date * ONE_SECOND_IN_MILLIS
         )
 
-        if (currentItem.previewAvailable) {
+        if (currentItem.previewAvailable == true) {
             val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(currentItem.previewLink))
                 .setProgressiveRenderingEnabled(true)
                 .setRotationOptions(RotationOptions.autoRotate())

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

@@ -199,7 +199,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
             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)),
+                message.getSelectedIndividualHashMap().get(MagicPreviewMessageViewHolder.KEY_MIMETYPE),
                 new FileViewerUtils.ProgressUi(progressBar, getMessageText(), image));
 
         } else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {

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

@@ -5,12 +5,12 @@ import com.nextcloud.talk.models.database.UserEntity
 data class SharedItem(
     val id: String,
     val name: String,
-    val fileSize: Long,
+    val fileSize: Long?,
     val date: Long,
     val path: String,
-    val link: String,
-    val mimeType: String,
-    val previewAvailable: Boolean,
+    val link: String?,
+    val mimeType: String?,
+    val previewAvailable: Boolean?,
     val previewLink: String,
     val userEntity: UserEntity,
 )

+ 5 - 1
app/src/main/java/com/nextcloud/talk/utils/DrawableUtils.kt

@@ -25,7 +25,7 @@ import java.util.HashMap
 
 object DrawableUtils {
 
-    fun getDrawableResourceIdForMimeType(mimetype: String): Int {
+    fun getDrawableResourceIdForMimeType(mimetype: String?): Int {
         var localMimetype = mimetype
         val drawableMap = HashMap<String, Int>()
 
@@ -143,6 +143,10 @@ object DrawableUtils {
         drawableMap["unknown"] = R.drawable.ic_mimetype_file
         drawableMap["application/pdf"] = R.drawable.ic_mimetype_application_pdf
 
+        if (localMimetype.isNullOrEmpty()) {
+            return drawableMap["unknown"]!!
+        }
+
         if ("DIR" == localMimetype) {
             localMimetype = "inode/directory"
             return drawableMap[localMimetype]!!

+ 51 - 29
app/src/main/java/com/nextcloud/talk/utils/FileViewerUtils.kt

@@ -29,6 +29,7 @@ import android.os.Build
 import android.util.Log
 import android.view.View
 import android.widget.ProgressBar
+import android.widget.Toast
 import androidx.core.content.FileProvider
 import androidx.emoji.widget.EmojiTextView
 import androidx.work.Data
@@ -82,8 +83,8 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
     fun openFile(
         fileInfo: FileInfo,
         path: String,
-        link: String,
-        mimetype: String,
+        link: String?,
+        mimetype: String?,
         progressUi: ProgressUi
     ) {
         if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileInfo.fileName)) {
@@ -93,12 +94,20 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
                 mimetype,
                 progressUi
             )
-        } else {
+        } else if (!link.isNullOrEmpty()) {
             openFileInFilesApp(link, fileInfo.fileId)
+        } else {
+            Log.e(
+                TAG,
+                "File with id " + fileInfo.fileId + " can't be opened because internal viewer doesn't " +
+                    "support it, it can't be handled by an external app and there is no link " +
+                    "to open it in the nextcloud files app"
+            )
+            Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
         }
     }
 
-    private fun canBeHandledByExternalApp(mimetype: String, fileName: String): Boolean {
+    private fun canBeHandledByExternalApp(mimetype: String?, fileName: String): Boolean {
         val path: String = context.cacheDir.absolutePath + "/" + fileName
         val file = File(path)
         val intent = Intent(Intent.ACTION_VIEW)
@@ -109,12 +118,12 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
     private fun openOrDownloadFile(
         fileInfo: FileInfo,
         path: String,
-        mimetype: String,
+        mimetype: String?,
         progressUi: ProgressUi
     ) {
         val file = File(context.cacheDir, fileInfo.fileName)
         if (file.exists()) {
-            openFileByMimetype(fileInfo.fileName!!, mimetype!!)
+            openFileByMimetype(fileInfo.fileName!!, mimetype)
         } else {
             downloadFileToCache(
                 fileInfo,
@@ -125,24 +134,29 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
         }
     }
 
-    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)
+    private fun openFileByMimetype(filename: String, mimetype: String?) {
+        if (mimetype != null) {
+            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)
+            }
+        } else {
+            Log.e(TAG, "can't open file with unknown mimetype")
+            Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
         }
     }
 
@@ -255,7 +269,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
     private fun downloadFileToCache(
         fileInfo: FileInfo,
         path: String,
-        mimetype: String,
+        mimetype: String?,
         progressUi: ProgressUi
     ) {
         // check if download worker is already running
@@ -273,6 +287,13 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
             Log.e(TAG, "Error when checking if worker already exists", e)
         }
         val downloadWorker: OneTimeWorkRequest
+
+        val size: Long = if (fileInfo.fileSize == null) {
+            -1
+        } else {
+            fileInfo.fileSize!!
+        }
+
         val data: Data = Data.Builder()
             .putString(DownloadFileToCacheWorker.KEY_BASE_URL, userEntity.baseUrl)
             .putString(DownloadFileToCacheWorker.KEY_USER_ID, userEntity.userId)
@@ -282,8 +303,9 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
             )
             .putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileInfo.fileName)
             .putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
-            .putLong(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileInfo.fileSize)
+            .putLong(DownloadFileToCacheWorker.KEY_FILE_SIZE, size)
             .build()
+
         downloadWorker = OneTimeWorkRequest.Builder(DownloadFileToCacheWorker::class.java)
             .setInputData(data)
             .addTag(fileInfo.fileId)
@@ -303,7 +325,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
 
     private fun updateViewsByProgress(
         fileName: String,
-        mimetype: String,
+        mimetype: String?,
         workInfo: WorkInfo,
         progressUi: ProgressUi
     ) {
@@ -343,7 +365,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
     fun resumeToUpdateViewsByProgress(
         fileName: String,
         fileId: String,
-        mimeType: String,
+        mimeType: String?,
         progressUi: ProgressUi
     ) {
         val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId)
@@ -383,7 +405,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
     data class FileInfo(
         val fileId: String,
         val fileName: String,
-        var fileSize: Long
+        var fileSize: Long?
     )
 
     companion object {

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

@@ -76,16 +76,16 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository, privat
                             val fileParameters = it.value.messageParameters["file"]!!
 
                             val previewAvailable =
-                                "yes".equals(fileParameters["preview-available"]!!, ignoreCase = true)
+                                "yes".equals(fileParameters["preview-available"], ignoreCase = true)
 
                             items[it.value.id] = SharedItem(
                                 fileParameters["id"]!!,
                                 fileParameters["name"]!!,
-                                fileParameters["size"]!!.toLong(),
+                                fileParameters["size"]?.toLong(),
                                 it.value.timestamp,
                                 fileParameters["path"]!!,
-                                fileParameters["link"]!!,
-                                fileParameters["mimetype"]!!,
+                                fileParameters["link"],
+                                fileParameters["mimetype"],
                                 previewAvailable,
                                 repository.previewLink(fileParameters["id"]),
                                 repository.parameters!!.userEntity