mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
OPS: Use new Image Picker
This commit is contained in:
parent
fcd61c35b2
commit
5b30f2f3ea
@ -33,7 +33,7 @@ import * as NavigationService from './NavigationService';
|
||||
import WalletGradient from './class/wallet-gradient';
|
||||
import ToolTip from 'react-native-tooltip';
|
||||
import { BlurView } from '@react-native-community/blur';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
|
||||
import showPopupMenu from 'react-native-popup-menu-android';
|
||||
import NetworkTransactionFees, { NetworkTransactionFee, NetworkTransactionFeeType } from './models/networkTransactionFees';
|
||||
import Biometric from './class/biometrics';
|
||||
@ -1616,7 +1616,7 @@ export class BlueAddressInput extends Component {
|
||||
};
|
||||
|
||||
choosePhoto = () => {
|
||||
ImagePicker.launchImageLibrary(
|
||||
launchImageLibrary(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
@ -1638,7 +1638,7 @@ export class BlueAddressInput extends Component {
|
||||
};
|
||||
|
||||
takePhoto = () => {
|
||||
ImagePicker.launchCamera(
|
||||
launchCamera(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -265,8 +265,8 @@ PODS:
|
||||
- React
|
||||
- react-native-geolocation (2.0.2):
|
||||
- React
|
||||
- react-native-image-picker (2.3.4):
|
||||
- React-Core
|
||||
- react-native-image-picker (3.0.1):
|
||||
- React
|
||||
- react-native-is-catalyst (1.0.0):
|
||||
- React
|
||||
- react-native-randombytes (3.5.3):
|
||||
@ -278,7 +278,7 @@ PODS:
|
||||
- react-native-tcp-socket (3.7.1):
|
||||
- CocoaAsyncSocket
|
||||
- React
|
||||
- react-native-webview (10.10.0):
|
||||
- react-native-webview (11.0.0):
|
||||
- React-Core
|
||||
- react-native-widget-center (0.0.4):
|
||||
- React
|
||||
@ -359,7 +359,7 @@ PODS:
|
||||
- React-Core
|
||||
- RNDefaultPreference (1.4.3):
|
||||
- React
|
||||
- RNDeviceInfo (6.2.0):
|
||||
- RNDeviceInfo (7.0.2):
|
||||
- React-Core
|
||||
- RNFS (2.16.6):
|
||||
- React
|
||||
@ -703,13 +703,13 @@ SPEC CHECKSUMS:
|
||||
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
|
||||
react-native-fingerprint-scanner: c68136ca57e3704d7bdf5faa554ea535ce15b1d0
|
||||
react-native-geolocation: cbd9d6bd06bac411eed2671810f454d4908484a8
|
||||
react-native-image-picker: 32d1ad2c0024ca36161ae0d5c2117e2d6c441f11
|
||||
react-native-image-picker: 4efc5b7f3a780975bcc677335eb670e52d203424
|
||||
react-native-is-catalyst: 52ee70e0123c82419dd4ce47dc4cc94b22467512
|
||||
react-native-randombytes: 991545e6eaaf700b4ee384c291ef3d572e0b2ca8
|
||||
react-native-safe-area-context: 01158a92c300895d79dee447e980672dc3fb85a6
|
||||
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
|
||||
react-native-tcp-socket: 96a4f104cdcc9c6621aafe92937f163d88447c5b
|
||||
react-native-webview: 2e330b109bfd610e9818bf7865d1979f898960a7
|
||||
react-native-webview: f0da708d7e471b60ebdbf861c114d2c5d7f7af2d
|
||||
react-native-widget-center: 0f81d17beb163e7fb5848b06754d7d277fe7d99a
|
||||
React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa
|
||||
React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2
|
||||
@ -729,7 +729,7 @@ SPEC CHECKSUMS:
|
||||
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
|
||||
RNCPushNotificationIOS: eaf01f848a0b872b194d31bcad94bb864299e01e
|
||||
RNDefaultPreference: 21816c0a6f61a2829ccc0cef034392e9b509ee5f
|
||||
RNDeviceInfo: 980848feea8d74412b16f2e3e8758c8294d63ca2
|
||||
RNDeviceInfo: a37a15a98822c31c3982cb28eba6d336ba4d0968
|
||||
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
||||
RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39
|
||||
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -18996,9 +18996,9 @@
|
||||
"integrity": "sha512-KTIy7lExwMtB6pOpCARyUzFj5EzYTh+A1GN/FB5Eb0LrW5C6hbb1kdj9K2/RHyZC+wyAJD1M823ZaDCU6n6cLA=="
|
||||
},
|
||||
"react-native-image-picker": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-2.3.4.tgz",
|
||||
"integrity": "sha512-4UHu+zOyDT570r5mIbjH6h1iMrKIq/qfsKiAVUEZwncVegh0usJiEYNyJw4CEVwNeehmye/ia5sLDsa+kzIE4g=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-3.0.1.tgz",
|
||||
"integrity": "sha512-jVWiKT24jxr7K8dAixlsfHURZd+eDA4WWYeZhhKeJDGITCtFPphcTuFomTMtaWYE/gJgNTEL8TiLedcfeqJ9qw=="
|
||||
},
|
||||
"react-native-inappbrowser-reborn": {
|
||||
"version": "git+https://github.com/BlueWallet/react-native-inappbrowser.git#fa2d8e1763e46dd12a7e53081e97a0f908049103",
|
||||
|
@ -129,7 +129,7 @@
|
||||
"react-native-gesture-handler": "1.8.0",
|
||||
"react-native-handoff": "git+https://github.com/marcosrdz/react-native-handoff.git",
|
||||
"react-native-haptic-feedback": "1.11.0",
|
||||
"react-native-image-picker": "2.3.4",
|
||||
"react-native-image-picker": "3.0.1",
|
||||
"react-native-inappbrowser-reborn": "git+https://github.com/BlueWallet/react-native-inappbrowser.git#fa2d8e1763e46dd12a7e53081e97a0f908049103",
|
||||
"react-native-is-catalyst": "git+https://github.com/BlueWallet/react-native-is-catalyst.git#v1.0.0",
|
||||
"react-native-level-fs": "3.0.1",
|
||||
|
@ -3,7 +3,7 @@ import React, { useState } from 'react';
|
||||
import { Image, View, TouchableOpacity, StatusBar, Platform, StyleSheet, TextInput } from 'react-native';
|
||||
import { RNCamera } from 'react-native-camera';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchImageLibrary } from 'react-native-image-picker';
|
||||
import { decodeUR, extractSingleWorkload } from 'bc-ur';
|
||||
import { useNavigation, useRoute, useIsFocused, useTheme } from '@react-navigation/native';
|
||||
import loc from '../../loc';
|
||||
@ -192,7 +192,7 @@ const ScanQRCode = () => {
|
||||
const showImagePicker = () => {
|
||||
if (!isLoading) {
|
||||
setIsLoading(true);
|
||||
ImagePicker.launchImageLibrary(
|
||||
launchImageLibrary(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -6,7 +6,7 @@ import { DynamicQRCode } from '../../components/DynamicQRCode';
|
||||
import { SquareButton } from '../../components/SquareButton';
|
||||
import { getSystemName } from 'react-native-device-info';
|
||||
import loc from '../../loc';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchCamera } from 'react-native-image-picker';
|
||||
import ScanQRCode from './ScanQRCode';
|
||||
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
@ -49,7 +49,7 @@ const PsbtMultisigQRCode = () => {
|
||||
|
||||
const openScanner = () => {
|
||||
if (isDesktop) {
|
||||
ImagePicker.launchCamera(
|
||||
launchCamera(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -17,7 +17,7 @@ import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
|
||||
import WalletImport from '../../class/wallet-import';
|
||||
import Clipboard from '@react-native-community/clipboard';
|
||||
import ActionSheet from '../ActionSheet';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
|
||||
import loc from '../../loc';
|
||||
import { getSystemName } from 'react-native-device-info';
|
||||
import RNFS from 'react-native-fs';
|
||||
@ -115,7 +115,7 @@ const WalletsImport = () => {
|
||||
};
|
||||
|
||||
const choosePhoto = () => {
|
||||
ImagePicker.launchImageLibrary(
|
||||
launchImageLibrary(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
@ -137,7 +137,7 @@ const WalletsImport = () => {
|
||||
};
|
||||
|
||||
const takePhoto = () => {
|
||||
ImagePicker.launchCamera(
|
||||
launchCamera(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -21,7 +21,7 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
import { PlaceholderWallet } from '../../class';
|
||||
import WalletImport from '../../class/wallet-import';
|
||||
import ActionSheet from '../ActionSheet';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchImageLibrary, launchCamera } from 'react-native-image-picker';
|
||||
import Clipboard from '@react-native-community/clipboard';
|
||||
import loc from '../../loc';
|
||||
import { FContainer, FButton } from '../../components/FloatButtons';
|
||||
@ -363,7 +363,7 @@ const WalletsList = () => {
|
||||
};
|
||||
|
||||
const choosePhoto = () => {
|
||||
ImagePicker.launchImageLibrary(
|
||||
launchImageLibrary(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
@ -385,7 +385,7 @@ const WalletsList = () => {
|
||||
};
|
||||
|
||||
const takePhoto = () => {
|
||||
ImagePicker.launchCamera(
|
||||
launchCamera(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchImageLibrary } from 'react-native-image-picker';
|
||||
import Clipboard from '@react-native-community/clipboard';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import Handoff from 'react-native-handoff';
|
||||
@ -451,7 +451,7 @@ const WalletTransactions = () => {
|
||||
};
|
||||
|
||||
const choosePhoto = () => {
|
||||
ImagePicker.launchImageLibrary(
|
||||
launchImageLibrary(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -18,7 +18,7 @@ import { Icon } from 'react-native-elements';
|
||||
import { useFocusEffect, useNavigation, useRoute, useTheme } from '@react-navigation/native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { getSystemName } from 'react-native-device-info';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import { launchCamera } from 'react-native-image-picker';
|
||||
|
||||
import {
|
||||
BlueButton,
|
||||
@ -382,7 +382,7 @@ const ViewEditMultisigCosigners = () => {
|
||||
const scanOrOpenFile = () => {
|
||||
setIsProvideMnemonicsModalVisible(false);
|
||||
if (isDesktop) {
|
||||
ImagePicker.launchCamera(
|
||||
launchCamera(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
|
@ -1,619 +0,0 @@
|
||||
--- ImagePickerManager.m 1985-10-26 04:15:00.000000000 -0400
|
||||
+++ ImagePickerManager.m 2020-11-15 21:01:40.000000000 -0500
|
||||
@@ -1,9 +1,11 @@
|
||||
#import "ImagePickerManager.h"
|
||||
#import <React/RCTConvert.h>
|
||||
-#import <AssetsLibrary/AssetsLibrary.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <Photos/Photos.h>
|
||||
#import <React/RCTUtils.h>
|
||||
+#if !TARGET_OS_MACCATALYST
|
||||
+#import <AssetsLibrary/AssetsLibrary.h>
|
||||
+#endif
|
||||
|
||||
@import MobileCoreServices;
|
||||
|
||||
@@ -42,25 +44,25 @@
|
||||
{
|
||||
self.callback = callback; // Save the callback so we can use it from the delegate methods
|
||||
self.options = options;
|
||||
-
|
||||
+
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
-
|
||||
+
|
||||
NSString *title = [self.options valueForKey:@"title"];
|
||||
if ([title isEqual:[NSNull null]] || title.length == 0) {
|
||||
title = nil; // A more visually appealing UIAlertControl is displayed with a nil title rather than title = @""
|
||||
}
|
||||
NSString *cancelTitle = [self.options valueForKey:@"cancelButtonTitle"];
|
||||
NSString *takePhotoButtonTitle = [self.options valueForKey:@"takePhotoButtonTitle"];
|
||||
- NSString *chooseFromLibraryButtonTitle = [self.options valueForKey:@"chooseFromLibraryButtonTitle"];
|
||||
-
|
||||
+ NSString *chooseFromLibraryButtonTitle = [self.options valueForKey:@"chooseFromLibraryButtonTitle"];
|
||||
+
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
alertController.view.tintColor = [RCTConvert UIColor:options[@"tintColor"]];
|
||||
-
|
||||
+
|
||||
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
self.callback(@[@{@"didCancel": @YES}]); // Return callback for 'cancel' action (if is required)
|
||||
}];
|
||||
[alertController addAction:cancelAction];
|
||||
-
|
||||
+
|
||||
if (![takePhotoButtonTitle isEqual:[NSNull null]] && takePhotoButtonTitle.length > 0) {
|
||||
UIAlertAction *takePhotoAction = [UIAlertAction actionWithTitle:takePhotoButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
[self actionHandler:action];
|
||||
@@ -73,7 +75,7 @@
|
||||
}];
|
||||
[alertController addAction:chooseFromLibraryAction];
|
||||
}
|
||||
-
|
||||
+
|
||||
// Add custom buttons to action sheet
|
||||
if ([self.options objectForKey:@"customButtons"] && [[self.options objectForKey:@"customButtons"] isKindOfClass:[NSArray class]]) {
|
||||
self.customButtons = [self.options objectForKey:@"customButtons"];
|
||||
@@ -85,16 +87,16 @@
|
||||
[alertController addAction:customAction];
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
UIViewController *root = RCTPresentedViewController();
|
||||
-
|
||||
+
|
||||
/* On iPad, UIAlertController presents a popover view rather than an action sheet like on iPhone. We must provide the location
|
||||
- of the location to show the popover in this case. For simplicity, we'll just display it on the bottom center of the screen
|
||||
- to mimic an action sheet */
|
||||
+ of the location to show the popover in this case. For simplicity, we'll just display it on the bottom center of the screen
|
||||
+ to mimic an action sheet */
|
||||
alertController.popoverPresentationController.sourceView = root.view;
|
||||
alertController.popoverPresentationController.sourceRect = CGRectMake(root.view.bounds.size.width / 2.0, root.view.bounds.size.height, 1.0, 1.0);
|
||||
-
|
||||
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
||||
+
|
||||
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
||||
alertController.popoverPresentationController.permittedArrowDirections = 0;
|
||||
for (id subview in alertController.view.subviews) {
|
||||
if ([subview isMemberOfClass:[UIView class]]) {
|
||||
@@ -102,7 +104,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
[root presentViewController:alertController animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
@@ -119,7 +121,7 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
if ([action.title isEqualToString:[self.options valueForKey:@"takePhotoButtonTitle"]]) { // Take photo
|
||||
[self launchImagePicker:RNImagePickerTargetCamera];
|
||||
}
|
||||
@@ -137,7 +139,7 @@
|
||||
- (void)launchImagePicker:(RNImagePickerTarget)target
|
||||
{
|
||||
self.picker = [[UIImagePickerController alloc] init];
|
||||
-
|
||||
+
|
||||
if (target == RNImagePickerTargetCamera) {
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
self.callback(@[@{@"error": @"Camera not available on simulator"}]);
|
||||
@@ -155,10 +157,10 @@
|
||||
else { // RNImagePickerTargetLibrarySingleImage
|
||||
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
||||
}
|
||||
-
|
||||
+
|
||||
if ([[self.options objectForKey:@"mediaType"] isEqualToString:@"video"]
|
||||
|| [[self.options objectForKey:@"mediaType"] isEqualToString:@"mixed"]) {
|
||||
-
|
||||
+
|
||||
if ([[self.options objectForKey:@"videoQuality"] isEqualToString:@"high"]) {
|
||||
self.picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
|
||||
}
|
||||
@@ -168,7 +170,7 @@
|
||||
else {
|
||||
self.picker.videoQuality = UIImagePickerControllerQualityTypeMedium;
|
||||
}
|
||||
-
|
||||
+
|
||||
id durationLimit = [self.options objectForKey:@"durationLimit"];
|
||||
if (durationLimit) {
|
||||
self.picker.videoMaximumDuration = [durationLimit doubleValue];
|
||||
@@ -182,13 +184,13 @@
|
||||
} else {
|
||||
self.picker.mediaTypes = @[(NSString *)kUTTypeImage];
|
||||
}
|
||||
-
|
||||
+
|
||||
if ([[self.options objectForKey:@"allowsEditing"] boolValue]) {
|
||||
self.picker.allowsEditing = true;
|
||||
}
|
||||
self.picker.modalPresentationStyle = UIModalPresentationCurrentContext;
|
||||
self.picker.delegate = self;
|
||||
-
|
||||
+
|
||||
// Check permissions
|
||||
void (^showPickerViewController)() = ^void() {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@@ -196,57 +198,57 @@
|
||||
[root presentViewController:self.picker animated:YES completion:nil];
|
||||
});
|
||||
};
|
||||
-
|
||||
+
|
||||
if (target == RNImagePickerTargetCamera) {
|
||||
[self checkCameraPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
self.callback(@[@{@"error": @"Camera permissions not granted"}]);
|
||||
return;
|
||||
}
|
||||
-
|
||||
+
|
||||
showPickerViewController();
|
||||
}];
|
||||
}
|
||||
else { // RNImagePickerTargetLibrarySingleImage
|
||||
- if (@available(iOS 11.0, *)) {
|
||||
- showPickerViewController();
|
||||
- } else {
|
||||
- [self checkPhotosPermissions:^(BOOL granted) {
|
||||
- if (!granted) {
|
||||
- self.callback(@[@{@"error": @"Photo library permissions not granted"}]);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- showPickerViewController();
|
||||
- }];
|
||||
- }
|
||||
+ if (@available(iOS 11.0, *)) {
|
||||
+ showPickerViewController();
|
||||
+ } else {
|
||||
+ [self checkPhotosPermissions:^(BOOL granted) {
|
||||
+ if (!granted) {
|
||||
+ self.callback(@[@{@"error": @"Photo library permissions not granted"}]);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ showPickerViewController();
|
||||
+ }];
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString * _Nullable)originalFilenameForAsset:(PHAsset * _Nullable)asset assetType:(PHAssetResourceType)type {
|
||||
if (!asset) { return nil; }
|
||||
-
|
||||
+
|
||||
PHAssetResource *originalResource;
|
||||
// Get the underlying resources for the PHAsset (PhotoKit)
|
||||
NSArray<PHAssetResource *> *pickedAssetResources = [PHAssetResource assetResourcesForAsset:asset];
|
||||
-
|
||||
+
|
||||
// Find the original resource (underlying image) for the asset, which has the desired filename
|
||||
for (PHAssetResource *resource in pickedAssetResources) {
|
||||
if (resource.type == type) {
|
||||
originalResource = resource;
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
return originalResource.originalFilename;
|
||||
}
|
||||
|
||||
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
|
||||
{
|
||||
dispatch_block_t dismissCompletionBlock = ^{
|
||||
-
|
||||
- NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
|
||||
+
|
||||
+ NSURL *imageURL = [info valueForKey:UIImagePickerControllerPHAsset];
|
||||
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
||||
-
|
||||
+
|
||||
NSString *fileName;
|
||||
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
|
||||
NSString *tempFileName = [[NSUUID UUID] UUIDString];
|
||||
@@ -264,18 +266,18 @@
|
||||
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
|
||||
fileName = videoURL.lastPathComponent;
|
||||
}
|
||||
-
|
||||
+
|
||||
// We default to path to the temporary directory
|
||||
NSString *path = [[NSTemporaryDirectory()stringByStandardizingPath] stringByAppendingPathComponent:fileName];
|
||||
-
|
||||
+
|
||||
// If storage options are provided, we use the documents directory which is persisted
|
||||
if ([self.options objectForKey:@"storageOptions"] && [[self.options objectForKey:@"storageOptions"] isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
|
||||
-
|
||||
+
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
path = [documentsDirectory stringByAppendingPathComponent:fileName];
|
||||
-
|
||||
+
|
||||
// Creates documents subdirectory, if provided
|
||||
if ([storageOptions objectForKey:@"path"]) {
|
||||
NSString *newPath = [documentsDirectory stringByAppendingPathComponent:[storageOptions objectForKey:@"path"]];
|
||||
@@ -291,10 +293,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
// Create the response object
|
||||
self.response = [[NSMutableDictionary alloc] init];
|
||||
-
|
||||
+
|
||||
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) { // PHOTOS
|
||||
UIImage *originalImage;
|
||||
if ([[self.options objectForKey:@"allowsEditing"] boolValue]) {
|
||||
@@ -303,13 +305,15 @@
|
||||
else {
|
||||
originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
}
|
||||
-
|
||||
+
|
||||
if (imageURL) {
|
||||
PHAsset *pickedAsset;
|
||||
if (@available(iOS 11.0, *)) {
|
||||
- pickedAsset = [info objectForKey: UIImagePickerControllerPHAsset];
|
||||
+ pickedAsset = [info objectForKey: UIImagePickerControllerPHAsset];
|
||||
} else {
|
||||
- pickedAsset = [PHAsset fetchAssetsWithALAssetURLs:@[imageURL] options:nil].lastObject;
|
||||
+#if !TARGET_OS_MACCATALYST
|
||||
+ pickedAsset = [PHAsset fetchAssetsWithALAssetURLs:@[imageURL] options:nil].lastObject;
|
||||
+#endif
|
||||
}
|
||||
|
||||
NSString *originalFilename = [self originalFilenameForAsset:pickedAsset assetType:PHAssetResourceTypePhoto];
|
||||
@@ -322,9 +326,10 @@
|
||||
self.response[@"timestamp"] = [[ImagePickerManager ISO8601DateFormatter] stringFromDate:pickedAsset.creationDate];
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
// GIFs break when resized, so we handle them differently
|
||||
if (imageURL && [[imageURL absoluteString] rangeOfString:@"ext=GIF"].location != NSNotFound) {
|
||||
+#if !TARGET_OS_MACCATALYST
|
||||
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
|
||||
[assetsLibrary assetForURL:imageURL resultBlock:^(ALAsset *asset) {
|
||||
ALAssetRepresentation *rep = [asset defaultRepresentation];
|
||||
@@ -333,38 +338,39 @@
|
||||
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:repSize error:nil];
|
||||
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
|
||||
[data writeToFile:path atomically:YES];
|
||||
-
|
||||
+
|
||||
NSMutableDictionary *gifResponse = [[NSMutableDictionary alloc] init];
|
||||
[gifResponse setObject:@(originalImage.size.width) forKey:@"width"];
|
||||
[gifResponse setObject:@(originalImage.size.height) forKey:@"height"];
|
||||
-
|
||||
+
|
||||
BOOL vertical = (originalImage.size.width < originalImage.size.height) ? YES : NO;
|
||||
[gifResponse setObject:@(vertical) forKey:@"isVertical"];
|
||||
-
|
||||
+
|
||||
if (![[self.options objectForKey:@"noData"] boolValue]) {
|
||||
NSString *dataString = [data base64EncodedStringWithOptions:0];
|
||||
[gifResponse setObject:dataString forKey:@"data"];
|
||||
}
|
||||
-
|
||||
+
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
||||
[gifResponse setObject:[fileURL absoluteString] forKey:@"uri"];
|
||||
-
|
||||
+
|
||||
NSNumber *fileSizeValue = nil;
|
||||
NSError *fileSizeError = nil;
|
||||
[fileURL getResourceValue:&fileSizeValue forKey:NSURLFileSizeKey error:&fileSizeError];
|
||||
if (fileSizeValue){
|
||||
[gifResponse setObject:fileSizeValue forKey:@"fileSize"];
|
||||
}
|
||||
-
|
||||
+
|
||||
self.callback(@[gifResponse]);
|
||||
} failureBlock:^(NSError *error) {
|
||||
self.callback(@[@{@"error": error.localizedFailureReason}]);
|
||||
}];
|
||||
+#endif
|
||||
return;
|
||||
}
|
||||
-
|
||||
+
|
||||
UIImage *editedImage = [self fixOrientation:originalImage]; // Rotate the image for upload to web
|
||||
-
|
||||
+
|
||||
// If needed, downscale image
|
||||
float maxWidth = editedImage.size.width;
|
||||
float maxHeight = editedImage.size.height;
|
||||
@@ -375,7 +381,7 @@
|
||||
maxHeight = [[self.options valueForKey:@"maxHeight"] floatValue];
|
||||
}
|
||||
editedImage = [self downscaleImageIfNecessary:editedImage maxWidth:maxWidth maxHeight:maxHeight];
|
||||
-
|
||||
+
|
||||
NSData *data;
|
||||
NSString *mimeType;
|
||||
if ([[self.options objectForKey:@"imageFileType"] isEqualToString:@"png"]) {
|
||||
@@ -388,36 +394,37 @@
|
||||
}
|
||||
[self.response setObject:mimeType forKey:@"type"];
|
||||
[data writeToFile:path atomically:YES];
|
||||
-
|
||||
+
|
||||
if (![[self.options objectForKey:@"noData"] boolValue]) {
|
||||
NSString *dataString = [data base64EncodedStringWithOptions:0]; // base64 encoded image string
|
||||
[self.response setObject:dataString forKey:@"data"];
|
||||
}
|
||||
-
|
||||
+
|
||||
BOOL vertical = (editedImage.size.width < editedImage.size.height) ? YES : NO;
|
||||
[self.response setObject:@(vertical) forKey:@"isVertical"];
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
||||
NSString *filePath = [fileURL absoluteString];
|
||||
[self.response setObject:filePath forKey:@"uri"];
|
||||
-
|
||||
+
|
||||
// add ref to the original image
|
||||
NSString *origURL = [imageURL absoluteString];
|
||||
if (origURL) {
|
||||
- [self.response setObject:origURL forKey:@"origURL"];
|
||||
+ [self.response setObject:origURL forKey:@"origURL"];
|
||||
}
|
||||
-
|
||||
+
|
||||
NSNumber *fileSizeValue = nil;
|
||||
NSError *fileSizeError = nil;
|
||||
[fileURL getResourceValue:&fileSizeValue forKey:NSURLFileSizeKey error:&fileSizeError];
|
||||
if (fileSizeValue){
|
||||
[self.response setObject:fileSizeValue forKey:@"fileSize"];
|
||||
}
|
||||
-
|
||||
+
|
||||
[self.response setObject:@(editedImage.size.width) forKey:@"width"];
|
||||
[self.response setObject:@(editedImage.size.height) forKey:@"height"];
|
||||
-
|
||||
+
|
||||
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
|
||||
if (storageOptions && [[storageOptions objectForKey:@"cameraRoll"] boolValue] == YES && self.picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
||||
+#if !TARGET_OS_MACCATALYST
|
||||
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
|
||||
if ([[storageOptions objectForKey:@"waitUntilSaved"] boolValue]) {
|
||||
[library writeImageToSavedPhotosAlbum:originalImage.CGImage metadata:[info valueForKey:UIImagePickerControllerMediaMetadata] completionBlock:^(NSURL *assetURL, NSError *error) {
|
||||
@@ -440,13 +447,15 @@
|
||||
} else {
|
||||
[library writeImageToSavedPhotosAlbum:originalImage.CGImage metadata:[info valueForKey:UIImagePickerControllerMediaMetadata] completionBlock:nil];
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
else { // VIDEO
|
||||
- NSURL *videoRefURL = info[UIImagePickerControllerReferenceURL];
|
||||
+ NSURL *videoRefURL = info[UIImagePickerControllerPHAsset];
|
||||
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
|
||||
NSURL *videoDestinationURL = [NSURL fileURLWithPath:path];
|
||||
-
|
||||
+
|
||||
+#if !TARGET_OS_MACCATALYST
|
||||
if (videoRefURL) {
|
||||
PHAsset *pickedAsset = [PHAsset fetchAssetsWithALAssetURLs:@[videoRefURL] options:nil].lastObject;
|
||||
NSString *originalFilename = [self originalFilenameForAsset:pickedAsset assetType:PHAssetResourceTypeVideo];
|
||||
@@ -459,39 +468,41 @@
|
||||
self.response[@"timestamp"] = [[ImagePickerManager ISO8601DateFormatter] stringFromDate:pickedAsset.creationDate];
|
||||
}
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
+
|
||||
if ([videoURL.URLByResolvingSymlinksInPath.path isEqualToString:videoDestinationURL.URLByResolvingSymlinksInPath.path] == NO) {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
-
|
||||
+
|
||||
// Delete file if it already exists
|
||||
if ([fileManager fileExistsAtPath:videoDestinationURL.path]) {
|
||||
[fileManager removeItemAtURL:videoDestinationURL error:nil];
|
||||
}
|
||||
-
|
||||
+
|
||||
if (videoURL) { // Protect against reported crash
|
||||
- NSError *error = nil;
|
||||
-
|
||||
- // If we have write access to the source file, move it. Otherwise use copy.
|
||||
- if ([fileManager isWritableFileAtPath:[videoURL path]]) {
|
||||
- [fileManager moveItemAtURL:videoURL toURL:videoDestinationURL error:&error];
|
||||
- } else {
|
||||
- [fileManager copyItemAtURL:videoURL toURL:videoDestinationURL error:&error];
|
||||
- }
|
||||
-
|
||||
- if (error) {
|
||||
- self.callback(@[@{@"error": error.localizedFailureReason}]);
|
||||
- return;
|
||||
- }
|
||||
+ NSError *error = nil;
|
||||
+
|
||||
+ // If we have write access to the source file, move it. Otherwise use copy.
|
||||
+ if ([fileManager isWritableFileAtPath:[videoURL path]]) {
|
||||
+ [fileManager moveItemAtURL:videoURL toURL:videoDestinationURL error:&error];
|
||||
+ } else {
|
||||
+ [fileManager copyItemAtURL:videoURL toURL:videoDestinationURL error:&error];
|
||||
+ }
|
||||
+
|
||||
+ if (error) {
|
||||
+ self.callback(@[@{@"error": error.localizedFailureReason}]);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
[self.response setObject:videoDestinationURL.absoluteString forKey:@"uri"];
|
||||
if (videoRefURL.absoluteString) {
|
||||
[self.response setObject:videoRefURL.absoluteString forKey:@"origURL"];
|
||||
}
|
||||
-
|
||||
+
|
||||
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
|
||||
if (storageOptions && [[storageOptions objectForKey:@"cameraRoll"] boolValue] == YES && self.picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
||||
+#if !TARGET_OS_MACCATALYST
|
||||
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
|
||||
[library writeVideoAtPathToSavedPhotosAlbum:videoDestinationURL completionBlock:^(NSURL *assetURL, NSError *error) {
|
||||
if (error) {
|
||||
@@ -509,22 +520,23 @@
|
||||
self.response[@"timestamp"] = [[ImagePickerManager ISO8601DateFormatter] stringFromDate:capturedAsset.creationDate];
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
self.callback(@[self.response]);
|
||||
}
|
||||
}
|
||||
}];
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
// If storage options are provided, check the skipBackup flag
|
||||
if ([self.options objectForKey:@"storageOptions"] && [[self.options objectForKey:@"storageOptions"] isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
|
||||
-
|
||||
+
|
||||
if ([[storageOptions objectForKey:@"skipBackup"] boolValue]) {
|
||||
[self addSkipBackupAttributeToItemAtPath:path]; // Don't back up the file to iCloud
|
||||
}
|
||||
-
|
||||
+
|
||||
if ([[storageOptions objectForKey:@"waitUntilSaved"] boolValue] == NO ||
|
||||
[[storageOptions objectForKey:@"cameraRoll"] boolValue] == NO ||
|
||||
self.picker.sourceType != UIImagePickerControllerSourceTypeCamera)
|
||||
@@ -536,7 +548,7 @@
|
||||
self.callback(@[self.response]);
|
||||
}
|
||||
};
|
||||
-
|
||||
+
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[picker dismissViewControllerAnimated:YES completion:dismissCompletionBlock];
|
||||
});
|
||||
@@ -595,12 +607,12 @@
|
||||
- (UIImage*)downscaleImageIfNecessary:(UIImage*)image maxWidth:(float)maxWidth maxHeight:(float)maxHeight
|
||||
{
|
||||
UIImage* newImage = image;
|
||||
-
|
||||
+
|
||||
// Nothing to do here
|
||||
if (image.size.width <= maxWidth && image.size.height <= maxHeight) {
|
||||
return newImage;
|
||||
}
|
||||
-
|
||||
+
|
||||
CGSize scaledSize = CGSizeMake(image.size.width, image.size.height);
|
||||
if (maxWidth < scaledSize.width) {
|
||||
scaledSize = CGSizeMake(maxWidth, (maxWidth / scaledSize.width) * scaledSize.height);
|
||||
@@ -608,11 +620,11 @@
|
||||
if (maxHeight < scaledSize.height) {
|
||||
scaledSize = CGSizeMake((maxHeight / scaledSize.height) * scaledSize.width, maxHeight);
|
||||
}
|
||||
-
|
||||
+
|
||||
// If the pixels are floats, it causes a white line in iOS8 and probably other versions too
|
||||
scaledSize.width = (int)scaledSize.width;
|
||||
scaledSize.height = (int)scaledSize.height;
|
||||
-
|
||||
+
|
||||
UIGraphicsBeginImageContext(scaledSize); // this will resize
|
||||
[image drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)];
|
||||
newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
@@ -620,7 +632,7 @@
|
||||
NSLog(@"could not scale image");
|
||||
}
|
||||
UIGraphicsEndImageContext();
|
||||
-
|
||||
+
|
||||
return newImage;
|
||||
}
|
||||
|
||||
@@ -628,7 +640,7 @@
|
||||
if (srcImg.imageOrientation == UIImageOrientationUp) {
|
||||
return srcImg;
|
||||
}
|
||||
-
|
||||
+
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
switch (srcImg.imageOrientation) {
|
||||
case UIImageOrientationDown:
|
||||
@@ -636,13 +648,13 @@
|
||||
transform = CGAffineTransformTranslate(transform, srcImg.size.width, srcImg.size.height);
|
||||
transform = CGAffineTransformRotate(transform, M_PI);
|
||||
break;
|
||||
-
|
||||
+
|
||||
case UIImageOrientationLeft:
|
||||
case UIImageOrientationLeftMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, srcImg.size.width, 0);
|
||||
transform = CGAffineTransformRotate(transform, M_PI_2);
|
||||
break;
|
||||
-
|
||||
+
|
||||
case UIImageOrientationRight:
|
||||
case UIImageOrientationRightMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, 0, srcImg.size.height);
|
||||
@@ -652,14 +664,14 @@
|
||||
case UIImageOrientationUpMirrored:
|
||||
break;
|
||||
}
|
||||
-
|
||||
+
|
||||
switch (srcImg.imageOrientation) {
|
||||
case UIImageOrientationUpMirrored:
|
||||
case UIImageOrientationDownMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, srcImg.size.width, 0);
|
||||
transform = CGAffineTransformScale(transform, -1, 1);
|
||||
break;
|
||||
-
|
||||
+
|
||||
case UIImageOrientationLeftMirrored:
|
||||
case UIImageOrientationRightMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, srcImg.size.height, 0);
|
||||
@@ -671,7 +683,7 @@
|
||||
case UIImageOrientationRight:
|
||||
break;
|
||||
}
|
||||
-
|
||||
+
|
||||
CGContextRef ctx = CGBitmapContextCreate(NULL, srcImg.size.width, srcImg.size.height, CGImageGetBitsPerComponent(srcImg.CGImage), 0, CGImageGetColorSpace(srcImg.CGImage), CGImageGetBitmapInfo(srcImg.CGImage));
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
switch (srcImg.imageOrientation) {
|
||||
@@ -681,12 +693,12 @@
|
||||
case UIImageOrientationRightMirrored:
|
||||
CGContextDrawImage(ctx, CGRectMake(0,0,srcImg.size.height,srcImg.size.width), srcImg.CGImage);
|
||||
break;
|
||||
-
|
||||
+
|
||||
default:
|
||||
CGContextDrawImage(ctx, CGRectMake(0,0,srcImg.size.width,srcImg.size.height), srcImg.CGImage);
|
||||
break;
|
||||
}
|
||||
-
|
||||
+
|
||||
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
|
||||
UIImage *img = [UIImage imageWithCGImage:cgimg];
|
||||
CGContextRelease(ctx);
|
||||
@@ -701,7 +713,7 @@
|
||||
NSError *error = nil;
|
||||
BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
|
||||
forKey: NSURLIsExcludedFromBackupKey error: &error];
|
||||
-
|
||||
+
|
||||
if(!success){
|
||||
NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
|
||||
}
|
@ -15,12 +15,8 @@ cd node_modules/react-native-camera/ios/RCT
|
||||
patch RCTCameraManager.m ../../../../scripts/maccatalystpatches/RCTCameraManager.patch --no-backup-if-mismatch
|
||||
cd ../RN/
|
||||
patch RNCamera.m ../../../../scripts/maccatalystpatches/RNCamera.patch
|
||||
echo "Applying patch for react-native-image-picker"
|
||||
cd ../../../../
|
||||
cd node_modules/react-native-image-picker/ios
|
||||
patch ImagePickerManager.m ../../../scripts/maccatalystpatches/ImagePickerManager.patch --no-backup-if-mismatch
|
||||
echo "Applying patch for Podfile"
|
||||
cd ../../../
|
||||
cd ../../../../
|
||||
patch ios/Podfile ./scripts/maccatalystpatches/podfile.patch --no-backup-if-mismatch
|
||||
echo "Applying patch for Realm podspec"
|
||||
patch node_modules/realm/RealmJS.podspec ./scripts/maccatalystpatches/realm.patch --no-backup-if-mismatch
|
||||
|
Loading…
Reference in New Issue
Block a user