Ability to upload other file types (#1662)
This commit is contained in:
parent
76e664cdae
commit
23ca490525
15 changed files with 285 additions and 2 deletions
4
Makefile
4
Makefile
|
|
@ -67,7 +67,9 @@ post-install:
|
|||
@# Must remove the .babelrc for 0.42.0 to work correctly
|
||||
@# Need to copy custom ImagePickerModule.java that implements correct permission checks for android
|
||||
@rm node_modules/react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java
|
||||
@cp ./ImagePickerModule.java node_modules/react-native-image-picker/android/src/main/java/com/imagepicker
|
||||
@cp ./native_modules/ImagePickerModule.java node_modules/react-native-image-picker/android/src/main/java/com/imagepicker
|
||||
@# Need to copy custom RNDocumentPicker.m that implements direct access to the document picker in iOS
|
||||
@cp ./native_modules/RNDocumentPicker.m node_modules/react-native-document-picker/ios/RNDocumentPicker/RNDocumentPicker.m
|
||||
@rm -f node_modules/intl/.babelrc
|
||||
@# Hack to get react-intl and its dependencies to work with react-native
|
||||
@# Based off of https://github.com/este/este/blob/master/gulp/native-fix.js
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-document-picker')
|
||||
compile project(':react-native-doc-viewer')
|
||||
compile project(':react-native-video')
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.content.Context;
|
|||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.reactnativedocumentpicker.ReactNativeDocumentPicker;
|
||||
import com.reactlibrary.RNReactNativeDocViewerPackage;
|
||||
import com.brentvatne.react.ReactVideoPackage;
|
||||
import com.horcrux.svg.SvgPackage;
|
||||
|
|
@ -72,6 +73,7 @@ public class MainApplication extends NavigationApplication implements INotificat
|
|||
new ReactNativeYouTube(),
|
||||
new ReactVideoPackage(),
|
||||
new RNReactNativeDocViewerPackage(),
|
||||
new ReactNativeDocumentPicker(),
|
||||
new SharePackage()
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ public class RealPathUtil {
|
|||
|
||||
return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
}
|
||||
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
}
|
||||
|
||||
if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
// MediaStore (and general)
|
||||
|
||||
if (isGooglePhotosUri(uri)) {
|
||||
|
|
|
|||
|
|
@ -89,6 +89,23 @@ public class ShareModule extends ReactContextBaseJavaModule {
|
|||
promise.resolve(processIntent());
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getFilePath(String filePath, Promise promise) {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
WritableMap map = Arguments.createMap();
|
||||
|
||||
if (currentActivity != null) {
|
||||
Uri uri = Uri.parse(filePath);
|
||||
String path = RealPathUtil.getRealPathFromURI(currentActivity, uri);
|
||||
if (path != null) {
|
||||
String text = "file://" + path;
|
||||
map.putString("filePath", text);
|
||||
}
|
||||
}
|
||||
|
||||
promise.resolve(map);
|
||||
}
|
||||
|
||||
public WritableArray processIntent() {
|
||||
WritableMap map = Arguments.createMap();
|
||||
WritableArray items = Arguments.createArray();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
rootProject.name = 'Mattermost'
|
||||
include ':react-native-document-picker'
|
||||
project(':react-native-document-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-document-picker/android')
|
||||
include ':react-native-doc-viewer'
|
||||
project(':react-native-doc-viewer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-doc-viewer/android')
|
||||
include ':react-native-video'
|
||||
|
|
|
|||
|
|
@ -3,17 +3,21 @@ import PropTypes from 'prop-types';
|
|||
import {intlShape} from 'react-intl';
|
||||
import {
|
||||
Alert,
|
||||
NativeModules,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/Ionicons';
|
||||
import {DocumentPicker} from 'react-native-document-picker';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import Permissions from 'react-native-permissions';
|
||||
|
||||
import {PermissionTypes} from 'app/constants';
|
||||
import {changeOpacity} from 'app/utils/theme';
|
||||
|
||||
const ShareExtension = NativeModules.MattermostShare;
|
||||
|
||||
export default class AttachmentButton extends PureComponent {
|
||||
static propTypes = {
|
||||
blurTextBox: PropTypes.func.isRequired,
|
||||
|
|
@ -141,6 +145,32 @@ export default class AttachmentButton extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
attachFileFromFiles = async () => {
|
||||
const hasPermission = await this.hasStoragePermission();
|
||||
|
||||
if (hasPermission) {
|
||||
DocumentPicker.show({
|
||||
filetype: [Platform.OS === 'ios' ? 'public.item' : '*/*'],
|
||||
}, async (error, res) => {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
// For android we need to retrieve the realPath in case the file being imported is from the cloud
|
||||
const newUri = await ShareExtension.getFilePath(res.uri);
|
||||
if (newUri.filePath) {
|
||||
res.uri = newUri.filePath;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.uploadFiles([res]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
hasPhotoPermission = async () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
const {formatMessage} = this.context.intl;
|
||||
|
|
@ -194,6 +224,59 @@ export default class AttachmentButton extends PureComponent {
|
|||
return true;
|
||||
};
|
||||
|
||||
hasStoragePermission = async () => {
|
||||
if (Platform.OS === 'android') {
|
||||
const {formatMessage} = this.context.intl;
|
||||
let permissionRequest;
|
||||
const hasPermissionToStorage = await Permissions.check('storage');
|
||||
|
||||
switch (hasPermissionToStorage) {
|
||||
case PermissionTypes.UNDETERMINED:
|
||||
permissionRequest = await Permissions.request('storage');
|
||||
if (permissionRequest !== PermissionTypes.AUTHORIZED) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PermissionTypes.DENIED: {
|
||||
const canOpenSettings = await Permissions.canOpenSettings();
|
||||
let grantOption = null;
|
||||
if (canOpenSettings) {
|
||||
grantOption = {
|
||||
text: formatMessage({
|
||||
id: 'mobile.android.permission_denied_retry',
|
||||
defaultMessage: 'Set permission',
|
||||
}),
|
||||
onPress: () => Permissions.openSettings(),
|
||||
};
|
||||
}
|
||||
|
||||
Alert.alert(
|
||||
formatMessage({
|
||||
id: 'mobile.android.storage_permission_denied_title',
|
||||
defaultMessage: 'File Storage access is required',
|
||||
}),
|
||||
formatMessage({
|
||||
id: 'mobile.android.storage_permission_denied_description',
|
||||
defaultMessage: 'To upload images from your Android device, please change your permission settings.',
|
||||
}),
|
||||
[
|
||||
grantOption,
|
||||
{
|
||||
text: formatMessage({
|
||||
id: 'mobile.android.permission_denied_dismiss',
|
||||
defaultMessage: 'Dismiss',
|
||||
}),
|
||||
},
|
||||
]
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
uploadFiles = (images) => {
|
||||
this.props.uploadFiles(images);
|
||||
};
|
||||
|
|
@ -251,6 +334,15 @@ export default class AttachmentButton extends PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
options.items.push({
|
||||
action: () => this.handleFileAttachmentOption(this.attachFileFromFiles),
|
||||
text: {
|
||||
id: 'mobile.file_upload.browse',
|
||||
defaultMessage: 'Browse Files',
|
||||
},
|
||||
icon: 'file',
|
||||
});
|
||||
|
||||
this.props.navigator.showModal({
|
||||
screen: 'OptionsModal',
|
||||
title: '',
|
||||
|
|
|
|||
|
|
@ -2035,6 +2035,8 @@
|
|||
"mobile.android.permission_denied_retry": "Set permission",
|
||||
"mobile.android.photos_permission_denied_description": "To upload images from your library, please change your permission settings.",
|
||||
"mobile.android.photos_permission_denied_title": "Photo library access is required",
|
||||
"mobile.android.storage_permission_denied_title": "File Storage access is required",
|
||||
"mobile.android.storage_permission_denied_description": "To upload images from your Android device, please change your permission settings.",
|
||||
"mobile.android.videos_permission_denied_description": "To upload videos from your library, please change your permission settings.",
|
||||
"mobile.android.videos_permission_denied_title": "Video library access is required",
|
||||
"mobile.announcement_banner.dismiss": "Dismiss",
|
||||
|
|
@ -2135,6 +2137,7 @@
|
|||
"mobile.failed_network_action.description": "There seems to be a problem with your internet connection. Make sure you have an active connection and try again.",
|
||||
"mobile.failed_network_action.retry": "Try Again",
|
||||
"mobile.failed_network_action.title": "No internet connection",
|
||||
"mobile.file_upload.browse": "Browse Files",
|
||||
"mobile.file_upload.camera": "Take Photo or Video",
|
||||
"mobile.file_upload.library": "Photo Library",
|
||||
"mobile.file_upload.max_warning": "Uploads limited to 5 files maximum.",
|
||||
|
|
|
|||
|
|
@ -94,6 +94,13 @@ platform :ios do
|
|||
)
|
||||
end
|
||||
|
||||
unless ENV['IOS_ICLOUD_CONTAINER'].nil? || ENV['IOS_ICLOUD_CONTAINER'].empty? || ENV['IOS_ICLOUD_CONTAINER'] == 'iCloud.com.mattermost.rnbeta'
|
||||
update_icloud_container_identifiers(
|
||||
entitlements_file: './ios/Mattermost/Mattermost.entitlements',
|
||||
icloud_container_identifiers: [ENV['IOS_ICLOUD_CONTAINER']]
|
||||
)
|
||||
end
|
||||
|
||||
if ENV['IOS_APP_NAME'] != 'Mattermost Beta'
|
||||
update_info_plist(
|
||||
xcodeproj: './ios/Mattermost.xcodeproj',
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
7F50C96B203C6E80007CA374 /* SessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F50C969203C6E80007CA374 /* SessionManager.m */; };
|
||||
7F642DF02093533300F3165E /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F642DED2093530B00F3165E /* libRNDeviceInfo.a */; };
|
||||
7F642DF1209353A400F3165E /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F642DED2093530B00F3165E /* libRNDeviceInfo.a */; };
|
||||
7F5CA9A0208FE3B9004F91CE /* libRNDocumentPicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F5CA991208FE38F004F91CE /* libRNDocumentPicker.a */; };
|
||||
7F6877B31E7836070094B63F /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F6877B01E7835E50094B63F /* libToolTipMenu.a */; };
|
||||
7F6C47A51FE87E8C00F5A912 /* PerformRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6C47A41FE87E8C00F5A912 /* PerformRequests.m */; };
|
||||
7F7D7F98201645E100D31155 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F7D7F87201645D300D31155 /* libReactNativePermissions.a */; };
|
||||
|
|
@ -422,6 +423,13 @@
|
|||
remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
|
||||
remoteInfo = "fishhook-tvOS";
|
||||
};
|
||||
7F5CA990208FE38F004F91CE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7F5CA956208FE38F004F91CE /* RNDocumentPicker.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = E01DD9DB1D2311A600C39062;
|
||||
remoteInfo = RNDocumentPicker;
|
||||
};
|
||||
7F63D2801E6C957C001FAE12 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 7F63D27B1E6C957C001FAE12 /* RCTPushNotification.xcodeproj */;
|
||||
|
|
@ -697,6 +705,7 @@
|
|||
7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-Mattermost.a"; path = "../../../../../../../Library/Developer/Xcode/DerivedData/Mattermost-czlinsdviifujheezzjvmisotjrm/Build/Products/Debug-iphonesimulator/libPods-Mattermost.a"; sourceTree = "<group>"; };
|
||||
7F50C968203C6E80007CA374 /* SessionManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SessionManager.h; sourceTree = "<group>"; };
|
||||
7F50C969203C6E80007CA374 /* SessionManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SessionManager.m; sourceTree = "<group>"; };
|
||||
7F5CA956208FE38F004F91CE /* RNDocumentPicker.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNDocumentPicker.xcodeproj; path = "../node_modules/react-native-document-picker/ios/RNDocumentPicker.xcodeproj"; sourceTree = "<group>"; };
|
||||
7F63D27B1E6C957C001FAE12 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = "<group>"; };
|
||||
7F63D2C21E6DD98A001FAE12 /* Mattermost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Mattermost.entitlements; path = Mattermost/Mattermost.entitlements; sourceTree = "<group>"; };
|
||||
7F642DE72093530B00F3165E /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNDeviceInfo.xcodeproj; path = "../node_modules/react-native-device-info/ios/RNDeviceInfo.xcodeproj"; sourceTree = "<group>"; };
|
||||
|
|
@ -802,6 +811,7 @@
|
|||
7F43D5DD1F6BF95F001FC614 /* libRNCookieManagerIOS.a in Frameworks */,
|
||||
7F43D6401F6BFA82001FC614 /* libRCTPushNotification.a in Frameworks */,
|
||||
7FDB92B11F706F58006CDFD1 /* libRNImagePicker.a in Frameworks */,
|
||||
7F5CA9A0208FE3B9004F91CE /* libRNDocumentPicker.a in Frameworks */,
|
||||
7F43D5DE1F6BF96A001FC614 /* libRCTYouTube.a in Frameworks */,
|
||||
7F43D6061F6BF9EB001FC614 /* libPods-Mattermost.a in Frameworks */,
|
||||
A9B746D2CFA9CEBFB8AE2B5B /* libPods-Mattermost.a in Frameworks */,
|
||||
|
|
@ -1131,6 +1141,14 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7F5CA957208FE38F004F91CE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F5CA991208FE38F004F91CE /* libRNDocumentPicker.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7F63D27C1E6C957C001FAE12 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -1299,6 +1317,7 @@
|
|||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F5CA956208FE38F004F91CE /* RNDocumentPicker.xcodeproj */,
|
||||
7F642DE72093530B00F3165E /* RNDeviceInfo.xcodeproj */,
|
||||
7FD8DE972029ECDE001AAC5E /* RNTableView.xcodeproj */,
|
||||
7F7D7F52201645D300D31155 /* ReactNativePermissions.xcodeproj */,
|
||||
|
|
@ -1470,6 +1489,9 @@
|
|||
com.apple.Push = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.iCloud = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
7FFE32991FD9CB640038C7A0 = {
|
||||
|
|
@ -1597,6 +1619,10 @@
|
|||
ProductGroup = 7F642DE82093530B00F3165E /* Products */;
|
||||
ProjectRef = 7F642DE72093530B00F3165E /* RNDeviceInfo.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 7F5CA957208FE38F004F91CE /* Products */;
|
||||
ProjectRef = 7F5CA956208FE38F004F91CE /* RNDocumentPicker.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 3752181C1F4B9E320035444B /* Products */;
|
||||
ProjectRef = 546CB0A5BB8F453890CBA559 /* RNFetchBlob.xcodeproj */;
|
||||
|
|
@ -1957,6 +1983,13 @@
|
|||
remoteRef = 7F4C1F851FBE572B0029D1DF /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7F5CA991208FE38F004F91CE /* libRNDocumentPicker.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNDocumentPicker.a;
|
||||
remoteRef = 7F5CA990208FE38F004F91CE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
7F63D2811E6C957C001FAE12 /* libRCTPushNotification.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
|
@ -2491,6 +2524,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-doc-viewer/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea",
|
||||
"$(SRCROOT)/../node_modules/react-native-document-picker/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-device-info/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = Mattermost/Info.plist;
|
||||
|
|
@ -2541,6 +2575,7 @@
|
|||
"$(SRCROOT)/../node_modules/react-native-video/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-doc-viewer/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea",
|
||||
"$(SRCROOT)/../node_modules/react-native-document-picker/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-device-info/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = Mattermost/Info.plist;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,20 @@
|
|||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
</array>
|
||||
<key>com.apple.developer.icloud-services</key>
|
||||
<array>
|
||||
<string>CloudDocuments</string>
|
||||
</array>
|
||||
<key>com.apple.developer.ubiquity-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
</array>
|
||||
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
|
||||
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.mattermost.rnbeta</string>
|
||||
|
|
|
|||
100
native_modules/RNDocumentPicker.m
Normal file
100
native_modules/RNDocumentPicker.m
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#import "RNDocumentPicker.h"
|
||||
|
||||
#if __has_include(<React/RCTConvert.h>)
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTBridge.h>
|
||||
#else // back compatibility for RN version < 0.40
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTBridge.h"
|
||||
#endif
|
||||
|
||||
#define IDIOM UI_USER_INTERFACE_IDIOM()
|
||||
#define IPAD UIUserInterfaceIdiomPad
|
||||
|
||||
@interface RNDocumentPicker () <UIDocumentPickerDelegate>
|
||||
@end
|
||||
|
||||
|
||||
@implementation RNDocumentPicker {
|
||||
NSMutableArray *composeViews;
|
||||
NSMutableArray *composeCallbacks;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
composeCallbacks = [[NSMutableArray alloc] init];
|
||||
composeViews = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
return dispatch_get_main_queue();
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
RCT_EXPORT_METHOD(show:(NSDictionary *)options
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
|
||||
NSArray *allowedUTIs = [RCTConvert NSArray:options[@"filetype"]];
|
||||
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:(NSArray *)allowedUTIs inMode:UIDocumentPickerModeImport];
|
||||
|
||||
[composeCallbacks addObject:callback];
|
||||
|
||||
|
||||
documentPicker.delegate = self;
|
||||
documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
|
||||
|
||||
UIViewController *rootViewController = [[[[UIApplication sharedApplication]delegate] window] rootViewController];
|
||||
while (rootViewController.modalViewController) {
|
||||
rootViewController = rootViewController.modalViewController;
|
||||
}
|
||||
|
||||
if ( IDIOM == IPAD ) {
|
||||
NSNumber *top = [RCTConvert NSNumber:options[@"top"]];
|
||||
NSNumber *left = [RCTConvert NSNumber:options[@"left"]];
|
||||
[documentPicker.popoverPresentationController setSourceRect: CGRectMake([left floatValue], [top floatValue], 0, 0)];
|
||||
[documentPicker.popoverPresentationController setSourceView: rootViewController.view];
|
||||
}
|
||||
|
||||
[rootViewController presentViewController:documentPicker animated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
|
||||
if (controller.documentPickerMode == UIDocumentPickerModeImport) {
|
||||
RCTResponseSenderBlock callback = [composeCallbacks lastObject];
|
||||
[composeCallbacks removeLastObject];
|
||||
|
||||
[url startAccessingSecurityScopedResource];
|
||||
|
||||
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] init];
|
||||
__block NSError *error;
|
||||
|
||||
[coordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingResolvesSymbolicLink error:&error byAccessor:^(NSURL *newURL) {
|
||||
NSMutableDictionary* result = [NSMutableDictionary dictionary];
|
||||
|
||||
[result setValue:newURL.absoluteString forKey:@"uri"];
|
||||
[result setValue:[newURL lastPathComponent] forKey:@"fileName"];
|
||||
|
||||
NSError *attributesError = nil;
|
||||
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:newURL.path error:&attributesError];
|
||||
if(!attributesError) {
|
||||
[result setValue:[fileAttributes objectForKey:NSFileSize] forKey:@"fileSize"];
|
||||
} else {
|
||||
NSLog(@"%@", attributesError);
|
||||
}
|
||||
|
||||
callback(@[[NSNull null], result]);
|
||||
}];
|
||||
|
||||
[url stopAccessingSecurityScopedResource];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
|
|
@ -14426,6 +14426,11 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-doc-viewer/-/react-native-doc-viewer-2.7.8.tgz",
|
||||
"integrity": "sha1-Q9BlMo+xt+yQ0yHlvSNHEegHyPY="
|
||||
},
|
||||
"react-native-document-picker": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-2.1.0.tgz",
|
||||
"integrity": "sha512-BFCBXwz8xuLvHLVFVeQM+RhaY8yZ38PEWt9WSbq5VIoZ/VssP6uu51XxOfdwaMALOrAHIojK0SiYnd155upZAg=="
|
||||
},
|
||||
"react-native-drawer": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-drawer/-/react-native-drawer-2.5.0.tgz",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
"react-native-cookies": "3.2.0",
|
||||
"react-native-device-info": "0.21.5",
|
||||
"react-native-doc-viewer": "2.7.8",
|
||||
"react-native-document-picker": "2.1.0",
|
||||
"react-native-drawer": "2.5.0",
|
||||
"react-native-exception-handler": "2.7.5",
|
||||
"react-native-fast-image": "4.0.8",
|
||||
|
|
|
|||
Loading…
Reference in a new issue