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) { | |
msarda
2017/04/28 11:53:14
Personal preference (I find that you need less loc
jlebel
2017/04/28 13:03:17
Done.
| |
30 CGPoint initialCellOrigin = cell.frame.origin; | |
31 CGRect fixedWidthMaxHeightFrame = | |
32 CGRectMake(initialCellOrigin.x, initialCellOrigin.y, width, CGFLOAT_MAX); | |
33 cell.frame = fixedWidthMaxHeightFrame; | |
34 [cell setNeedsLayout]; | |
35 [cell layoutIfNeeded]; | |
36 CGSize result = | |
37 [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize | |
38 withHorizontalFittingPriority:UILayoutPriorityRequired | |
39 verticalFittingPriority:UILayoutPriorityDefaultLow]; | |
40 cell.frame = CGRectMake(initialCellOrigin.x, initialCellOrigin.y, | |
41 result.width, result.height); | |
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)]; | |
msarda
2017/04/28 11:53:14
I would prefer CGFLOAT_MAX, CGFLOAT_MAX instead of
jlebel
2017/04/28 13:03:17
It is totally arbitrary. But it seems more reasona
lpromero
2017/05/02 15:25:20
CGFLOAT_MAX*CGFLOAT_MAX would have a large (huge!)
jlebel
2017/05/03 11:02:31
Done.
| |
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 |