mirror of
https://github.com/mattermost/mattermost-mobile.git
synced 2026-11-05 18:38:54 +00:00
127 lines
5.3 KiB
Diff
127 lines
5.3 KiB
Diff
diff --git a/node_modules/react-native-image-picker/ios/ImagePickerManager.mm b/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
|
|
index 93e99be..94082ec 100644
|
|
--- a/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
|
|
+++ b/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
|
|
@@ -68,7 +68,7 @@ RCT_EXPORT_METHOD(launchImageLibrary:(NSDictionary *)options callback:(RCTRespon
|
|
self.callback = callback;
|
|
|
|
if (target == camera && [ImagePickerUtils isSimulator]) {
|
|
- self.callback(@[@{@"errorCode": errCameraUnavailable}]);
|
|
+ [self invokeCallback:@[@{@"errorCode": errCameraUnavailable}]];
|
|
return;
|
|
}
|
|
|
|
@@ -87,7 +87,7 @@ RCT_EXPORT_METHOD(launchImageLibrary:(NSDictionary *)options callback:(RCTRespon
|
|
|
|
[self checkPhotosPermissions:^(BOOL granted) {
|
|
if (!granted) {
|
|
- self.callback(@[@{@"errorCode": errPermission}]);
|
|
+ [self invokeCallback:@[@{@"errorCode": errPermission}]];
|
|
return;
|
|
}
|
|
[self showPickerViewController:picker];
|
|
@@ -108,7 +108,7 @@ RCT_EXPORT_METHOD(launchImageLibrary:(NSDictionary *)options callback:(RCTRespon
|
|
if([self.options[@"includeExtra"] boolValue]) {
|
|
[self checkPhotosPermissions:^(BOOL granted) {
|
|
if (!granted) {
|
|
- self.callback(@[@{@"errorCode": errPermission}]);
|
|
+ [self invokeCallback:@[@{@"errorCode": errPermission}]];
|
|
return;
|
|
}
|
|
[self showPickerViewController:picker];
|
|
@@ -126,6 +126,22 @@ RCT_EXPORT_METHOD(launchImageLibrary:(NSDictionary *)options callback:(RCTRespon
|
|
});
|
|
}
|
|
|
|
+// The bridge callback aborts the app if invoked more than once. Delegate
|
|
+// callbacks can double-fire (e.g. presentationControllerDidDismiss followed by
|
|
+// picker:didFinishPicking:), so consume the callback exactly once, serialized
|
|
+// on the main queue.
|
|
+- (void)invokeCallback:(NSArray *)response
|
|
+{
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
+ RCTResponseSenderBlock callback = self.callback;
|
|
+ if (callback == nil) {
|
|
+ return;
|
|
+ }
|
|
+ self.callback = nil;
|
|
+ callback(response);
|
|
+ });
|
|
+}
|
|
+
|
|
#pragma mark - Helpers
|
|
|
|
NSData* extractImageData(UIImage* image){
|
|
@@ -465,7 +481,7 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
if (videoAsset == nil) {
|
|
NSString *errorMessage = error.localizedFailureReason;
|
|
if (errorMessage == nil) errorMessage = @"Video asset not found";
|
|
- self.callback(@[@{@"errorCode": errOthers, @"errorMessage": errorMessage}]);
|
|
+ [self invokeCallback:@[@{@"errorCode": errOthers, @"errorMessage": errorMessage}]];
|
|
return;
|
|
}
|
|
[assets addObject:videoAsset];
|
|
@@ -473,7 +489,7 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
|
|
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
|
|
response[@"assets"] = assets;
|
|
- self.callback(@[response]);
|
|
+ [self invokeCallback:@[response]];
|
|
};
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -485,7 +501,7 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
{
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[picker dismissViewControllerAnimated:YES completion:^{
|
|
- self.callback(@[@{@"didCancel": @YES}]);
|
|
+ [self invokeCallback:@[@{@"didCancel": @YES}]];
|
|
}];
|
|
});
|
|
}
|
|
@@ -496,7 +512,14 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
|
|
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
|
|
{
|
|
- self.callback(@[@{@"didCancel": @YES}]);
|
|
+ // A selection already being processed must win over the interactive
|
|
+ // dismissal, otherwise the picked assets would later hit a consumed
|
|
+ // callback (or be reported as a cancel).
|
|
+ if (photoSelected == YES) {
|
|
+ return;
|
|
+ }
|
|
+ photoSelected = YES;
|
|
+ [self invokeCallback:@[@{@"didCancel": @YES}]];
|
|
}
|
|
|
|
@end
|
|
@@ -514,9 +537,7 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
photoSelected = YES;
|
|
|
|
if (results.count == 0) {
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
|
- self.callback(@[@{@"didCancel": @YES}]);
|
|
- });
|
|
+ [self invokeCallback:@[@{@"didCancel": @YES}]];
|
|
return;
|
|
}
|
|
|
|
@@ -571,7 +592,7 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
// mapVideoToAsset can fail and return nil, leaving asset NSNull.
|
|
for (NSDictionary *asset in assets) {
|
|
if ([asset isEqual:[NSNull null]]) {
|
|
- self.callback(@[@{@"errorCode": errOthers}]);
|
|
+ [self invokeCallback:@[@{@"errorCode": errOthers}]];
|
|
return;
|
|
}
|
|
}
|
|
@@ -579,7 +600,7 @@ CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIIma
|
|
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
|
|
[response setObject:assets forKey:@"assets"];
|
|
|
|
- self.callback(@[response]);
|
|
+ [self invokeCallback:@[response]];
|
|
});
|
|
}
|
|
|