Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import <MobileCoreServices/MobileCoreServices.h> | 5 #import <MobileCoreServices/MobileCoreServices.h> |
| 6 | 6 |
| 7 #import "ios/chrome/share_extension/share_view_controller.h" | 7 #import "ios/chrome/share_extension/share_view_controller.h" |
| 8 | 8 |
| 9 #import "base/ios/block_types.h" | 9 #import "base/ios/block_types.h" |
| 10 #import "base/mac/foundation_util.h" | 10 #import "base/mac/foundation_util.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 | 33 |
| 34 } // namespace | 34 } // namespace |
| 35 | 35 |
| 36 @interface ShareViewController ()<ShareExtensionViewActionTarget> { | 36 @interface ShareViewController ()<ShareExtensionViewActionTarget> { |
| 37 // This constraint the center of the widget to be vertically in the center | 37 // This constraint the center of the widget to be vertically in the center |
| 38 // of the the screen. It has to be modified for the dismissal animation. | 38 // of the the screen. It has to be modified for the dismissal animation. |
| 39 NSLayoutConstraint* _centerYConstraint; | 39 NSLayoutConstraint* _centerYConstraint; |
| 40 | 40 |
| 41 NSURL* _shareURL; | 41 NSURL* _shareURL; |
| 42 NSString* _shareTitle; | 42 NSString* _shareTitle; |
| 43 UIImage* _image; | |
| 43 NSExtensionItem* _shareItem; | 44 NSExtensionItem* _shareItem; |
| 44 } | 45 } |
| 45 | 46 |
| 46 @property(nonatomic, weak) UIView* maskView; | 47 @property(nonatomic, weak) UIView* maskView; |
| 47 @property(nonatomic, weak) ShareExtensionView* shareView; | 48 @property(nonatomic, weak) ShareExtensionView* shareView; |
| 48 @property(nonatomic, assign) app_group::ShareExtensionItemType itemType; | 49 @property(nonatomic, assign) app_group::ShareExtensionItemType itemType; |
| 49 | 50 |
| 50 // Creates a files in |app_group::ShareExtensionItemsFolder()| containing a | 51 // Creates a files in |app_group::ShareExtensionItemsFolder()| containing a |
| 51 // serialized NSDictionary. | 52 // serialized NSDictionary. |
| 52 // If |cancel| is true, |actionType| is ignored. | 53 // If |cancel| is true, |actionType| is ignored. |
| 53 - (void)queueActionItemURL:(NSURL*)URL | 54 - (void)queueActionItemURL:(NSURL*)URL |
| 54 title:(NSString*)title | 55 title:(NSString*)title |
| 55 action:(app_group::ShareExtensionItemType)actionType | 56 action:(app_group::ShareExtensionItemType)actionType |
| 56 cancel:(BOOL)cancel | 57 cancel:(BOOL)cancel |
| 57 completion:(ProceduralBlock)completion; | 58 completion:(ProceduralBlock)completion; |
| 58 | 59 |
| 59 // Loads all the shared elements from the extension context and update the UI. | 60 // Loads all the shared elements from the extension context and update the UI. |
| 60 - (void)loadElementsFromContext; | 61 - (void)loadElementsFromContext; |
| 61 | 62 |
| 62 // Sets constaints to the widget so that margin are at least | 63 // Sets constaints to the widget so that margin are at least |
| 63 // kShareExtensionMargin points and widget width is closest up to | 64 // kShareExtensionMargin points and widget width is closest up to |
| 64 // kShareExtensionMaxWidth points. | 65 // kShareExtensionMaxWidth points. |
| 65 - (void)constrainWidgetWidth; | 66 - (void)constrainWidgetWidth; |
| 66 | 67 |
| 68 // Display the normal share view. | |
|
gambard
2017/01/02 09:11:41
s/Display/Displays
Olivier
2017/01/02 10:40:40
Done.
| |
| 69 - (void)displayShareView; | |
| 70 | |
| 71 // Display an alert to report an error to the user. | |
|
gambard
2017/01/02 09:11:41
s/Display/Displays
Olivier
2017/01/02 10:40:40
Done.
| |
| 72 - (void)displayErrorView; | |
| 73 | |
| 67 @end | 74 @end |
| 68 | 75 |
| 69 @implementation ShareViewController | 76 @implementation ShareViewController |
| 70 | 77 |
| 71 @synthesize maskView = _maskView; | 78 @synthesize maskView = _maskView; |
| 72 @synthesize shareView = _shareView; | 79 @synthesize shareView = _shareView; |
| 73 @synthesize itemType = _itemType; | 80 @synthesize itemType = _itemType; |
| 74 | 81 |
| 75 #pragma mark - UIViewController | 82 #pragma mark - UIViewController |
| 76 | 83 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 91 [self setShareView:shareView]; | 98 [self setShareView:shareView]; |
| 92 [self.view addSubview:self.shareView]; | 99 [self.view addSubview:self.shareView]; |
| 93 | 100 |
| 94 [self constrainWidgetWidth]; | 101 [self constrainWidgetWidth]; |
| 95 | 102 |
| 96 // Position the widget below the screen. It will be slided up with an | 103 // Position the widget below the screen. It will be slided up with an |
| 97 // animation. | 104 // animation. |
| 98 _centerYConstraint = [[shareView centerYAnchor] | 105 _centerYConstraint = [[shareView centerYAnchor] |
| 99 constraintEqualToAnchor:[self.view centerYAnchor]]; | 106 constraintEqualToAnchor:[self.view centerYAnchor]]; |
| 100 [_centerYConstraint setConstant:(self.view.frame.size.height + | 107 [_centerYConstraint setConstant:(self.view.frame.size.height + |
| 101 self.shareView.frame.size.height) / | 108 self.shareView.frame.size.height)]; |
| 102 2]; | |
|
gambard
2017/01/02 09:11:41
Why removing the /2?
Olivier
2017/01/02 10:40:40
In view did load, the size of Shareview is not fin
| |
| 103 [_centerYConstraint setActive:YES]; | 109 [_centerYConstraint setActive:YES]; |
| 104 [[[shareView centerXAnchor] constraintEqualToAnchor:[self.view centerXAnchor]] | 110 [[[shareView centerXAnchor] constraintEqualToAnchor:[self.view centerXAnchor]] |
| 105 setActive:YES]; | 111 setActive:YES]; |
| 106 | 112 |
| 107 [self.maskView setTranslatesAutoresizingMaskIntoConstraints:NO]; | 113 [self.maskView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 108 [self.shareView setTranslatesAutoresizingMaskIntoConstraints:NO]; | 114 [self.shareView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 109 | 115 |
| 110 [self loadElementsFromContext]; | 116 [self loadElementsFromContext]; |
| 111 } | 117 } |
| 112 | 118 |
| 113 - (void)viewWillAppear:(BOOL)animated { | |
| 114 [super viewWillAppear:animated]; | |
| 115 | |
| 116 // Center the widget. | |
| 117 [_centerYConstraint setConstant:0]; | |
| 118 [self.maskView setAlpha:0]; | |
| 119 [UIView animateWithDuration:kAnimationDuration | |
| 120 animations:^{ | |
| 121 [self.maskView setAlpha:1]; | |
| 122 [self.view layoutIfNeeded]; | |
| 123 }]; | |
| 124 } | |
| 125 | |
| 126 #pragma mark - Private methods | 119 #pragma mark - Private methods |
| 127 | 120 |
| 121 - (void)displayShareView { | |
| 122 [self.shareView setTitle:_shareTitle]; | |
| 123 [self.shareView setURL:_shareURL]; | |
| 124 if (_image) { | |
| 125 [self.shareView setScreenshot:_image]; | |
| 126 } | |
| 127 dispatch_async(dispatch_get_main_queue(), ^{ | |
| 128 // Center the widget. | |
| 129 [_centerYConstraint setConstant:0]; | |
| 130 [self.maskView setAlpha:0]; | |
| 131 [UIView animateWithDuration:kAnimationDuration | |
| 132 animations:^{ | |
| 133 [self.maskView setAlpha:1]; | |
| 134 [self.view layoutIfNeeded]; | |
| 135 }]; | |
| 136 }); | |
| 137 } | |
| 138 | |
| 139 - (void)displayErrorView { | |
| 140 NSString* errorMessage = | |
| 141 NSLocalizedString(@"IDS_IOS_ERROR_MESSAGE_SHARE_EXTENSION", | |
| 142 @"The error message to display to the user."); | |
| 143 NSString* okButton = | |
| 144 NSLocalizedString(@"IDS_IOS_OK_BUTTON_SHARE_EXTENSION", | |
| 145 @"The label of the OK button in share extension."); | |
| 146 NSString* applicationName = [[[NSBundle mainBundle] infoDictionary] | |
| 147 valueForKey:@"CFBundleDisplayName"]; | |
| 148 errorMessage = | |
| 149 [errorMessage stringByReplacingOccurrencesOfString:@"APPLICATION_NAME" | |
| 150 withString:applicationName]; | |
| 151 UIAlertController* alert = | |
| 152 [UIAlertController alertControllerWithTitle:errorMessage | |
| 153 message:[_shareURL absoluteString] | |
| 154 preferredStyle:UIAlertControllerStyleAlert]; | |
| 155 UIAlertAction* defaultAction = | |
| 156 [UIAlertAction actionWithTitle:okButton | |
| 157 style:UIAlertActionStyleDefault | |
| 158 handler:^(UIAlertAction* action) { | |
| 159 [self dismissAndReturnItem:nil]; | |
| 160 }]; | |
| 161 [alert addAction:defaultAction]; | |
| 162 [self presentViewController:alert animated:YES completion:nil]; | |
| 163 } | |
| 164 | |
| 128 - (void)constrainWidgetWidth { | 165 - (void)constrainWidgetWidth { |
| 129 // Setting the constraints. | 166 // Setting the constraints. |
| 130 NSDictionary* views = @{ @"share" : self.shareView }; | 167 NSDictionary* views = @{ @"share" : self.shareView }; |
| 131 | 168 |
| 132 NSDictionary* metrics = @{ | 169 NSDictionary* metrics = @{ |
| 133 @"margin" : @(kShareExtensionMargin), | 170 @"margin" : @(kShareExtensionMargin), |
| 134 @"maxWidth" : @(kShareExtensionMaxWidth), | 171 @"maxWidth" : @(kShareExtensionMaxWidth), |
| 135 }; | 172 }; |
| 136 | 173 |
| 137 NSArray* constraints = @[ | 174 NSArray* constraints = @[ |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 164 if ([itemProvider hasItemConformingToTypeIdentifier:typeURL]) { | 201 if ([itemProvider hasItemConformingToTypeIdentifier:typeURL]) { |
| 165 ItemBlock URLCompletion = ^(id idURL, NSError* error) { | 202 ItemBlock URLCompletion = ^(id idURL, NSError* error) { |
| 166 NSURL* URL = static_cast<NSURL*>(idURL); | 203 NSURL* URL = static_cast<NSURL*>(idURL); |
| 167 dispatch_async(dispatch_get_main_queue(), ^{ | 204 dispatch_async(dispatch_get_main_queue(), ^{ |
| 168 _shareItem = [item copy]; | 205 _shareItem = [item copy]; |
| 169 _shareURL = [URL copy]; | 206 _shareURL = [URL copy]; |
| 170 _shareTitle = [[[item attributedContentText] string] copy]; | 207 _shareTitle = [[[item attributedContentText] string] copy]; |
| 171 if ([_shareTitle length] == 0) { | 208 if ([_shareTitle length] == 0) { |
| 172 _shareTitle = [URL host]; | 209 _shareTitle = [URL host]; |
| 173 } | 210 } |
| 174 [self.shareView setURL:URL]; | 211 if ([[_shareURL scheme] isEqualToString:@"http"] || |
| 175 [self.shareView setTitle:_shareTitle]; | 212 [[_shareURL scheme] isEqualToString:@"https"]) { |
| 213 [self displayShareView]; | |
| 214 } else { | |
| 215 [self displayErrorView]; | |
| 216 } | |
| 176 }); | 217 }); |
| 177 | 218 |
| 178 }; | 219 }; |
| 179 [itemProvider loadItemForTypeIdentifier:typeURL | 220 [itemProvider loadItemForTypeIdentifier:typeURL |
| 180 options:nil | 221 options:nil |
| 181 completionHandler:URLCompletion]; | 222 completionHandler:URLCompletion]; |
| 182 NSDictionary* imageOptions = @{ | 223 NSDictionary* imageOptions = @{ |
| 183 NSItemProviderPreferredImageSizeKey : [NSValue | 224 NSItemProviderPreferredImageSizeKey : [NSValue |
| 184 valueWithCGSize:CGSizeMake(kScreenShotWidth, kScreenShotHeight)] | 225 valueWithCGSize:CGSizeMake(kScreenShotWidth, kScreenShotHeight)] |
| 185 }; | 226 }; |
| 186 ItemBlock ImageCompletion = ^(id item, NSError* error) { | 227 ItemBlock imageCompletion = ^(id item, NSError* error) { |
| 187 | 228 _image = static_cast<UIImage*>(item); |
| 188 UIImage* image = static_cast<UIImage*>(item); | 229 if (_image && self.shareView) { |
| 189 if (image) { | |
| 190 dispatch_async(dispatch_get_main_queue(), ^{ | 230 dispatch_async(dispatch_get_main_queue(), ^{ |
| 191 [self.shareView setScreenshot:image]; | 231 [self.shareView setScreenshot:_image]; |
| 192 }); | 232 }); |
| 193 } | 233 } |
| 194 | 234 |
| 195 }; | 235 }; |
| 196 [itemProvider loadPreviewImageWithOptions:imageOptions | 236 [itemProvider loadPreviewImageWithOptions:imageOptions |
| 197 completionHandler:ImageCompletion]; | 237 completionHandler:imageCompletion]; |
| 198 } | 238 } |
| 199 } | 239 } |
| 200 } | 240 } |
| 201 } | 241 } |
| 202 | 242 |
| 203 - (void)dismissAndReturnItem:(NSExtensionItem*)item { | 243 - (void)dismissAndReturnItem:(NSExtensionItem*)item { |
| 204 // Set the Y center constraints so the whole extension slides out of the | 244 // Set the Y center constraints so the whole extension slides out of the |
| 205 // screen. Constant is relative to the center of the screen. | 245 // screen. Constant is relative to the center of the screen. |
| 206 // The direction (up or down) is relative to the output (cancel or submit). | 246 // The direction (up or down) is relative to the output (cancel or submit). |
| 207 NSInteger direction = item ? -1 : 1; | 247 NSInteger direction = item ? -1 : 1; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 [self dismissAndReturnItem:_shareItem]; | 338 [self dismissAndReturnItem:_shareItem]; |
| 299 }]; | 339 }]; |
| 300 } | 340 } |
| 301 | 341 |
| 302 - (void)shareExtensionView:(id)sender | 342 - (void)shareExtensionView:(id)sender |
| 303 typeChanged:(app_group::ShareExtensionItemType)type { | 343 typeChanged:(app_group::ShareExtensionItemType)type { |
| 304 [self setItemType:type]; | 344 [self setItemType:type]; |
| 305 } | 345 } |
| 306 | 346 |
| 307 @end | 347 @end |
| OLD | NEW |