Allow to pick multiple files in chat message picker

This commit is contained in:
Sylvain Berfini 2021-01-29 11:04:15 +01:00
parent 3159ed7ab3
commit 9a548ff388
4 changed files with 76 additions and 25 deletions

View file

@ -338,12 +338,10 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch { lifecycleScope.launch {
val fileToUploadPath = ImageUtils.getImageFilePathFromPickerIntent( for (fileToUploadPath in ImageUtils.getFilesPathFromPickerIntent(data, chatSendingViewModel.temporaryFileUploadPath)) {
data, if (fileToUploadPath != null) {
chatSendingViewModel.temporaryFileUploadPath chatSendingViewModel.addAttachment(fileToUploadPath)
) }
if (fileToUploadPath != null) {
chatSendingViewModel.addAttachment(fileToUploadPath)
} }
} }
} }
@ -481,6 +479,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
val galleryIntent = Intent(Intent.ACTION_PICK) val galleryIntent = Intent(Intent.ACTION_PICK)
galleryIntent.type = "*/*" galleryIntent.type = "*/*"
galleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*")) galleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
galleryIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
if (PermissionHelper.get().hasCameraPermission()) { if (PermissionHelper.get().hasCameraPermission()) {
// Allows to capture directly from the camera // Allows to capture directly from the camera
@ -497,6 +496,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
// Finally allow any kind of file // Finally allow any kind of file
val fileIntent = Intent(Intent.ACTION_GET_CONTENT) val fileIntent = Intent(Intent.ACTION_GET_CONTENT)
fileIntent.type = "*/*" fileIntent.type = "*/*"
fileIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
cameraIntents.add(fileIntent) cameraIntents.add(fileIntent)
} }

View file

@ -132,7 +132,7 @@ class ContactEditorFragment : GenericFragment<ContactEditorFragmentBinding>(), S
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch { lifecycleScope.launch {
val contactImageFilePath = ImageUtils.getImageFilePathFromPickerIntent(data, temporaryPicturePath) val contactImageFilePath = ImageUtils.getFilePathFromPickerIntent(data, temporaryPicturePath)
if (contactImageFilePath != null) { if (contactImageFilePath != null) {
viewModel.setPictureFromPath(contactImageFilePath) viewModel.setPictureFromPath(contactImageFilePath)
} }

View file

@ -120,7 +120,7 @@ class SideMenuFragment : GenericFragment<SideMenuFragmentBinding>() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch { lifecycleScope.launch {
val contactImageFilePath = ImageUtils.getImageFilePathFromPickerIntent(data, temporaryPicturePath) val contactImageFilePath = ImageUtils.getFilePathFromPickerIntent(data, temporaryPicturePath)
if (contactImageFilePath != null) { if (contactImageFilePath != null) {
viewModel.setPictureFromPath(contactImageFilePath) viewModel.setPictureFromPath(contactImageFilePath)
} }

View file

@ -71,17 +71,64 @@ class ImageUtils {
return ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND) return ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND)
} }
suspend fun getImageFilePathFromPickerIntent(data: Intent?, temporaryImageFilePath: File?): String? { suspend fun getFilesPathFromPickerIntent(data: Intent?, temporaryImageFilePath: File?): List<String> {
var imageFilePath: String? = null var imageFilePath: String? = null
if (temporaryImageFilePath != null) { if (temporaryImageFilePath != null) {
if (data != null) { if (data != null) {
val dataUri = data.data val clipData = data.clipData
if (dataUri != null) { if (clipData != null) { // Multiple selection
imageFilePath = dataUri.toString() Log.i("[Image Utils] Found ${clipData.itemCount} elements")
Log.i("[Image Utils] Using data URI $imageFilePath") val list = arrayListOf<String>()
} else if (temporaryImageFilePath.exists()) { for (i in 0 until clipData.itemCount) {
imageFilePath = temporaryImageFilePath.absolutePath val dataUri = clipData.getItemAt(i).uri
Log.i("[Image Utils] Data URI is null, using $imageFilePath") if (dataUri != null) {
imageFilePath = dataUri.toString()
Log.i("[Image Utils] Using data URI $imageFilePath")
}
imageFilePath = cleanFilePath(imageFilePath)
if (imageFilePath != null) list.add(imageFilePath)
}
return list
} else { // Single selection
val dataUri = data.data
if (dataUri != null) {
imageFilePath = dataUri.toString()
Log.i("[Image Utils] Using data URI $imageFilePath")
} else if (temporaryImageFilePath.exists()) {
imageFilePath = temporaryImageFilePath.absolutePath
Log.i("[Image Utils] Data URI is null, using $imageFilePath")
}
imageFilePath = cleanFilePath(imageFilePath)
if (imageFilePath != null) return arrayListOf(imageFilePath)
}
} else if (temporaryImageFilePath.exists()) {
imageFilePath = temporaryImageFilePath.absolutePath
Log.i("[Image Utils] Data is null, using $imageFilePath")
imageFilePath = cleanFilePath(imageFilePath)
if (imageFilePath != null) return arrayListOf(imageFilePath)
}
}
return arrayListOf()
}
suspend fun getFilePathFromPickerIntent(data: Intent?, temporaryImageFilePath: File?): String? {
var imageFilePath: String? = null
if (temporaryImageFilePath != null) {
if (data != null) {
val clipData = data.clipData
if (clipData != null) { // Multiple selection
for (i in 0 until clipData.itemCount) {
val uri = clipData.getItemAt(i).uri
}
} else { // Single selection
val dataUri = data.data
if (dataUri != null) {
imageFilePath = dataUri.toString()
Log.i("[Image Utils] Using data URI $imageFilePath")
} else if (temporaryImageFilePath.exists()) {
imageFilePath = temporaryImageFilePath.absolutePath
Log.i("[Image Utils] Data URI is null, using $imageFilePath")
}
} }
} else if (temporaryImageFilePath.exists()) { } else if (temporaryImageFilePath.exists()) {
imageFilePath = temporaryImageFilePath.absolutePath imageFilePath = temporaryImageFilePath.absolutePath
@ -89,20 +136,24 @@ class ImageUtils {
} }
} }
if (imageFilePath != null) { return cleanFilePath(imageFilePath)
if (imageFilePath.startsWith("content://") || }
imageFilePath.startsWith("file://")
private suspend fun cleanFilePath(filePath: String?): String? {
if (filePath != null) {
if (filePath.startsWith("content://") ||
filePath.startsWith("file://")
) { ) {
val uriToParse = Uri.parse(imageFilePath) val uriToParse = Uri.parse(filePath)
imageFilePath = FileUtils.getFilePath(coreContext.context, uriToParse) val result = FileUtils.getFilePath(coreContext.context, uriToParse)
Log.i("[Image Utils] Path was using a content or file scheme, real path is: $imageFilePath") Log.i("[Image Utils] Path was using a content or file scheme, real path is: $filePath")
if (imageFilePath == null) { if (result == null) {
Log.e("[Image Utils] Failed to get access to file $uriToParse") Log.e("[Image Utils] Failed to get access to file $uriToParse")
} }
return result
} }
} }
return filePath
return imageFilePath
} }
private fun getRoundBitmap(bitmap: Bitmap): Bitmap? { private fun getRoundBitmap(bitmap: Bitmap): Bitmap? {