Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.mm

Issue 2586993002: Upstream Chrome on iOS source code [3/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ios/chrome/browser/ui/authentication/signin_account_selector_view_cont roller.h"
6
7 #include <memory>
8
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"
12 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrom e.h"
13 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_ite m.h"
14 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item .h"
15 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h "
16 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
17 #import "ios/chrome/browser/ui/settings/utils/resized_avatar_cache.h"
18 #import "ios/chrome/browser/ui/uikit_ui_util.h"
19 #include "ios/chrome/grit/ios_chromium_strings.h"
20 #include "ios/chrome/grit/ios_strings.h"
21 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
22 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
23 #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"
25 #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"
27 #import "ui/base/l10n/l10n_util.h"
28
29 namespace {
30 const CGFloat kHeaderViewMinHeight = 100.;
31 const CGFloat kHeaderViewHeightMultiplier = 0.33;
32 const CGFloat kContentViewBottomInset = 40.;
33
34 typedef NS_ENUM(NSInteger, SectionIdentifier) {
35 SectionIdentifierTitle = kSectionIdentifierEnumZero,
36 SectionIdentifierAccounts,
37 SectionIdentifierAddAccount,
38 };
39
40 typedef NS_ENUM(NSInteger, ItemType) {
41 ItemTypeTitle = kItemTypeEnumZero,
42 ItemTypeAccount,
43 ItemTypeAddAccount,
44 };
45 } // namespace
46
47 @interface SigninAccountSelectorViewController ()<
48 ChromeIdentityServiceObserver> {
49 std::unique_ptr<ChromeIdentityServiceObserverBridge> _identityServiceObserver;
50 // Cache for account avatar images.
51 base::scoped_nsobject<ResizedAvatarCache> _avatarCache;
52 }
53 @end
54
55 @implementation SigninAccountSelectorViewController
56
57 @synthesize delegate = _delegate;
58
59 - (instancetype)init {
60 self = [super initWithStyle:CollectionViewControllerStyleAppBar];
61 if (self) {
62 _identityServiceObserver.reset(
63 new ChromeIdentityServiceObserverBridge(self));
64 _avatarCache.reset([[ResizedAvatarCache alloc] init]);
65 }
66 return self;
67 }
68
69 #pragma mark - UIViewController
70
71 - (void)viewDidLoad {
72 [super viewDidLoad];
73
74 // Configure the header.
75 MDCFlexibleHeaderView* headerView =
76 self.appBar.headerViewController.headerView;
77 headerView.canOverExtend = YES;
78 headerView.maximumHeight = 200;
79 headerView.backgroundColor = [UIColor whiteColor];
80 headerView.shiftBehavior = MDCFlexibleHeaderShiftBehaviorEnabled;
81 [headerView addSubview:[self contentViewWithFrame:headerView.bounds]];
82 self.appBar.navigationBar.hidesBackButton = YES;
83 self.collectionView.backgroundColor = [UIColor clearColor];
84 [headerView changeContentInsets:^{
85 UIEdgeInsets contentInset = self.collectionView.contentInset;
86 contentInset.bottom += kContentViewBottomInset;
87 self.collectionView.contentInset = contentInset;
88 }];
89
90 // Load the contents of the collection view.
91 [self loadModel];
92 }
93
94 - (UIView*)contentViewWithFrame:(CGRect)frame {
95 base::scoped_nsobject<UIView> contentView(
96 [[UIView alloc] initWithFrame:frame]);
97 contentView.get().autoresizingMask =
98 (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
99 contentView.get().clipsToBounds = YES;
100
101 base::scoped_nsobject<UILabel> titleLabel(
102 [[UILabel alloc] initWithFrame:CGRectZero]);
103 titleLabel.get().text =
104 l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE);
105 titleLabel.get().textColor = [[MDCPalette greyPalette] tint900];
106 titleLabel.get().font = [MDCTypography headlineFont];
107 titleLabel.get().translatesAutoresizingMaskIntoConstraints = NO;
108
109 base::scoped_nsobject<UIView> divider(
110 [[UIView alloc] initWithFrame:CGRectZero]);
111 divider.get().backgroundColor = [[MDCPalette greyPalette] tint300];
112 divider.get().translatesAutoresizingMaskIntoConstraints = NO;
113
114 base::scoped_nsobject<UILayoutGuide> layoutGuide1(
115 [[UILayoutGuide alloc] init]);
116 base::scoped_nsobject<UILayoutGuide> layoutGuide2(
117 [[UILayoutGuide alloc] init]);
118
119 [contentView addSubview:titleLabel];
120 [contentView addSubview:divider];
121 [contentView addLayoutGuide:layoutGuide1];
122 [contentView addLayoutGuide:layoutGuide2];
123
124 NSDictionary* views = @{
125 @"title" : titleLabel,
126 @"divider" : divider,
127 @"v1" : layoutGuide1,
128 @"v2" : layoutGuide2
129 };
130 NSArray* constraints = @[
131 @"V:[title]-(16)-[divider(==1)]|",
132 @"H:|[v1(16)][title(<=440)][v2(>=v1)]|",
133 @"H:|[divider]|",
134 ];
135 ApplyVisualConstraints(constraints, views);
136 return contentView.autorelease();
137 }
138
139 - (void)viewWillLayoutSubviews {
140 CGSize viewSize = self.view.bounds.size;
141 MDCFlexibleHeaderView* headerView =
142 self.appBar.headerViewController.headerView;
143 headerView.maximumHeight =
144 MAX(kHeaderViewMinHeight, kHeaderViewHeightMultiplier * viewSize.height);
145 }
146
147 #pragma mark - Model
148
149 - (void)loadModel {
150 [super loadModel];
151 CollectionViewModel* model = self.collectionViewModel;
152 [model addSectionWithIdentifier:SectionIdentifierTitle];
153 [model addItem:[self titleItem]
154 toSectionWithIdentifier:SectionIdentifierTitle];
155
156 [model addSectionWithIdentifier:SectionIdentifierAccounts];
157 NSArray* identities = ios::GetChromeBrowserProvider()
158 ->GetChromeIdentityService()
159 ->GetAllIdentitiesSortedForDisplay();
160 if ([identities count]) {
161 for (NSUInteger i = 0; i < [identities count]; ++i) {
162 [model addItem:[self accountItemForIdentity:identities[i]
163 checked:(i == 0)]
164 toSectionWithIdentifier:SectionIdentifierAccounts];
165 }
166 [model addSectionWithIdentifier:SectionIdentifierAddAccount];
167 [model addItem:[self addAccountItem]
168 toSectionWithIdentifier:SectionIdentifierAddAccount];
169 }
170 }
171
172 - (CollectionViewItem*)titleItem {
173 // TODO(crbug.com/662549) : Rename FooterItem to be used as regular item.
174 CollectionViewFooterItem* item = [[[CollectionViewFooterItem alloc]
175 initWithType:ItemTypeTitle] autorelease];
176 item.text =
177 l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_DESCRIPTION);
178 return item;
179 }
180
181 - (CollectionViewItem*)accountItemForIdentity:(ChromeIdentity*)identity
182 checked:(BOOL)isChecked {
183 CollectionViewAccountItem* item = [[[CollectionViewAccountItem alloc]
184 initWithType:ItemTypeAccount] autorelease];
185 [self updateAccountItem:item withIdentity:identity];
186 if (isChecked) {
187 item.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
188 }
189 return item;
190 }
191
192 - (void)updateAccountItem:(CollectionViewAccountItem*)item
193 withIdentity:(ChromeIdentity*)identity {
194 item.image = [_avatarCache resizedAvatarForIdentity:identity];
195 item.text = identity.userEmail;
196 item.chromeIdentity = identity;
197 }
198
199 - (CollectionViewItem*)addAccountItem {
200 CollectionViewAccountItem* item = [[[CollectionViewAccountItem alloc]
201 initWithType:ItemTypeAddAccount] autorelease];
202 item.text = l10n_util::GetNSString(
203 IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_ADD_ACCOUNT_BUTTON);
204 item.image = [UIImage imageNamed:@"settings_accounts_add_account"];
205 return item;
206 }
207
208 - (ChromeIdentity*)selectedIdentity {
209 NSArray* accountItems = [self.collectionViewModel
210 itemsInSectionWithIdentifier:SectionIdentifierAccounts];
211 for (CollectionViewAccountItem* accountItem in accountItems) {
212 if (accountItem.accessoryType == MDCCollectionViewCellAccessoryCheckmark) {
213 return accountItem.chromeIdentity;
214 }
215 }
216 return nil;
217 }
218
219 #pragma mark - UICollectionViewDelegate
220
221 - (void)collectionView:(UICollectionView*)collectionView
222 didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
223 [super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
224 CollectionViewItem* item =
225 [self.collectionViewModel itemAtIndexPath:indexPath];
226 if (item.type == ItemTypeAccount) {
227 CollectionViewAccountItem* selectedAccountItem =
228 base::mac::ObjCCastStrict<CollectionViewAccountItem>(item);
229 // TODO(crbug.com/631486) : Checkmark animation.
230 selectedAccountItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
231
232 base::scoped_nsobject<NSMutableArray<CollectionViewItem*>> reloadItems(
233 [[NSMutableArray alloc] init]);
234 [reloadItems addObject:selectedAccountItem];
235
236 // Uncheck all the other account items.
237 NSArray* accountItems = [self.collectionViewModel
238 itemsInSectionWithIdentifier:SectionIdentifierAccounts];
239 for (CollectionViewAccountItem* accountItem in accountItems) {
240 if (accountItem != selectedAccountItem &&
241 accountItem.accessoryType != MDCCollectionViewCellAccessoryNone) {
242 // TODO(crbug.com/631486) : Checkmark animation.
243 accountItem.accessoryType = MDCCollectionViewCellAccessoryNone;
244 [reloadItems addObject:accountItem];
245 }
246 }
247 [self reconfigureCellsForItems:reloadItems
248 inSectionWithIdentifier:SectionIdentifierAccounts];
249 } else if (item.type == ItemTypeAddAccount) {
250 [self.delegate accountSelectorControllerDidSelectAddAccount:self];
251 }
252 }
253
254 #pragma mark - ChromeIdentityServiceObserver
255
256 - (void)onIdentityListChanged {
257 ChromeIdentity* selectedIdentity = [self selectedIdentity];
258 [self loadModel];
259
260 // Reselect the identity.
261 if (!selectedIdentity) {
262 return;
263 }
264 NSArray* accountItems = [self.collectionViewModel
265 itemsInSectionWithIdentifier:SectionIdentifierAccounts];
266 for (CollectionViewAccountItem* accountItem in accountItems) {
267 if ([accountItem.chromeIdentity.gaiaID
268 isEqualToString:selectedIdentity.gaiaID]) {
269 accountItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
270 } else {
271 accountItem.accessoryType = MDCCollectionViewCellAccessoryNone;
272 }
273 }
274 }
275
276 - (void)onChromeIdentityServiceWillBeDestroyed {
277 _identityServiceObserver.reset();
278 }
279
280 #pragma mark UICollectionViewDataSource
281
282 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
283 cellForItemAtIndexPath:(NSIndexPath*)indexPath {
284 MDCCollectionViewCell* cell =
285 [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
286 CollectionViewItem* item =
287 [self.collectionViewModel itemAtIndexPath:indexPath];
288
289 if (item.type == ItemTypeAccount || item.type == ItemTypeAddAccount) {
290 CollectionViewAccountCell* accountCell =
291 base::mac::ObjCCastStrict<CollectionViewAccountCell>(cell);
292 accountCell.textLabel.font = [MDCTypography body1Font];
293 accountCell.textLabel.textColor = [[MDCPalette greyPalette] tint900];
294 } else if (item.type == ItemTypeTitle) {
295 CollectionViewFooterCell* titleCell =
296 base::mac::ObjCCastStrict<CollectionViewFooterCell>(cell);
297 titleCell.textLabel.font = [MDCTypography body1Font];
298 titleCell.textLabel.textColor = [[MDCPalette greyPalette] tint900];
299 titleCell.horizontalPadding = 16;
300 }
301 cell.shouldHideSeparator = YES;
302 return cell;
303 }
304
305 #pragma mark - MDCCollectionViewStylingDelegate
306
307 - (CGFloat)collectionView:(UICollectionView*)collectionView
308 cellHeightAtIndexPath:(NSIndexPath*)indexPath {
309 CollectionViewItem* item =
310 [self.collectionViewModel itemAtIndexPath:indexPath];
311
312 if (item.type == ItemTypeTitle) {
313 return [MDCCollectionViewCell
314 cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
315 forItem:item];
316 }
317 return MDCCellDefaultTwoLineHeight;
318 }
319
320 - (BOOL)collectionView:(UICollectionView*)collectionView
321 hidesInkViewAtIndexPath:(NSIndexPath*)indexPath {
322 NSInteger itemType =
323 [self.collectionViewModel itemTypeForIndexPath:indexPath];
324 return (itemType == ItemTypeTitle);
325 }
326
327 - (BOOL)collectionView:(nonnull UICollectionView*)collectionView
328 shouldHideItemBackgroundAtIndexPath:(nonnull NSIndexPath*)indexPath {
329 return YES;
330 }
331
332 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698