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 |