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

make attributes of file nullable and handle null values
This commit is contained in:
Andy Scherzinger 2022-05-07 12:54:56 +02:00 committed by GitHub
commit 0c5429bd7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 45 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,6 +29,7 @@ import android.os.Build
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.emoji.widget.EmojiTextView import androidx.emoji.widget.EmojiTextView
import androidx.work.Data import androidx.work.Data
@ -82,8 +83,8 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
fun openFile( fun openFile(
fileInfo: FileInfo, fileInfo: FileInfo,
path: String, path: String,
link: String, link: String?,
mimetype: String, mimetype: String?,
progressUi: ProgressUi progressUi: ProgressUi
) { ) {
if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileInfo.fileName)) { if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileInfo.fileName)) {
@ -93,12 +94,20 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
mimetype, mimetype,
progressUi progressUi
) )
} else { } else if (!link.isNullOrEmpty()) {
openFileInFilesApp(link, fileInfo.fileId) 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 path: String = context.cacheDir.absolutePath + "/" + fileName
val file = File(path) val file = File(path)
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
@ -109,12 +118,12 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
private fun openOrDownloadFile( private fun openOrDownloadFile(
fileInfo: FileInfo, fileInfo: FileInfo,
path: String, path: String,
mimetype: String, mimetype: String?,
progressUi: ProgressUi progressUi: ProgressUi
) { ) {
val file = File(context.cacheDir, fileInfo.fileName) val file = File(context.cacheDir, fileInfo.fileName)
if (file.exists()) { if (file.exists()) {
openFileByMimetype(fileInfo.fileName!!, mimetype!!) openFileByMimetype(fileInfo.fileName!!, mimetype)
} else { } else {
downloadFileToCache( downloadFileToCache(
fileInfo, fileInfo,
@ -125,24 +134,29 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
} }
} }
private fun openFileByMimetype(filename: String, mimetype: String) { private fun openFileByMimetype(filename: String, mimetype: String?) {
when (mimetype) { if (mimetype != null) {
"audio/mpeg", when (mimetype) {
"audio/wav", "audio/mpeg",
"audio/ogg", "audio/wav",
"video/mp4", "audio/ogg",
"video/quicktime", "video/mp4",
"video/ogg" "video/quicktime",
-> openMediaView(filename, mimetype) "video/ogg"
"image/png", -> openMediaView(filename, mimetype)
"image/jpeg", "image/png",
"image/gif" "image/jpeg",
-> openImageView(filename, mimetype) "image/gif"
"text/markdown", -> openImageView(filename, mimetype)
"text/plain" "text/markdown",
-> openTextView(filename, mimetype) "text/plain"
else -> openTextView(filename, mimetype)
-> openFileByExternalApp(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( private fun downloadFileToCache(
fileInfo: FileInfo, fileInfo: FileInfo,
path: String, path: String,
mimetype: String, mimetype: String?,
progressUi: ProgressUi progressUi: ProgressUi
) { ) {
// check if download worker is already running // 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) Log.e(TAG, "Error when checking if worker already exists", e)
} }
val downloadWorker: OneTimeWorkRequest val downloadWorker: OneTimeWorkRequest
val size: Long = if (fileInfo.fileSize == null) {
-1
} else {
fileInfo.fileSize!!
}
val data: Data = Data.Builder() val data: Data = Data.Builder()
.putString(DownloadFileToCacheWorker.KEY_BASE_URL, userEntity.baseUrl) .putString(DownloadFileToCacheWorker.KEY_BASE_URL, userEntity.baseUrl)
.putString(DownloadFileToCacheWorker.KEY_USER_ID, userEntity.userId) .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_NAME, fileInfo.fileName)
.putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path) .putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
.putLong(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileInfo.fileSize) .putLong(DownloadFileToCacheWorker.KEY_FILE_SIZE, size)
.build() .build()
downloadWorker = OneTimeWorkRequest.Builder(DownloadFileToCacheWorker::class.java) downloadWorker = OneTimeWorkRequest.Builder(DownloadFileToCacheWorker::class.java)
.setInputData(data) .setInputData(data)
.addTag(fileInfo.fileId) .addTag(fileInfo.fileId)
@ -303,7 +325,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
private fun updateViewsByProgress( private fun updateViewsByProgress(
fileName: String, fileName: String,
mimetype: String, mimetype: String?,
workInfo: WorkInfo, workInfo: WorkInfo,
progressUi: ProgressUi progressUi: ProgressUi
) { ) {
@ -343,7 +365,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
fun resumeToUpdateViewsByProgress( fun resumeToUpdateViewsByProgress(
fileName: String, fileName: String,
fileId: String, fileId: String,
mimeType: String, mimeType: String?,
progressUi: ProgressUi progressUi: ProgressUi
) { ) {
val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId) val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId)
@ -383,7 +405,7 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
data class FileInfo( data class FileInfo(
val fileId: String, val fileId: String,
val fileName: String, val fileName: String,
var fileSize: Long var fileSize: Long?
) )
companion object { companion object {

View File

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