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 "ios/chrome/share_extension/share_extension_view.h" | 5 #import "ios/chrome/share_extension/share_extension_view.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #import "ios/chrome/share_extension/ui_util.h" | 8 #import "ios/chrome/share_extension/ui_util.h" |
| 9 | 9 |
| 10 #if !defined(__has_feature) || !__has_feature(objc_arc) | 10 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 else | 44 else |
| 45 self.backgroundColor = [UIColor clearColor]; | 45 self.backgroundColor = [UIColor clearColor]; |
| 46 } | 46 } |
| 47 | 47 |
| 48 @end | 48 @end |
| 49 | 49 |
| 50 #pragma mark - Share Extension View | 50 #pragma mark - Share Extension View |
| 51 | 51 |
| 52 @interface ShareExtensionView () { | 52 @interface ShareExtensionView () { |
| 53 __weak id<ShareExtensionViewActionTarget> _target; | 53 __weak id<ShareExtensionViewActionTarget> _target; |
| 54 | |
| 55 // Track if a button has been pressed. All button pressing will have no effect | |
| 56 // if |_dismissed| is YES. | |
| 57 BOOL _dismissed; | |
| 54 } | 58 } |
| 55 | 59 |
| 56 // Keep strong references of the views that need to be updated. | 60 // Keep strong references of the views that need to be updated. |
| 57 @property(nonatomic, strong) UILabel* titleLabel; | 61 @property(nonatomic, strong) UILabel* titleLabel; |
| 58 @property(nonatomic, strong) UILabel* URLLabel; | 62 @property(nonatomic, strong) UILabel* URLLabel; |
| 63 @property(nonatomic, strong) UIButton* readingListButton; | |
| 59 @property(nonatomic, strong) UIImageView* screenshotView; | 64 @property(nonatomic, strong) UIImageView* screenshotView; |
| 60 @property(nonatomic, strong) UIStackView* itemStack; | 65 @property(nonatomic, strong) UIStackView* itemStack; |
| 61 | 66 |
| 62 // View creation helpers. | 67 // View creation helpers. |
| 63 // Returns a view containing the shared items (title, URL, screenshot). This | 68 // Returns a view containing the shared items (title, URL, screenshot). This |
| 64 // method will set the ivars. | 69 // method will set the ivars. |
| 65 - (UIView*)sharedItemView; | 70 - (UIView*)sharedItemView; |
| 66 | 71 |
| 67 // Returns a button containing the with title |title| and action |selector| on | 72 // Returns a button containing the with title |title| and action |selector| on |
| 68 // |_target|. | 73 // |_target|. |
| 69 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector; | 74 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector; |
| 70 | 75 |
| 71 // Returns a view containing a divider with vibrancy effect. | 76 // Returns a view containing a divider with vibrancy effect. |
| 72 - (UIView*)dividerViewWithVibrancy:(UIVisualEffect*)vibrancyEffect; | 77 - (UIView*)dividerViewWithVibrancy:(UIVisualEffect*)vibrancyEffect; |
| 73 | 78 |
| 74 // Returns a navigationBar. | 79 // Returns a navigationBar. |
| 75 - (UINavigationBar*)navigationBar; | 80 - (UINavigationBar*)navigationBar; |
| 76 | 81 |
| 82 // Called when "Read Later" button has been pressed. | |
| 83 - (void)addToReadingListPressed:(UIButton*)sender; | |
| 84 | |
| 85 // Called when "Add to bookmarks" button has been pressed. | |
| 86 - (void)addToBookmarksPressed:(UIButton*)sender; | |
| 87 | |
| 88 // Called when "Cancel" button has been pressed. | |
| 89 - (void)cancelPressed:(UIButton*)sender; | |
| 90 | |
| 77 @end | 91 @end |
| 78 | 92 |
| 79 @implementation ShareExtensionView | 93 @implementation ShareExtensionView |
| 80 | 94 |
| 81 @synthesize titleLabel = _titleLabel; | 95 @synthesize titleLabel = _titleLabel; |
| 82 @synthesize URLLabel = _URLLabel; | 96 @synthesize URLLabel = _URLLabel; |
| 97 @synthesize readingListButton = _readingListButton; | |
| 83 @synthesize screenshotView = _screenshotView; | 98 @synthesize screenshotView = _screenshotView; |
| 84 @synthesize itemStack = _itemStack; | 99 @synthesize itemStack = _itemStack; |
| 85 | 100 |
| 86 #pragma mark - Lifecycle | 101 #pragma mark - Lifecycle |
| 87 | 102 |
| 88 - (instancetype)initWithActionTarget: | 103 - (instancetype)initWithActionTarget: |
| 89 (id<ShareExtensionViewActionTarget>)target { | 104 (id<ShareExtensionViewActionTarget>)target { |
| 90 self = [super initWithFrame:CGRectZero]; | 105 self = [super initWithFrame:CGRectZero]; |
| 91 if (self) { | 106 if (self) { |
| 92 DCHECK(target); | 107 DCHECK(target); |
| 93 _target = target; | 108 _target = target; |
| 109 _dismissed = NO; | |
| 94 | 110 |
| 95 [self.layer setCornerRadius:kCornerRadius]; | 111 [self.layer setCornerRadius:kCornerRadius]; |
| 96 [self setClipsToBounds:YES]; | 112 [self setClipsToBounds:YES]; |
| 97 UIBlurEffect* blurEffect = | 113 UIBlurEffect* blurEffect = |
| 98 [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]; | 114 [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]; |
| 99 UIVibrancyEffect* vibrancyEffect = | 115 UIVibrancyEffect* vibrancyEffect = |
| 100 [UIVibrancyEffect effectForBlurEffect:blurEffect]; | 116 [UIVibrancyEffect effectForBlurEffect:blurEffect]; |
| 101 | 117 |
| 102 self.backgroundColor = [UIColor colorWithWhite:242.0f / 255.0f alpha:1]; | 118 self.backgroundColor = [UIColor colorWithWhite:242.0f / 255.0f alpha:1]; |
| 103 | 119 |
| 104 // Add the blur effect to the whole widget. | 120 // Add the blur effect to the whole widget. |
| 105 UIVisualEffectView* blurringView = | 121 UIVisualEffectView* blurringView = |
| 106 [[UIVisualEffectView alloc] initWithEffect:blurEffect]; | 122 [[UIVisualEffectView alloc] initWithEffect:blurEffect]; |
| 107 [self addSubview:blurringView]; | 123 [self addSubview:blurringView]; |
| 108 ui_util::ConstrainAllSidesOfViewToView(self, blurringView); | 124 ui_util::ConstrainAllSidesOfViewToView(self, blurringView); |
| 109 [[blurringView layer] setCornerRadius:kCornerRadius]; | 125 [[blurringView layer] setCornerRadius:kCornerRadius]; |
| 110 [blurringView setClipsToBounds:YES]; | 126 [blurringView setClipsToBounds:YES]; |
| 111 | 127 |
| 112 NSString* addToReadingListTitle = NSLocalizedString( | 128 NSString* addToReadingListTitle = NSLocalizedString( |
| 113 @"IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION", | 129 @"IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION", |
| 114 @"The add to reading list button text in share extension."); | 130 @"The add to reading list button text in share extension."); |
| 115 UIButton* readingListButton = [self | 131 self.readingListButton = |
| 116 buttonWithTitle:addToReadingListTitle | 132 [self buttonWithTitle:addToReadingListTitle |
| 117 selector:@selector( | 133 selector:@selector(addToReadingListPressed:)]; |
| 118 shareExtensionViewDidSelectAddToReadingList:)]; | |
| 119 | 134 |
| 120 NSString* addToBookmarksTitle = NSLocalizedString( | 135 NSString* addToBookmarksTitle = NSLocalizedString( |
| 121 @"IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION", | 136 @"IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION", |
| 122 @"The Add to bookmarks button text in share extension."); | 137 @"The Add to bookmarks button text in share extension."); |
| 123 UIButton* bookmarksButton = [self | 138 UIButton* bookmarksButton = |
| 124 buttonWithTitle:addToBookmarksTitle | 139 [self buttonWithTitle:addToBookmarksTitle |
| 125 selector:@selector(shareExtensionViewDidSelectAddToBookmarks:)]; | 140 selector:@selector(addToBookmarksPressed:)]; |
| 126 | 141 |
| 127 UIStackView* contentStack = [[UIStackView alloc] initWithArrangedSubviews:@[ | 142 UIStackView* contentStack = [[UIStackView alloc] initWithArrangedSubviews:@[ |
| 128 [self navigationBar], [self dividerViewWithVibrancy:vibrancyEffect], | 143 [self navigationBar], [self dividerViewWithVibrancy:vibrancyEffect], |
| 129 [self sharedItemView], [self dividerViewWithVibrancy:vibrancyEffect], | 144 [self sharedItemView], [self dividerViewWithVibrancy:vibrancyEffect], |
| 130 readingListButton, [self dividerViewWithVibrancy:vibrancyEffect], | 145 self.readingListButton, [self dividerViewWithVibrancy:vibrancyEffect], |
| 131 bookmarksButton | 146 bookmarksButton |
| 132 ]]; | 147 ]]; |
| 133 [contentStack setAxis:UILayoutConstraintAxisVertical]; | 148 [contentStack setAxis:UILayoutConstraintAxisVertical]; |
| 134 [[blurringView contentView] addSubview:contentStack]; | 149 [[blurringView contentView] addSubview:contentStack]; |
| 135 | 150 |
| 136 [blurringView setTranslatesAutoresizingMaskIntoConstraints:NO]; | 151 [blurringView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 137 [contentStack setTranslatesAutoresizingMaskIntoConstraints:NO]; | 152 [contentStack setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 138 | 153 |
| 139 ui_util::ConstrainAllSidesOfViewToView([blurringView contentView], | 154 ui_util::ConstrainAllSidesOfViewToView([blurringView contentView], |
| 140 contentStack); | 155 contentStack); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 | 264 |
| 250 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector { | 265 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector { |
| 251 UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem]; | 266 UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem]; |
| 252 UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal]; | 267 UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal]; |
| 253 | 268 |
| 254 UIButton* button = [[ShareExtensionButton alloc] initWithFrame:CGRectZero]; | 269 UIButton* button = [[ShareExtensionButton alloc] initWithFrame:CGRectZero]; |
| 255 [button setTitle:title forState:UIControlStateNormal]; | 270 [button setTitle:title forState:UIControlStateNormal]; |
| 256 [button setTitleColor:systemColor forState:UIControlStateNormal]; | 271 [button setTitleColor:systemColor forState:UIControlStateNormal]; |
| 257 [[button titleLabel] setFont:[UIFont systemFontOfSize:kButtonFontSize]]; | 272 [[button titleLabel] setFont:[UIFont systemFontOfSize:kButtonFontSize]]; |
| 258 [button setTranslatesAutoresizingMaskIntoConstraints:NO]; | 273 [button setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 259 [button addTarget:_target | 274 [button addTarget:self |
| 260 action:selector | 275 action:selector |
| 261 forControlEvents:UIControlEventTouchUpInside]; | 276 forControlEvents:UIControlEventTouchUpInside]; |
| 262 [button.heightAnchor constraintEqualToConstant:kButtonHeight].active = YES; | 277 [button.heightAnchor constraintEqualToConstant:kButtonHeight].active = YES; |
| 263 return button; | 278 return button; |
| 264 } | 279 } |
| 265 | 280 |
| 266 - (UINavigationBar*)navigationBar { | 281 - (UINavigationBar*)navigationBar { |
| 267 // Create the navigation bar. | 282 // Create the navigation bar. |
| 268 UINavigationBar* navigationBar = | 283 UINavigationBar* navigationBar = |
| 269 [[UINavigationBar alloc] initWithFrame:CGRectZero]; | 284 [[UINavigationBar alloc] initWithFrame:CGRectZero]; |
| 270 [[navigationBar layer] setCornerRadius:kCornerRadius]; | 285 [[navigationBar layer] setCornerRadius:kCornerRadius]; |
| 271 [navigationBar setClipsToBounds:YES]; | 286 [navigationBar setClipsToBounds:YES]; |
| 272 | 287 |
| 273 // Create an empty image to replace the standard gray background of the | 288 // Create an empty image to replace the standard gray background of the |
| 274 // UINavigationBar. | 289 // UINavigationBar. |
| 275 UIImage* emptyImage = [[UIImage alloc] init]; | 290 UIImage* emptyImage = [[UIImage alloc] init]; |
| 276 [navigationBar setBackgroundImage:emptyImage | 291 [navigationBar setBackgroundImage:emptyImage |
| 277 forBarMetrics:UIBarMetricsDefault]; | 292 forBarMetrics:UIBarMetricsDefault]; |
| 278 [navigationBar setShadowImage:emptyImage]; | 293 [navigationBar setShadowImage:emptyImage]; |
| 279 [navigationBar setTranslucent:YES]; | 294 [navigationBar setTranslucent:YES]; |
| 280 [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO]; | 295 [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 281 | 296 |
| 282 UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] | 297 UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] |
| 283 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel | 298 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel |
| 284 target:_target | 299 target:self |
| 285 action:@selector( | 300 action:@selector(cancelPressed:)]; |
| 286 shareExtensionViewDidSelectCancel:)]; | |
| 287 | 301 |
| 288 NSString* appName = | 302 NSString* appName = |
| 289 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; | 303 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; |
| 290 UINavigationItem* titleItem = | 304 UINavigationItem* titleItem = |
| 291 [[UINavigationItem alloc] initWithTitle:appName]; | 305 [[UINavigationItem alloc] initWithTitle:appName]; |
| 292 [titleItem setLeftBarButtonItem:cancelButton]; | 306 [titleItem setLeftBarButtonItem:cancelButton]; |
| 293 [titleItem setHidesBackButton:YES]; | 307 [titleItem setHidesBackButton:YES]; |
| 294 [navigationBar pushNavigationItem:titleItem animated:NO]; | 308 [navigationBar pushNavigationItem:titleItem animated:NO]; |
| 295 return navigationBar; | 309 return navigationBar; |
| 296 } | 310 } |
| 297 | 311 |
| 312 - (void)addToReadingListPressed:(UIButton*)sender { | |
| 313 if (_dismissed) { | |
| 314 return; | |
| 315 } | |
| 316 _dismissed = YES; | |
| 317 [self animateButtonPressed:sender | |
| 318 withCompletion:^{ | |
| 319 [_target shareExtensionViewDidSelectAddToReadingList:sender]; | |
| 320 }]; | |
| 321 } | |
| 322 | |
| 323 - (void)animateButtonPressed:(UIButton*)sender | |
|
gambard
2017/01/06 16:23:54
Add method definition and comment.
Olivier
2017/01/06 16:42:16
Done.
| |
| 324 withCompletion:(void (^)(void))completion { | |
| 325 NSString* addedString = | |
| 326 NSLocalizedString(@"IDS_IOS_ADDED_ITEM_SHARE_EXTENSION", | |
|
gambard
2017/01/06 16:23:54
Did you add IDS_IOS_ADDED_ITEM_SHARE_EXTENSION? I
Olivier
2017/01/06 16:42:15
I did... in another tree... :(
| |
| 327 @"Button label after being pressed."); | |
| 328 NSString* addedCheckedString = | |
| 329 [addedString stringByAppendingString:@" \u2713"]; | |
| 330 // Create a label with the same style as the split animation between the text | |
| 331 // and the checkmark. | |
| 332 UILabel* addedLabel = [[UILabel alloc] initWithFrame:CGRectZero]; | |
| 333 [addedLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; | |
| 334 [addedLabel setText:addedString]; | |
| 335 [self addSubview:addedLabel]; | |
| 336 [addedLabel setFont:[sender titleLabel].font]; | |
| 337 [addedLabel setTextColor:[sender titleLabel].textColor]; | |
|
gambard
2017/01/06 16:23:54
You can use [sender titleColorForState:UIControlSt
Olivier
2017/01/06 16:42:15
Done.
| |
| 338 [addedLabel.leadingAnchor | |
|
gambard
2017/01/06 16:23:54
This will align the beginning of the "Added" with
Olivier
2017/01/06 16:42:15
There is no mock on what is centered.
What is true
| |
| 339 constraintEqualToAnchor:[sender titleLabel].leadingAnchor] | |
| 340 .active = YES; | |
| 341 [addedLabel.centerYAnchor | |
| 342 constraintEqualToAnchor:[sender titleLabel].centerYAnchor] | |
| 343 .active = YES; | |
| 344 [addedLabel setAlpha:0]; | |
| 345 | |
| 346 void (^step3ShowCheck)() = ^{ | |
| 347 [UIView animateWithDuration:ui_util::kAnimationDuration | |
| 348 animations:^{ | |
| 349 [addedLabel setAlpha:0]; | |
| 350 [sender setAlpha:1]; | |
| 351 } | |
| 352 completion:^(BOOL finished) { | |
| 353 completion(); | |
|
gambard
2017/01/06 16:23:54
You don't check for nullability?
Olivier
2017/01/06 16:42:16
Done.
| |
| 354 }]; | |
| 355 }; | |
| 356 | |
| 357 void (^step2ShowTextWithoutCheck)() = ^{ | |
| 358 [sender setTitle:addedCheckedString forState:UIControlStateNormal]; | |
| 359 [UIView animateWithDuration:ui_util::kAnimationDuration | |
| 360 animations:^{ | |
| 361 [addedLabel setAlpha:1]; | |
| 362 } | |
| 363 completion:^(BOOL finished) { | |
| 364 step3ShowCheck(); | |
| 365 }]; | |
| 366 }; | |
| 367 | |
| 368 void (^step1HideText)() = ^{ | |
| 369 [UIView animateWithDuration:ui_util::kAnimationDuration | |
| 370 animations:^{ | |
| 371 [sender setAlpha:0]; | |
| 372 } | |
| 373 completion:^(BOOL finished) { | |
| 374 step2ShowTextWithoutCheck(); | |
| 375 }]; | |
| 376 }; | |
| 377 step1HideText(); | |
| 378 } | |
| 379 | |
| 380 - (void)addToBookmarksPressed:(UIButton*)sender { | |
|
gambard
2017/01/06 16:23:54
Please position this function before animateButton
Olivier
2017/01/06 16:42:16
Done.
| |
| 381 if (_dismissed) { | |
| 382 return; | |
| 383 } | |
| 384 _dismissed = YES; | |
| 385 [self animateButtonPressed:sender | |
| 386 withCompletion:^{ | |
| 387 [_target shareExtensionViewDidSelectAddToBookmarks:sender]; | |
| 388 }]; | |
| 389 } | |
| 390 | |
| 391 - (void)cancelPressed:(UIButton*)sender { | |
| 392 if (_dismissed) { | |
| 393 return; | |
| 394 } | |
| 395 _dismissed = YES; | |
| 396 [_target shareExtensionViewDidSelectCancel:sender]; | |
| 397 } | |
| 398 | |
| 298 #pragma mark - Content getters and setters. | 399 #pragma mark - Content getters and setters. |
| 299 | 400 |
| 300 - (void)setURL:(NSURL*)URL { | 401 - (void)setURL:(NSURL*)URL { |
| 301 [[self URLLabel] setText:[URL absoluteString]]; | 402 [[self URLLabel] setText:[URL absoluteString]]; |
| 302 } | 403 } |
| 303 | 404 |
| 304 - (void)setTitle:(NSString*)title { | 405 - (void)setTitle:(NSString*)title { |
| 305 [[self titleLabel] setText:title]; | 406 [[self titleLabel] setText:title]; |
| 306 } | 407 } |
| 307 | 408 |
| 308 - (void)setScreenshot:(UIImage*)screenshot { | 409 - (void)setScreenshot:(UIImage*)screenshot { |
| 309 [[self screenshotView] setHidden:NO]; | 410 [[self screenshotView] setHidden:NO]; |
| 310 [[self screenshotView] setImage:screenshot]; | 411 [[self screenshotView] setImage:screenshot]; |
| 311 [[self itemStack] addArrangedSubview:[self screenshotView]]; | 412 [[self itemStack] addArrangedSubview:[self screenshotView]]; |
| 312 } | 413 } |
| 313 | 414 |
| 314 @end | 415 @end |
| OLD | NEW |