OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/browser/ui/bookmarks/bookmark_folder_collection_view.h" | 5 #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_collection_view.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/sys_string_conversions.h" | 8 #include "base/strings/sys_string_conversions.h" |
9 #include "components/bookmarks/browser/bookmark_model.h" | 9 #include "components/bookmarks/browser/bookmark_model.h" |
10 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" | 10 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" |
11 #include "ios/chrome/browser/experimental_flags.h" | 11 #include "ios/chrome/browser/experimental_flags.h" |
| 12 #import "ios/chrome/browser/ui/authentication/signin_promo_view.h" |
| 13 #import "ios/chrome/browser/ui/authentication/signin_promo_view_configurator.h" |
| 14 #import "ios/chrome/browser/ui/authentication/signin_promo_view_consumer.h" |
| 15 #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" |
12 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h" | 16 #import "ios/chrome/browser/ui/bookmarks/bookmark_collection_cells.h" |
13 #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_cell.h" | 17 #import "ios/chrome/browser/ui/bookmarks/bookmark_promo_cell.h" |
| 18 #import "ios/chrome/browser/ui/bookmarks/bookmark_signin_promo_cell.h" |
14 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" | 19 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" |
15 | 20 |
16 #if !defined(__has_feature) || !__has_feature(objc_arc) | 21 #if !defined(__has_feature) || !__has_feature(objc_arc) |
17 #error "This file requires ARC support." | 22 #error "This file requires ARC support." |
18 #endif | 23 #endif |
19 | 24 |
20 using bookmarks::BookmarkNode; | 25 using bookmarks::BookmarkNode; |
21 | 26 |
22 @interface BookmarkFolderCollectionView ()<BookmarkPromoCellDelegate> { | 27 namespace { |
| 28 // Computes the cell size based on width. |
| 29 CGSize PreferredCellSizeForWidth(UICollectionViewCell* cell, CGFloat width) { |
| 30 CGRect cellFrame = cell.frame; |
| 31 cellFrame.size.width = width; |
| 32 cellFrame.size.height = CGFLOAT_MAX; |
| 33 cell.frame = cellFrame; |
| 34 [cell setNeedsLayout]; |
| 35 [cell layoutIfNeeded]; |
| 36 CGSize result = |
| 37 [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize |
| 38 withHorizontalFittingPriority:UILayoutPriorityRequired |
| 39 verticalFittingPriority:UILayoutPriorityDefaultLow]; |
| 40 cellFrame.size = result; |
| 41 cell.frame = cellFrame; |
| 42 return result; |
| 43 } |
| 44 } |
| 45 |
| 46 @interface BookmarkFolderCollectionView ()<BookmarkPromoCellDelegate, |
| 47 SigninPromoViewConsumer> { |
23 // A vector of folders to display in the collection view. | 48 // A vector of folders to display in the collection view. |
24 std::vector<const BookmarkNode*> _subFolders; | 49 std::vector<const BookmarkNode*> _subFolders; |
25 // A vector of bookmark urls to display in the collection view. | 50 // A vector of bookmark urls to display in the collection view. |
26 std::vector<const BookmarkNode*> _subItems; | 51 std::vector<const BookmarkNode*> _subItems; |
27 | 52 |
28 // True if the promo is visible. | 53 // True if the promo is visible. |
29 BOOL _promoVisible; | 54 BOOL _promoVisible; |
| 55 |
| 56 // Mediator, helper for the sign-in promo view. |
| 57 SigninPromoViewMediator* _signinPromoViewMediator; |
30 } | 58 } |
31 @property(nonatomic, assign) const bookmarks::BookmarkNode* folder; | 59 @property(nonatomic, assign) const bookmarks::BookmarkNode* folder; |
32 | 60 |
33 // Section indices. | 61 // Section indices. |
34 @property(nonatomic, readonly, assign) NSInteger promoSection; | 62 @property(nonatomic, readonly, assign) NSInteger promoSection; |
35 @property(nonatomic, readonly, assign) NSInteger folderSection; | 63 @property(nonatomic, readonly, assign) NSInteger folderSection; |
36 @property(nonatomic, readonly, assign) NSInteger itemsSection; | 64 @property(nonatomic, readonly, assign) NSInteger itemsSection; |
37 @property(nonatomic, readonly, assign) NSInteger sectionCount; | 65 @property(nonatomic, readonly, assign) NSInteger sectionCount; |
38 | 66 |
39 // Keep a reference to the promo cell to deregister as delegate. | |
40 @property(nonatomic, strong) BookmarkPromoCell* promoCell; | |
41 | |
42 @end | 67 @end |
43 | 68 |
44 @implementation BookmarkFolderCollectionView | 69 @implementation BookmarkFolderCollectionView |
45 @synthesize delegate = _delegate; | 70 @synthesize delegate = _delegate; |
46 @synthesize folder = _folder; | 71 @synthesize folder = _folder; |
47 @synthesize promoCell = _promoCell; | |
48 | 72 |
49 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState | 73 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState |
50 frame:(CGRect)frame { | 74 frame:(CGRect)frame { |
51 self = [super initWithBrowserState:browserState frame:frame]; | 75 self = [super initWithBrowserState:browserState frame:frame]; |
52 if (self) { | 76 if (self) { |
53 [self updateCollectionView]; | 77 [self updateCollectionView]; |
54 } | 78 } |
55 return self; | 79 return self; |
56 } | 80 } |
57 | 81 |
58 - (void)dealloc { | |
59 _promoCell.delegate = nil; | |
60 } | |
61 | |
62 - (void)setDelegate:(id<BookmarkFolderCollectionViewDelegate>)delegate { | 82 - (void)setDelegate:(id<BookmarkFolderCollectionViewDelegate>)delegate { |
63 _delegate = delegate; | 83 _delegate = delegate; |
64 [self promoStateChangedAnimated:NO]; | 84 [self promoStateChangedAnimated:NO]; |
65 } | 85 } |
66 | 86 |
67 - (NSInteger)promoSection { | 87 - (NSInteger)promoSection { |
68 return [self shouldShowPromoCell] ? 0 : -1; | 88 return [self shouldShowPromoCell] ? 0 : -1; |
69 } | 89 } |
70 | 90 |
71 - (NSInteger)folderSection { | 91 - (NSInteger)folderSection { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 else if (section == self.itemsSection) | 369 else if (section == self.itemsSection) |
350 insets.top = [self interitemSpacingForSectionAtIndex:section] / 2.; | 370 insets.top = [self interitemSpacingForSectionAtIndex:section] / 2.; |
351 else if (section == self.promoSection) | 371 else if (section == self.promoSection) |
352 (void)0; // No insets to update. | 372 (void)0; // No insets to update. |
353 else | 373 else |
354 NOTREACHED(); | 374 NOTREACHED(); |
355 return insets; | 375 return insets; |
356 } | 376 } |
357 | 377 |
358 // Parent class override. | 378 // Parent class override. |
| 379 - (CGSize)cellSizeForIndexPath:(NSIndexPath*)indexPath { |
| 380 if ([self isPromoSection:indexPath.section]) { |
| 381 UICollectionViewCell* cell = |
| 382 [self.collectionView cellForItemAtIndexPath:indexPath]; |
| 383 if (!cell) { |
| 384 // -[UICollectionView |
| 385 // dequeueReusableCellWithReuseIdentifier:forIndexPath:] cannot be used |
| 386 // here since this method is called by -[id<UICollectionViewDelegate> |
| 387 // collectionView:layout:sizeForItemAtIndexPath:]. This would generate |
| 388 // crash: SIGFPE, EXC_I386_DIV. |
| 389 if (experimental_flags::IsSigninPromoEnabled()) { |
| 390 DCHECK(_signinPromoViewMediator); |
| 391 BookmarkSigninPromoCell* signinPromoCell = |
| 392 [[BookmarkSigninPromoCell alloc] |
| 393 initWithFrame:CGRectMake(0, 0, 1000, 1000)]; |
| 394 [[_signinPromoViewMediator createConfigurator] |
| 395 configureSigninPromoView:signinPromoCell.signinPromoView]; |
| 396 cell = signinPromoCell; |
| 397 } else { |
| 398 cell = [[BookmarkPromoCell alloc] init]; |
| 399 } |
| 400 } |
| 401 return PreferredCellSizeForWidth(cell, CGRectGetWidth(self.bounds)); |
| 402 } |
| 403 return [super cellSizeForIndexPath:indexPath]; |
| 404 } |
| 405 |
| 406 // Parent class override. |
359 - (UICollectionViewCell*)cellAtIndexPath:(NSIndexPath*)indexPath { | 407 - (UICollectionViewCell*)cellAtIndexPath:(NSIndexPath*)indexPath { |
360 if (indexPath.section == self.promoSection) { | 408 if (indexPath.section == self.promoSection) { |
361 self.promoCell = [self.collectionView | 409 if (experimental_flags::IsSigninPromoEnabled()) { |
362 dequeueReusableCellWithReuseIdentifier:[BookmarkPromoCell | 410 BookmarkSigninPromoCell* signinPromoCell = [self.collectionView |
363 reuseIdentifier] | 411 dequeueReusableCellWithReuseIdentifier:[BookmarkSigninPromoCell |
364 forIndexPath:indexPath]; | 412 reuseIdentifier] |
365 self.promoCell.delegate = self; | 413 forIndexPath:indexPath]; |
366 return self.promoCell; | 414 signinPromoCell.signinPromoView.sendChromeCommand = YES; |
| 415 [[_signinPromoViewMediator createConfigurator] |
| 416 configureSigninPromoView:signinPromoCell.signinPromoView]; |
| 417 return signinPromoCell; |
| 418 } else { |
| 419 BookmarkPromoCell* promoCell = [self.collectionView |
| 420 dequeueReusableCellWithReuseIdentifier:[BookmarkPromoCell |
| 421 reuseIdentifier] |
| 422 forIndexPath:indexPath]; |
| 423 promoCell.delegate = self; |
| 424 return promoCell; |
| 425 } |
367 } | 426 } |
368 const BookmarkNode* node = [self nodeAtIndexPath:indexPath]; | 427 const BookmarkNode* node = [self nodeAtIndexPath:indexPath]; |
369 | 428 |
370 if (indexPath.section == self.folderSection) | 429 if (indexPath.section == self.folderSection) |
371 return [self cellForFolder:node indexPath:indexPath]; | 430 return [self cellForFolder:node indexPath:indexPath]; |
372 | 431 |
373 BookmarkItemCell* cell = [self cellForBookmark:node indexPath:indexPath]; | 432 BookmarkItemCell* cell = [self cellForBookmark:node indexPath:indexPath]; |
374 return cell; | 433 return cell; |
375 } | 434 } |
376 | 435 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 - (void)promoStateChangedAnimated:(BOOL)animate { | 497 - (void)promoStateChangedAnimated:(BOOL)animate { |
439 BOOL newPromoState = | 498 BOOL newPromoState = |
440 !self.editing && self.folder && | 499 !self.editing && self.folder && |
441 self.folder->type() == BookmarkNode::MOBILE && | 500 self.folder->type() == BookmarkNode::MOBILE && |
442 [self.delegate bookmarkCollectionViewShouldShowPromoCell:self]; | 501 [self.delegate bookmarkCollectionViewShouldShowPromoCell:self]; |
443 if (newPromoState != _promoVisible) { | 502 if (newPromoState != _promoVisible) { |
444 // This is awful, but until the old code to do the refresh when switching | 503 // This is awful, but until the old code to do the refresh when switching |
445 // in and out of edit mode is fixed, this is probably the cleanest thing to | 504 // in and out of edit mode is fixed, this is probably the cleanest thing to |
446 // do. | 505 // do. |
447 _promoVisible = newPromoState; | 506 _promoVisible = newPromoState; |
| 507 if (experimental_flags::IsSigninPromoEnabled()) { |
| 508 if (!_promoVisible) { |
| 509 _signinPromoViewMediator.consumer = nil; |
| 510 _signinPromoViewMediator = nil; |
| 511 } else { |
| 512 _signinPromoViewMediator = [[SigninPromoViewMediator alloc] init]; |
| 513 _signinPromoViewMediator.consumer = self; |
| 514 } |
| 515 } |
448 [self.collectionView reloadData]; | 516 [self.collectionView reloadData]; |
449 } | 517 } |
450 } | 518 } |
451 | 519 |
452 #pragma mark - BookmarkPromoCellDelegate | 520 #pragma mark - BookmarkPromoCellDelegate |
453 | 521 |
454 - (void)bookmarkPromoCellDidTapSignIn:(BookmarkPromoCell*)bookmarkPromoCell { | 522 - (void)bookmarkPromoCellDidTapSignIn:(BookmarkPromoCell*)bookmarkPromoCell { |
455 [self.delegate bookmarkCollectionViewShowSignIn:self]; | 523 [self.delegate bookmarkCollectionViewShowSignIn:self]; |
456 } | 524 } |
457 | 525 |
458 - (void)bookmarkPromoCellDidTapDismiss:(BookmarkPromoCell*)bookmarkPromoCell { | 526 - (void)bookmarkPromoCellDidTapDismiss:(BookmarkPromoCell*)bookmarkPromoCell { |
459 [self.delegate bookmarkCollectionViewDismissPromo:self]; | 527 [self.delegate bookmarkCollectionViewDismissPromo:self]; |
460 } | 528 } |
461 | 529 |
462 #pragma mark - Promo Cell | 530 #pragma mark - Promo Cell |
463 | 531 |
464 - (BOOL)shouldShowPromoCell { | 532 - (BOOL)shouldShowPromoCell { |
465 return _promoVisible; | 533 return _promoVisible; |
466 } | 534 } |
467 | 535 |
| 536 #pragma mark - SigninPromoViewConsumer |
| 537 |
| 538 - (void)configureSigninPromoViewWithNewIdentity:(BOOL)newIdentity |
| 539 configurator:(SigninPromoViewConfigurator*) |
| 540 configurator { |
| 541 DCHECK(_signinPromoViewMediator); |
| 542 if (newIdentity) { |
| 543 NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:self.promoSection]; |
| 544 [self.collectionView reloadSections:indexSet]; |
| 545 return; |
| 546 } |
| 547 NSIndexPath* indexPath = |
| 548 [NSIndexPath indexPathForRow:0 inSection:self.promoSection]; |
| 549 BookmarkSigninPromoCell* signinPromoCell = |
| 550 static_cast<BookmarkSigninPromoCell*>( |
| 551 [self.collectionView cellForItemAtIndexPath:indexPath]); |
| 552 if (!signinPromoCell) |
| 553 return; |
| 554 [configurator configureSigninPromoView:signinPromoCell.signinPromoView]; |
| 555 } |
| 556 |
468 @end | 557 @end |
OLD | NEW |