From 9c84bdb10598dadd6afe30396a7c8f0bee7f418a Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 29 Jan 2018 16:35:31 -0500 Subject: [PATCH 1/2] Add support for images as documents. --- .../ConversationViewController.m | 45 ++++++++++++++++--- .../attachments/SignalAttachment.swift | 6 +++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index bec4f2a96..d4c42f2a5 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -233,6 +233,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { @property (nonatomic) BOOL shouldObserveDBModifications; @property (nonatomic) BOOL viewHasEverAppeared; @property (nonatomic) BOOL hasUnreadMessages; +@property (nonatomic) BOOL isPickingMediaAsDocument; @end @@ -2300,10 +2301,22 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { // UIDocumentPickerModeImport copies to a temp file within our container. // It uses more memory than "open" but lets us avoid working with security scoped URLs. UIDocumentPickerMode pickerMode = UIDocumentPickerModeImport; + // TODO: UIDocumentMenuViewController is deprecated; we should use UIDocumentPickerViewController + // instead. UIDocumentMenuViewController *menuController = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:documentTypes inMode:pickerMode]; menuController.delegate = self; + UIImage *takeMediaImage = [UIImage imageNamed:@"actionsheet_camera_black"]; + OWSAssert(takeMediaImage); + [menuController addOptionWithTitle:NSLocalizedString( + @"MEDIA_FROM_LIBRARY_BUTTON", @"media picker option to choose from library") + image:takeMediaImage + order:UIDocumentMenuOrderFirst + handler:^{ + [self chooseFromLibraryAsDocument]; + }]; + [self dismissKeyBoard]; [self presentViewController:menuController animated:YES completion:nil]; } @@ -2472,10 +2485,26 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { }]; } -- (void)chooseFromLibrary +- (void)chooseFromLibraryAsDocument +{ + OWSAssertIsOnMainThread(); + + [self chooseFromLibrary:YES]; +} + +- (void)chooseFromLibraryAsMedia +{ + OWSAssertIsOnMainThread(); + + [self chooseFromLibrary:NO]; +} + +- (void)chooseFromLibrary:(BOOL)shouldTreatAsDocument { OWSAssertIsOnMainThread(); + self.isPickingMediaAsDocument = shouldTreatAsDocument; + [self ows_askForMediaLibraryPermissions:^(BOOL granted) { if (!granted) { DDLogWarn(@"%@ Media Library permission denied.", self.logTag); @@ -2601,6 +2630,10 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { return failedToPickAttachment(nil); } + // Images chosen from the "attach document" UI should be sent as originals; + // images chosen from the "attach media" UI should be resized to "medium" size; + TSImageQuality imageQuality = (self.isPickingMediaAsDocument ? TSImageQualityOriginal : TSImageQualityMedium); + PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.synchronous = YES; // We're only fetching one asset. options.networkAccessAllowed = YES; // iCloud OK @@ -2622,11 +2655,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { DataSource *_Nullable dataSource = [DataSourceValue dataSourceWithData:imageData utiType:dataUTI]; [dataSource setSourceFilename:filename]; - // "Camera Roll" attachments _SHOULD_ be resized, if possible. - SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource - dataUTI:dataUTI - imageQuality:TSImageQualityMedium]; + SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource + dataUTI:dataUTI + imageQuality:imageQuality]; [self dismissViewControllerAnimated:YES completion:^{ OWSAssertIsOnMainThread(); @@ -3307,7 +3338,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { actionWithTitle:NSLocalizedString(@"MEDIA_FROM_LIBRARY_BUTTON", @"media picker option to choose from library") style:UIAlertActionStyleDefault handler:^(UIAlertAction *_Nonnull action) { - [self chooseFromLibrary]; + [self chooseFromLibraryAsMedia]; }]; UIImage *chooseMediaImage = [UIImage imageNamed:@"actionsheet_camera_roll_black"]; OWSAssert(chooseMediaImage); diff --git a/SignalMessaging/attachments/SignalAttachment.swift b/SignalMessaging/attachments/SignalAttachment.swift index fdf31398f..b956049ec 100644 --- a/SignalMessaging/attachments/SignalAttachment.swift +++ b/SignalMessaging/attachments/SignalAttachment.swift @@ -682,6 +682,12 @@ public class SignalAttachment: NSObject { private class func compressImageAsJPEG(image: UIImage, attachment: SignalAttachment, filename: String?, imageQuality: TSImageQuality) -> SignalAttachment { assert(attachment.error == nil) + if imageQuality == .original && + attachment.dataLength < kMaxFileSizeGeneric { + // We should avoid resizing images attached "as documents" if possible. + return attachment + } + var imageUploadQuality = imageQuality.imageQualityTier() while true { From fa76e524c4bf41d9c9f7e80e8d033669cf50d22e Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 30 Jan 2018 10:15:15 -0500 Subject: [PATCH 2/2] Respond to CR. --- .../ConversationView/ConversationViewController.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index d4c42f2a5..ea2b27d4e 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -2489,17 +2489,17 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { { OWSAssertIsOnMainThread(); - [self chooseFromLibrary:YES]; + [self chooseFromLibraryAsDocument:YES]; } - (void)chooseFromLibraryAsMedia { OWSAssertIsOnMainThread(); - [self chooseFromLibrary:NO]; + [self chooseFromLibraryAsDocument:NO]; } -- (void)chooseFromLibrary:(BOOL)shouldTreatAsDocument +- (void)chooseFromLibraryAsDocument:(BOOL)shouldTreatAsDocument { OWSAssertIsOnMainThread();