mattermost-mobile/patches/react-native-image-picker+2.3.1.patch
Mattermost Build 2fa572bcc7
Automated cherry pick of #4195 (#4206)
* Patch react-native-image-picker to allow selecting video

* Improve patch

* Fix Attaching a Photo capture

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
2020-04-22 19:10:28 -04:00

365 lines
14 KiB
Diff

diff --git a/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java b/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
index 48fb5c1..3def244 100644
--- a/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
+++ b/node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
@@ -3,6 +3,7 @@ package com.imagepicker;
import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -49,6 +50,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.List;
+import java.util.ArrayList;
import com.facebook.react.modules.core.PermissionListener;
import com.facebook.react.modules.core.PermissionAwareActivity;
@@ -69,6 +71,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
public static final int REQUEST_LAUNCH_IMAGE_LIBRARY = 13002;
public static final int REQUEST_LAUNCH_VIDEO_LIBRARY = 13003;
public static final int REQUEST_LAUNCH_VIDEO_CAPTURE = 13004;
+ public static final int REQUEST_LAUNCH_MIXED_CAPTURE = 13005;
public static final int REQUEST_PERMISSIONS_FOR_CAMERA = 14001;
public static final int REQUEST_PERMISSIONS_FOR_LIBRARY = 14002;
@@ -266,26 +269,24 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
cameraIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, videoDurationLimit);
}
}
+ else if (pickBoth) {
+ Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ this.setImageCaptureUri(takePictureIntent);
+ Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
+ cameraIntent = new Intent(Intent.ACTION_CHOOSER);
+ Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
+ Intent[] intentArray = new Intent[]{takePictureIntent,takeVideoIntent};
+ cameraIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
+ cameraIntent.putExtra(Intent.EXTRA_TITLE, "Choose an action");
+ cameraIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
+ requestCode = REQUEST_LAUNCH_MIXED_CAPTURE;
+ }
else
{
requestCode = REQUEST_LAUNCH_IMAGE_CAPTURE;
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- final File original = createNewFile(reactContext, this.options, false);
- imageConfig = imageConfig.withOriginalFile(original);
-
- if (imageConfig.original != null) {
- cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
- }else {
- responseHelper.invokeError(callback, "Couldn't get file path for photo");
- return;
- }
- if (cameraCaptureURI == null)
- {
- responseHelper.invokeError(callback, "Couldn't get file path for photo");
- return;
- }
- cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraCaptureURI);
+ this.setImageCaptureUri(cameraIntent);
}
if (cameraIntent.resolveActivity(reactContext.getPackageManager()) == null)
@@ -350,16 +351,19 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
libraryIntent = new Intent(Intent.ACTION_PICK);
libraryIntent.setType("video/*");
}
+ else if (pickBoth) {
+ libraryIntent = new Intent(Intent.ACTION_GET_CONTENT);
+ libraryIntent.addCategory(Intent.CATEGORY_OPENABLE);
+ libraryIntent.setType("image/*");
+ libraryIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});
+ requestCode = REQUEST_LAUNCH_MIXED_CAPTURE;
+ }
else
{
requestCode = REQUEST_LAUNCH_IMAGE_LIBRARY;
libraryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
-
- if (pickBoth)
- {
- libraryIntent.setType("image/* video/*");
- }
+ libraryIntent.setType("image/*");
}
if (libraryIntent.resolveActivity(reactContext.getPackageManager()) == null)
@@ -385,75 +389,47 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
}
}
- @Override
- public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
- //robustness code
- if (passResult(requestCode))
- {
- return;
- }
-
- responseHelper.cleanResponse();
-
- // user cancel
- if (resultCode != Activity.RESULT_OK)
- {
- removeUselessFiles(requestCode, imageConfig);
- responseHelper.invokeCancel(callback);
- callback = null;
- return;
- }
+ protected String getMimeType(Activity activity, Uri uri) {
+ String mimeType = null;
+ if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
+ ContentResolver cr = activity.getApplicationContext().getContentResolver();
+ mimeType = cr.getType(uri);
+ } else {
+ String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
+ .toString());
+ mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
+ fileExtension.toLowerCase());
+ }
+ return mimeType;
+ }
- Uri uri = null;
- switch (requestCode)
+ protected void extractImageFromResult(Activity activity, Uri uri, int requestCode) {
+ String realPath = getRealPathFromURI(uri);
+ String mime = getMimeType(activity, uri);
+ final boolean isUrl = !TextUtils.isEmpty(realPath) &&
+ Patterns.WEB_URL.matcher(realPath).matches();
+ if (realPath == null || isUrl)
{
- case REQUEST_LAUNCH_IMAGE_CAPTURE:
- uri = cameraCaptureURI;
- break;
-
- case REQUEST_LAUNCH_IMAGE_LIBRARY:
- uri = data.getData();
- String realPath = getRealPathFromURI(uri);
- final boolean isUrl = !TextUtils.isEmpty(realPath) &&
- Patterns.WEB_URL.matcher(realPath).matches();
- if (realPath == null || isUrl)
- {
- try
- {
- File file = createFileFromURI(uri);
- realPath = file.getAbsolutePath();
- uri = Uri.fromFile(file);
- }
- catch (Exception e)
- {
- // image not in cache
- responseHelper.putString("error", "Could not read photo");
- responseHelper.putString("uri", uri.toString());
- responseHelper.invokeResponse(callback);
- callback = null;
- return;
- }
- }
- imageConfig = imageConfig.withOriginalFile(new File(realPath));
- break;
-
- case REQUEST_LAUNCH_VIDEO_LIBRARY:
- responseHelper.putString("uri", data.getData().toString());
- responseHelper.putString("path", getRealPathFromURI(data.getData()));
- responseHelper.invokeResponse(callback);
- callback = null;
- return;
-
- case REQUEST_LAUNCH_VIDEO_CAPTURE:
- final String path = getRealPathFromURI(data.getData());
- responseHelper.putString("uri", data.getData().toString());
- responseHelper.putString("path", path);
- fileScan(reactContext, path);
+ try
+ {
+ File file = createFileFromURI(uri);
+ realPath = file.getAbsolutePath();
+ uri = Uri.fromFile(file);
+ }
+ catch (Exception e)
+ {
+ // image not in cache
+ responseHelper.putString("error", "Could not read photo");
+ responseHelper.putString("uri", uri.toString());
responseHelper.invokeResponse(callback);
callback = null;
+ this.options = null;
return;
+ }
}
+ imageConfig = imageConfig.withOriginalFile(new File(realPath));
+
final ReadExifResult result = readExifInterface(responseHelper, imageConfig);
if (result.error != null)
@@ -461,6 +437,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
removeUselessFiles(requestCode, imageConfig);
responseHelper.invokeError(callback, result.error.getMessage());
callback = null;
+ this.options = null;
return;
}
@@ -472,7 +449,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
updatedResultResponse(uri, imageConfig.original.getAbsolutePath());
// don't create a new file if contraint are respected
- if (imageConfig.useOriginal(initialWidth, initialHeight, result.currentRotation))
+ if (imageConfig.useOriginal(initialWidth, initialHeight, result.currentRotation) || mime.equals("image/gif"))
{
responseHelper.putInt("width", initialWidth);
responseHelper.putInt("height", initialHeight);
@@ -481,6 +458,14 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
else
{
imageConfig = getResizedImage(reactContext, this.options, imageConfig, initialWidth, initialHeight, requestCode);
+ if (imageConfig == null)
+ {
+ responseHelper.invokeError(callback, "Could not read image");
+ callback = null;
+ this.options = null;
+ return;
+ }
+
if (imageConfig.resized == null)
{
removeUselessFiles(requestCode, imageConfig);
@@ -523,6 +508,63 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
this.options = null;
}
+ protected void extractVideoFromResult(Uri uri) {
+ responseHelper.putString("uri", uri.toString());
+ responseHelper.putString("path", getRealPathFromURI(uri));
+ responseHelper.invokeResponse(callback);
+ callback = null;
+ this.options = null;
+ }
+
+ @Override
+ public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
+ //robustness code
+ if (passResult(requestCode))
+ {
+ return;
+ }
+
+ responseHelper.cleanResponse();
+
+ // user cancel
+ if (resultCode != Activity.RESULT_OK)
+ {
+ removeUselessFiles(requestCode, imageConfig);
+ responseHelper.invokeCancel(callback);
+ callback = null;
+ return;
+ }
+
+ switch (requestCode)
+ {
+ case REQUEST_LAUNCH_IMAGE_CAPTURE:
+ extractImageFromResult(activity, cameraCaptureURI, requestCode);
+ break;
+
+ case REQUEST_LAUNCH_IMAGE_LIBRARY:
+ extractImageFromResult(activity, data.getData(), requestCode);
+ break;
+
+ case REQUEST_LAUNCH_VIDEO_LIBRARY:
+ extractVideoFromResult(data.getData());
+ break;
+
+ case REQUEST_LAUNCH_MIXED_CAPTURE:
+ case REQUEST_LAUNCH_VIDEO_CAPTURE:
+ if (data == null || data.getData() == null) {
+ extractImageFromResult(activity, cameraCaptureURI, requestCode);
+ } else {
+ Uri selectedMediaUri = data.getData();
+ if (selectedMediaUri.toString().contains("image")) {
+ extractImageFromResult(activity, selectedMediaUri, requestCode);
+ } else {
+ extractVideoFromResult(selectedMediaUri);
+ }
+ }
+ break;
+ }
+ }
+
public void invokeCustomButton(@NonNull final String action)
{
responseHelper.invokeCustomButton(this.callback, action);
@@ -551,7 +593,8 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
{
return callback == null || (cameraCaptureURI == null && requestCode == REQUEST_LAUNCH_IMAGE_CAPTURE)
|| (requestCode != REQUEST_LAUNCH_IMAGE_CAPTURE && requestCode != REQUEST_LAUNCH_IMAGE_LIBRARY
- && requestCode != REQUEST_LAUNCH_VIDEO_LIBRARY && requestCode != REQUEST_LAUNCH_VIDEO_CAPTURE);
+ && requestCode != REQUEST_LAUNCH_VIDEO_LIBRARY && requestCode != REQUEST_LAUNCH_VIDEO_CAPTURE
+ && requestCode != REQUEST_LAUNCH_MIXED_CAPTURE);
}
private void updatedResultResponse(@Nullable final Uri uri,
@@ -571,22 +614,23 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
@NonNull final Callback callback,
@NonNull final int requestCode)
{
- final int writePermission = ActivityCompat
- .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
- final int cameraPermission = ActivityCompat
- .checkSelfPermission(activity, Manifest.permission.CAMERA);
-
- boolean permissionsGranted = false;
-
+ int selfCheckResult = 0;
switch (requestCode) {
case REQUEST_PERMISSIONS_FOR_LIBRARY:
- permissionsGranted = writePermission == PackageManager.PERMISSION_GRANTED;
+ selfCheckResult = ActivityCompat
+ .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
break;
case REQUEST_PERMISSIONS_FOR_CAMERA:
- permissionsGranted = cameraPermission == PackageManager.PERMISSION_GRANTED && writePermission == PackageManager.PERMISSION_GRANTED;
+ selfCheckResult = ActivityCompat
+ .checkSelfPermission(activity, Manifest.permission.CAMERA);
+ if (selfCheckResult == PackageManager.PERMISSION_GRANTED) {
+ selfCheckResult = ActivityCompat
+ .checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ }
break;
}
+ final boolean permissionsGranted = selfCheckResult == PackageManager.PERMISSION_GRANTED;
if (!permissionsGranted)
{
final Boolean dontAskAgain = ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA);
@@ -787,4 +831,22 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
videoDurationLimit = options.getInt("durationLimit");
}
}
+
+ private void setImageCaptureUri(Intent cameraIntent) {
+ final File original = createNewFile(reactContext, this.options, false);
+ imageConfig = imageConfig.withOriginalFile(original);
+
+ if (imageConfig.original != null) {
+ cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
+ }else {
+ responseHelper.invokeError(callback, "Couldn't get file path for photo");
+ return;
+ }
+ if (cameraCaptureURI == null)
+ {
+ responseHelper.invokeError(callback, "Couldn't get file path for photo");
+ return;
+ }
+ cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraCaptureURI);
+ }
}