| 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 #include "ios/chrome/browser/ui/authentication/signin_account_selector_view_cont
roller.h" | 5 #include "ios/chrome/browser/ui/authentication/signin_account_selector_view_cont
roller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #import "base/mac/foundation_util.h" | 9 #import "base/mac/foundation_util.h" |
| 10 #import "base/mac/scoped_nsobject.h" | |
| 11 #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h" | 10 #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h" |
| 12 #import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h" | 11 #import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h" |
| 13 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrom
e.h" | 12 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrom
e.h" |
| 14 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_ite
m.h" | 13 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_ite
m.h" |
| 15 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item
.h" | 14 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item
.h" |
| 16 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h
" | 15 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h
" |
| 17 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" | 16 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" |
| 18 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 17 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| 19 #include "ios/chrome/grit/ios_chromium_strings.h" | 18 #include "ios/chrome/grit/ios_chromium_strings.h" |
| 20 #include "ios/chrome/grit/ios_strings.h" | 19 #include "ios/chrome/grit/ios_strings.h" |
| 21 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" | 20 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
| 22 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" | 21 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" |
| 23 #include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h" | 22 #include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h" |
| 24 #import "ios/third_party/material_components_ios/src/components/AppBar/src/Mater
ialAppBar.h" | 23 #import "ios/third_party/material_components_ios/src/components/AppBar/src/Mater
ialAppBar.h" |
| 25 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat
erialPalettes.h" | 24 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat
erialPalettes.h" |
| 26 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 25 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
| 27 #import "ui/base/l10n/l10n_util.h" | 26 #import "ui/base/l10n/l10n_util.h" |
| 28 | 27 |
| 28 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 29 #error "This file requires ARC support." |
| 30 #endif |
| 31 |
| 29 namespace { | 32 namespace { |
| 30 const CGFloat kHeaderViewMinHeight = 100.; | 33 const CGFloat kHeaderViewMinHeight = 100.; |
| 31 const CGFloat kHeaderViewHeightMultiplier = 0.33; | 34 const CGFloat kHeaderViewHeightMultiplier = 0.33; |
| 32 const CGFloat kContentViewBottomInset = 40.; | 35 const CGFloat kContentViewBottomInset = 40.; |
| 33 | 36 |
| 34 typedef NS_ENUM(NSInteger, SectionIdentifier) { | 37 typedef NS_ENUM(NSInteger, SectionIdentifier) { |
| 35 SectionIdentifierTitle = kSectionIdentifierEnumZero, | 38 SectionIdentifierTitle = kSectionIdentifierEnumZero, |
| 36 SectionIdentifierAccounts, | 39 SectionIdentifierAccounts, |
| 37 SectionIdentifierAddAccount, | 40 SectionIdentifierAddAccount, |
| 38 }; | 41 }; |
| 39 | 42 |
| 40 typedef NS_ENUM(NSInteger, ItemType) { | 43 typedef NS_ENUM(NSInteger, ItemType) { |
| 41 ItemTypeTitle = kItemTypeEnumZero, | 44 ItemTypeTitle = kItemTypeEnumZero, |
| 42 ItemTypeAccount, | 45 ItemTypeAccount, |
| 43 ItemTypeAddAccount, | 46 ItemTypeAddAccount, |
| 44 }; | 47 }; |
| 45 } // namespace | 48 } // namespace |
| 46 | 49 |
| 47 @interface SigninAccountSelectorViewController ()< | 50 @interface SigninAccountSelectorViewController ()< |
| 48 ChromeIdentityServiceObserver> { | 51 ChromeIdentityServiceObserver> { |
| 49 std::unique_ptr<ChromeIdentityServiceObserverBridge> _identityServiceObserver; | 52 std::unique_ptr<ChromeIdentityServiceObserverBridge> _identityServiceObserver; |
| 50 // Cache for account avatar images. | 53 // Cache for account avatar images. |
| 51 base::scoped_nsobject<ResizedAvatarCache> _avatarCache; | 54 ResizedAvatarCache* _avatarCache; |
| 52 } | 55 } |
| 53 @end | 56 @end |
| 54 | 57 |
| 55 @implementation SigninAccountSelectorViewController | 58 @implementation SigninAccountSelectorViewController |
| 56 | 59 |
| 57 @synthesize delegate = _delegate; | 60 @synthesize delegate = _delegate; |
| 58 | 61 |
| 59 - (instancetype)init { | 62 - (instancetype)init { |
| 60 self = [super initWithStyle:CollectionViewControllerStyleAppBar]; | 63 self = [super initWithStyle:CollectionViewControllerStyleAppBar]; |
| 61 if (self) { | 64 if (self) { |
| 62 _identityServiceObserver.reset( | 65 _identityServiceObserver.reset( |
| 63 new ChromeIdentityServiceObserverBridge(self)); | 66 new ChromeIdentityServiceObserverBridge(self)); |
| 64 _avatarCache.reset([[ResizedAvatarCache alloc] init]); | 67 _avatarCache = [[ResizedAvatarCache alloc] init]; |
| 65 } | 68 } |
| 66 return self; | 69 return self; |
| 67 } | 70 } |
| 68 | 71 |
| 69 #pragma mark - UIViewController | 72 #pragma mark - UIViewController |
| 70 | 73 |
| 71 - (void)viewDidLoad { | 74 - (void)viewDidLoad { |
| 72 [super viewDidLoad]; | 75 [super viewDidLoad]; |
| 73 | 76 |
| 74 // Configure the header. | 77 // Configure the header. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 85 UIEdgeInsets contentInset = self.collectionView.contentInset; | 88 UIEdgeInsets contentInset = self.collectionView.contentInset; |
| 86 contentInset.bottom += kContentViewBottomInset; | 89 contentInset.bottom += kContentViewBottomInset; |
| 87 self.collectionView.contentInset = contentInset; | 90 self.collectionView.contentInset = contentInset; |
| 88 }]; | 91 }]; |
| 89 | 92 |
| 90 // Load the contents of the collection view. | 93 // Load the contents of the collection view. |
| 91 [self loadModel]; | 94 [self loadModel]; |
| 92 } | 95 } |
| 93 | 96 |
| 94 - (UIView*)contentViewWithFrame:(CGRect)frame { | 97 - (UIView*)contentViewWithFrame:(CGRect)frame { |
| 95 base::scoped_nsobject<UIView> contentView( | 98 UIView* contentView = [[UIView alloc] initWithFrame:frame]; |
| 96 [[UIView alloc] initWithFrame:frame]); | 99 contentView.autoresizingMask = |
| 97 contentView.get().autoresizingMask = | |
| 98 (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); | 100 (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); |
| 99 contentView.get().clipsToBounds = YES; | 101 contentView.clipsToBounds = YES; |
| 100 | 102 |
| 101 base::scoped_nsobject<UILabel> titleLabel( | 103 UILabel* titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; |
| 102 [[UILabel alloc] initWithFrame:CGRectZero]); | 104 titleLabel.text = |
| 103 titleLabel.get().text = | |
| 104 l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE); | 105 l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE); |
| 105 titleLabel.get().textColor = [[MDCPalette greyPalette] tint900]; | 106 titleLabel.textColor = [[MDCPalette greyPalette] tint900]; |
| 106 titleLabel.get().font = [MDCTypography headlineFont]; | 107 titleLabel.font = [MDCTypography headlineFont]; |
| 107 titleLabel.get().translatesAutoresizingMaskIntoConstraints = NO; | 108 titleLabel.translatesAutoresizingMaskIntoConstraints = NO; |
| 108 | 109 |
| 109 base::scoped_nsobject<UIView> divider( | 110 UIView* divider = [[UIView alloc] initWithFrame:CGRectZero]; |
| 110 [[UIView alloc] initWithFrame:CGRectZero]); | 111 divider.backgroundColor = [[MDCPalette greyPalette] tint300]; |
| 111 divider.get().backgroundColor = [[MDCPalette greyPalette] tint300]; | 112 divider.translatesAutoresizingMaskIntoConstraints = NO; |
| 112 divider.get().translatesAutoresizingMaskIntoConstraints = NO; | |
| 113 | 113 |
| 114 base::scoped_nsobject<UILayoutGuide> layoutGuide1( | 114 UILayoutGuide* layoutGuide1 = [[UILayoutGuide alloc] init]; |
| 115 [[UILayoutGuide alloc] init]); | 115 UILayoutGuide* layoutGuide2 = [[UILayoutGuide alloc] init]; |
| 116 base::scoped_nsobject<UILayoutGuide> layoutGuide2( | |
| 117 [[UILayoutGuide alloc] init]); | |
| 118 | 116 |
| 119 [contentView addSubview:titleLabel]; | 117 [contentView addSubview:titleLabel]; |
| 120 [contentView addSubview:divider]; | 118 [contentView addSubview:divider]; |
| 121 [contentView addLayoutGuide:layoutGuide1]; | 119 [contentView addLayoutGuide:layoutGuide1]; |
| 122 [contentView addLayoutGuide:layoutGuide2]; | 120 [contentView addLayoutGuide:layoutGuide2]; |
| 123 | 121 |
| 124 NSDictionary* views = @{ | 122 NSDictionary* views = @{ |
| 125 @"title" : titleLabel, | 123 @"title" : titleLabel, |
| 126 @"divider" : divider, | 124 @"divider" : divider, |
| 127 @"v1" : layoutGuide1, | 125 @"v1" : layoutGuide1, |
| 128 @"v2" : layoutGuide2 | 126 @"v2" : layoutGuide2 |
| 129 }; | 127 }; |
| 130 NSArray* constraints = @[ | 128 NSArray* constraints = @[ |
| 131 @"V:[title]-(16)-[divider(==1)]|", | 129 @"V:[title]-(16)-[divider(==1)]|", |
| 132 @"H:|[v1(16)][title(<=440)][v2(>=v1)]|", | 130 @"H:|[v1(16)][title(<=440)][v2(>=v1)]|", |
| 133 @"H:|[divider]|", | 131 @"H:|[divider]|", |
| 134 ]; | 132 ]; |
| 135 ApplyVisualConstraints(constraints, views); | 133 ApplyVisualConstraints(constraints, views); |
| 136 return contentView.autorelease(); | 134 return contentView = nil; |
| 137 } | 135 } |
| 138 | 136 |
| 139 - (void)viewWillLayoutSubviews { | 137 - (void)viewWillLayoutSubviews { |
| 140 CGSize viewSize = self.view.bounds.size; | 138 CGSize viewSize = self.view.bounds.size; |
| 141 MDCFlexibleHeaderView* headerView = | 139 MDCFlexibleHeaderView* headerView = |
| 142 self.appBar.headerViewController.headerView; | 140 self.appBar.headerViewController.headerView; |
| 143 headerView.maximumHeight = | 141 headerView.maximumHeight = |
| 144 MAX(kHeaderViewMinHeight, kHeaderViewHeightMultiplier * viewSize.height); | 142 MAX(kHeaderViewMinHeight, kHeaderViewHeightMultiplier * viewSize.height); |
| 145 } | 143 } |
| 146 | 144 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 164 toSectionWithIdentifier:SectionIdentifierAccounts]; | 162 toSectionWithIdentifier:SectionIdentifierAccounts]; |
| 165 } | 163 } |
| 166 [model addSectionWithIdentifier:SectionIdentifierAddAccount]; | 164 [model addSectionWithIdentifier:SectionIdentifierAddAccount]; |
| 167 [model addItem:[self addAccountItem] | 165 [model addItem:[self addAccountItem] |
| 168 toSectionWithIdentifier:SectionIdentifierAddAccount]; | 166 toSectionWithIdentifier:SectionIdentifierAddAccount]; |
| 169 } | 167 } |
| 170 } | 168 } |
| 171 | 169 |
| 172 - (CollectionViewItem*)titleItem { | 170 - (CollectionViewItem*)titleItem { |
| 173 // TODO(crbug.com/662549) : Rename FooterItem to be used as regular item. | 171 // TODO(crbug.com/662549) : Rename FooterItem to be used as regular item. |
| 174 CollectionViewFooterItem* item = [[[CollectionViewFooterItem alloc] | 172 CollectionViewFooterItem* item = |
| 175 initWithType:ItemTypeTitle] autorelease]; | 173 [[CollectionViewFooterItem alloc] initWithType:ItemTypeTitle]; |
| 176 item.text = | 174 item.text = |
| 177 l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_DESCRIPTION); | 175 l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_DESCRIPTION); |
| 178 return item; | 176 return item; |
| 179 } | 177 } |
| 180 | 178 |
| 181 - (CollectionViewItem*)accountItemForIdentity:(ChromeIdentity*)identity | 179 - (CollectionViewItem*)accountItemForIdentity:(ChromeIdentity*)identity |
| 182 checked:(BOOL)isChecked { | 180 checked:(BOOL)isChecked { |
| 183 CollectionViewAccountItem* item = [[[CollectionViewAccountItem alloc] | 181 CollectionViewAccountItem* item = |
| 184 initWithType:ItemTypeAccount] autorelease]; | 182 [[CollectionViewAccountItem alloc] initWithType:ItemTypeAccount]; |
| 185 [self updateAccountItem:item withIdentity:identity]; | 183 [self updateAccountItem:item withIdentity:identity]; |
| 186 if (isChecked) { | 184 if (isChecked) { |
| 187 item.accessoryType = MDCCollectionViewCellAccessoryCheckmark; | 185 item.accessoryType = MDCCollectionViewCellAccessoryCheckmark; |
| 188 } | 186 } |
| 189 return item; | 187 return item; |
| 190 } | 188 } |
| 191 | 189 |
| 192 - (void)updateAccountItem:(CollectionViewAccountItem*)item | 190 - (void)updateAccountItem:(CollectionViewAccountItem*)item |
| 193 withIdentity:(ChromeIdentity*)identity { | 191 withIdentity:(ChromeIdentity*)identity { |
| 194 item.image = [_avatarCache resizedAvatarForIdentity:identity]; | 192 item.image = [_avatarCache resizedAvatarForIdentity:identity]; |
| 195 item.text = identity.userEmail; | 193 item.text = identity.userEmail; |
| 196 item.chromeIdentity = identity; | 194 item.chromeIdentity = identity; |
| 197 } | 195 } |
| 198 | 196 |
| 199 - (CollectionViewItem*)addAccountItem { | 197 - (CollectionViewItem*)addAccountItem { |
| 200 CollectionViewAccountItem* item = [[[CollectionViewAccountItem alloc] | 198 CollectionViewAccountItem* item = |
| 201 initWithType:ItemTypeAddAccount] autorelease]; | 199 [[CollectionViewAccountItem alloc] initWithType:ItemTypeAddAccount]; |
| 202 item.text = l10n_util::GetNSString( | 200 item.text = l10n_util::GetNSString( |
| 203 IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_ADD_ACCOUNT_BUTTON); | 201 IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_ADD_ACCOUNT_BUTTON); |
| 204 item.image = [UIImage imageNamed:@"settings_accounts_add_account"]; | 202 item.image = [UIImage imageNamed:@"settings_accounts_add_account"]; |
| 205 return item; | 203 return item; |
| 206 } | 204 } |
| 207 | 205 |
| 208 - (ChromeIdentity*)selectedIdentity { | 206 - (ChromeIdentity*)selectedIdentity { |
| 209 NSArray* accountItems = [self.collectionViewModel | 207 NSArray* accountItems = [self.collectionViewModel |
| 210 itemsInSectionWithIdentifier:SectionIdentifierAccounts]; | 208 itemsInSectionWithIdentifier:SectionIdentifierAccounts]; |
| 211 for (CollectionViewAccountItem* accountItem in accountItems) { | 209 for (CollectionViewAccountItem* accountItem in accountItems) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 222 didSelectItemAtIndexPath:(NSIndexPath*)indexPath { | 220 didSelectItemAtIndexPath:(NSIndexPath*)indexPath { |
| 223 [super collectionView:collectionView didSelectItemAtIndexPath:indexPath]; | 221 [super collectionView:collectionView didSelectItemAtIndexPath:indexPath]; |
| 224 CollectionViewItem* item = | 222 CollectionViewItem* item = |
| 225 [self.collectionViewModel itemAtIndexPath:indexPath]; | 223 [self.collectionViewModel itemAtIndexPath:indexPath]; |
| 226 if (item.type == ItemTypeAccount) { | 224 if (item.type == ItemTypeAccount) { |
| 227 CollectionViewAccountItem* selectedAccountItem = | 225 CollectionViewAccountItem* selectedAccountItem = |
| 228 base::mac::ObjCCastStrict<CollectionViewAccountItem>(item); | 226 base::mac::ObjCCastStrict<CollectionViewAccountItem>(item); |
| 229 // TODO(crbug.com/631486) : Checkmark animation. | 227 // TODO(crbug.com/631486) : Checkmark animation. |
| 230 selectedAccountItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark; | 228 selectedAccountItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark; |
| 231 | 229 |
| 232 base::scoped_nsobject<NSMutableArray<CollectionViewItem*>> reloadItems( | 230 NSMutableArray<CollectionViewItem*>* reloadItems = |
| 233 [[NSMutableArray alloc] init]); | 231 [[NSMutableArray alloc] init]; |
| 234 [reloadItems addObject:selectedAccountItem]; | 232 [reloadItems addObject:selectedAccountItem]; |
| 235 | 233 |
| 236 // Uncheck all the other account items. | 234 // Uncheck all the other account items. |
| 237 NSArray* accountItems = [self.collectionViewModel | 235 NSArray* accountItems = [self.collectionViewModel |
| 238 itemsInSectionWithIdentifier:SectionIdentifierAccounts]; | 236 itemsInSectionWithIdentifier:SectionIdentifierAccounts]; |
| 239 for (CollectionViewAccountItem* accountItem in accountItems) { | 237 for (CollectionViewAccountItem* accountItem in accountItems) { |
| 240 if (accountItem != selectedAccountItem && | 238 if (accountItem != selectedAccountItem && |
| 241 accountItem.accessoryType != MDCCollectionViewCellAccessoryNone) { | 239 accountItem.accessoryType != MDCCollectionViewCellAccessoryNone) { |
| 242 // TODO(crbug.com/631486) : Checkmark animation. | 240 // TODO(crbug.com/631486) : Checkmark animation. |
| 243 accountItem.accessoryType = MDCCollectionViewCellAccessoryNone; | 241 accountItem.accessoryType = MDCCollectionViewCellAccessoryNone; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 [self.collectionViewModel itemTypeForIndexPath:indexPath]; | 321 [self.collectionViewModel itemTypeForIndexPath:indexPath]; |
| 324 return (itemType == ItemTypeTitle); | 322 return (itemType == ItemTypeTitle); |
| 325 } | 323 } |
| 326 | 324 |
| 327 - (BOOL)collectionView:(nonnull UICollectionView*)collectionView | 325 - (BOOL)collectionView:(nonnull UICollectionView*)collectionView |
| 328 shouldHideItemBackgroundAtIndexPath:(nonnull NSIndexPath*)indexPath { | 326 shouldHideItemBackgroundAtIndexPath:(nonnull NSIndexPath*)indexPath { |
| 329 return YES; | 327 return YES; |
| 330 } | 328 } |
| 331 | 329 |
| 332 @end | 330 @end |
| OLD | NEW |