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

Side by Side Diff: ios/chrome/browser/ui/payments/payment_request_view_controller.mm

Issue 2924663003: [Payment Request] Moves PaymentRequestViewController to :payments_ui (Closed)
Patch Set: Addressed comments Created 3 years, 6 months 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
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 #import "ios/chrome/browser/ui/payments/payment_request_view_controller.h" 5 #import "ios/chrome/browser/ui/payments/payment_request_view_controller.h"
6 6
7 #include "base/mac/foundation_util.h" 7 #include "base/mac/foundation_util.h"
8 8
9 #include "base/strings/sys_string_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "components/autofill/core/browser/autofill_data_util.h"
12 #include "components/autofill/core/browser/autofill_profile.h"
13 #include "components/autofill/core/browser/credit_card.h"
14 #include "components/autofill/core/browser/field_types.h"
15 #include "components/autofill/core/browser/personal_data_manager.h"
16 #include "components/payments/core/currency_formatter.h"
17 #include "components/payments/core/strings_util.h"
18 #include "components/strings/grit/components_strings.h" 9 #include "components/strings/grit/components_strings.h"
19 #include "ios/chrome/browser/payments/payment_request.h"
20 #import "ios/chrome/browser/payments/payment_request_util.h"
21 #import "ios/chrome/browser/ui/autofill/cells/status_item.h" 10 #import "ios/chrome/browser/ui/autofill/cells/status_item.h"
22 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrom e.h" 11 #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrom e.h"
23 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item .h" 12 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item .h"
24 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item .h" 13 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item .h"
14 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item+collec tion_view_controller.h"
25 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" 15 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
26 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" 16 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
27 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" 17 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
28 #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h"
29 #import "ios/chrome/browser/ui/payments/cells/page_info_item.h" 18 #import "ios/chrome/browser/ui/payments/cells/page_info_item.h"
30 #import "ios/chrome/browser/ui/payments/cells/payment_method_item.h"
31 #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h"
32 #import "ios/chrome/browser/ui/payments/cells/price_item.h" 19 #import "ios/chrome/browser/ui/payments/cells/price_item.h"
33 #import "ios/chrome/browser/ui/payments/payment_request_view_controller_actions. h" 20 #import "ios/chrome/browser/ui/payments/payment_request_view_controller_actions. h"
34 #include "ios/chrome/browser/ui/rtl_geometry.h" 21 #include "ios/chrome/browser/ui/rtl_geometry.h"
35 #include "ios/chrome/browser/ui/uikit_ui_util.h" 22 #include "ios/chrome/browser/ui/uikit_ui_util.h"
36 #include "ios/chrome/grit/ios_strings.h" 23 #include "ios/chrome/grit/ios_strings.h"
37 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate rialButtons.h" 24 #import "ios/third_party/material_components_ios/src/components/Buttons/src/Mate rialButtons.h"
38 #import "ios/third_party/material_components_ios/src/components/CollectionCells/ src/MaterialCollectionCells.h"
39 #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"
40 #include "ios/web/public/payments/payment_request.h"
41 #include "ui/base/l10n/l10n_util.h" 26 #include "ui/base/l10n/l10n_util.h"
42 #include "ui/base/resource/resource_bundle.h"
43 27
44 #if !defined(__has_feature) || !__has_feature(objc_arc) 28 #if !defined(__has_feature) || !__has_feature(objc_arc)
45 #error "This file requires ARC support." 29 #error "This file requires ARC support."
46 #endif 30 #endif
47 31
48 namespace {
49 using ::payment_request_util::GetNameLabelFromAutofillProfile;
50 using ::payment_request_util::GetShippingAddressLabelFromAutofillProfile;
51 using ::payment_request_util::GetPhoneNumberLabelFromAutofillProfile;
52 using ::payment_request_util::GetEmailLabelFromAutofillProfile;
53 using ::payment_request_util::GetShippingSectionTitle;
54 using ::payments::GetShippingOptionSectionString;
55 using ::payments::GetShippingAddressSectionString;
56
57 // String used as the "URL" to take the user to the settings page for card and
58 // address options. Needs to be URL-like; otherwise, the link will not appear
59 // as a link in the UI (see setLabelLinkURL: in CollectionViewFooterCell).
60 const char kSettingsURL[] = "settings://card-and-address";
61
62 const CGFloat kFooterCellHorizontalPadding = 16;
63
64 } // namespace
65
66 NSString* const kPaymentRequestCollectionViewID = 32 NSString* const kPaymentRequestCollectionViewID =
67 @"kPaymentRequestCollectionViewID"; 33 @"kPaymentRequestCollectionViewID";
68 34
69 namespace { 35 namespace {
36 const CGFloat kFooterCellHorizontalPadding = 16;
70 37
71 const CGFloat kButtonEdgeInset = 9; 38 const CGFloat kButtonEdgeInset = 9;
72 const CGFloat kSeparatorEdgeInset = 14; 39 const CGFloat kSeparatorEdgeInset = 14;
73 40
74 typedef NS_ENUM(NSInteger, SectionIdentifier) { 41 typedef NS_ENUM(NSInteger, SectionIdentifier) {
75 SectionIdentifierSummary = kSectionIdentifierEnumZero, 42 SectionIdentifierSummary = kSectionIdentifierEnumZero,
76 SectionIdentifierShipping, 43 SectionIdentifierShipping,
77 SectionIdentifierPayment, 44 SectionIdentifierPayment,
78 SectionIdentifierContactInfo, 45 SectionIdentifierContactInfo,
79 SectionIdentifierFooter, 46 SectionIdentifierFooter,
80 }; 47 };
81 48
82 typedef NS_ENUM(NSInteger, ItemType) { 49 typedef NS_ENUM(NSInteger, ItemType) {
83 ItemTypeSummaryPageInfo = kItemTypeEnumZero, 50 ItemTypeSummaryPageInfo = kItemTypeEnumZero,
84 ItemTypeSpinner, 51 ItemTypeSpinner,
85 ItemTypeSummaryTotal, 52 ItemTypeSummaryTotal,
86 ItemTypeShippingTitle, 53 ItemTypeShippingTitle,
87 ItemTypeShippingAddress, 54 ItemTypeShippingAddress,
88 ItemTypeAddShippingAddress,
89 ItemTypeShippingOption, 55 ItemTypeShippingOption,
90 ItemTypeSelectShippingOption, 56 ItemTypePaymentHeader,
91 ItemTypePaymentTitle,
92 ItemTypePaymentMethod, 57 ItemTypePaymentMethod,
93 ItemTypeAddPaymentMethod, 58 ItemTypeContactInfoHeader,
94 ItemTypeContactInfoTitle,
95 ItemTypeContactInfo, 59 ItemTypeContactInfo,
96 ItemTypeAddContactInfo,
97 ItemTypeFooterText, 60 ItemTypeFooterText,
98 }; 61 };
99 62
100 } // namespace 63 } // namespace
101 64
102 @interface PaymentRequestViewController ()< 65 @interface PaymentRequestViewController ()<
66 CollectionViewFooterLinkDelegate,
103 PaymentRequestViewControllerActions> { 67 PaymentRequestViewControllerActions> {
104 UIBarButtonItem* _cancelButton; 68 UIBarButtonItem* _cancelButton;
105 MDCButton* _payButton; 69 MDCButton* _payButton;
106
107 // The PaymentRequest object having a copy of web::PaymentRequest as provided
108 // by the page invoking the Payment Request API. This is a weak pointer and
109 // should outlive this class.
110 PaymentRequest* _paymentRequest;
111
112 __weak PriceItem* _paymentSummaryItem;
113 __weak AutofillProfileItem* _selectedShippingAddressItem;
114 __weak PaymentsTextItem* _selectedShippingOptionItem;
115 __weak PaymentMethodItem* _selectedPaymentMethodItem;
116 __weak AutofillProfileItem* _selectedContactInfoItem;
117 } 70 }
118 71
119 @end 72 @end
120 73
121 @implementation PaymentRequestViewController 74 @implementation PaymentRequestViewController
122 75
123 @synthesize pageFavicon = _pageFavicon; 76 @synthesize pageFavicon = _pageFavicon;
124 @synthesize pageTitle = _pageTitle; 77 @synthesize pageTitle = _pageTitle;
125 @synthesize pageHost = _pageHost; 78 @synthesize pageHost = _pageHost;
126 @synthesize connectionSecure = _connectionSecure; 79 @synthesize connectionSecure = _connectionSecure;
127 @synthesize pending = _pending; 80 @synthesize pending = _pending;
128 @synthesize delegate = _delegate; 81 @synthesize delegate = _delegate;
129 @synthesize showPaymentDataSource = _showPaymentDataSource;
130 @synthesize dataSource = _dataSource; 82 @synthesize dataSource = _dataSource;
131 83
132 - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest { 84 - (instancetype)init {
133 DCHECK(paymentRequest);
134 if ((self = [super initWithStyle:CollectionViewControllerStyleAppBar])) { 85 if ((self = [super initWithStyle:CollectionViewControllerStyleAppBar])) {
135 [self setTitle:l10n_util::GetNSString(IDS_PAYMENTS_TITLE)]; 86 [self setTitle:l10n_util::GetNSString(IDS_PAYMENTS_TITLE)];
136 87
137 // Set up leading (cancel) button. 88 // Set up leading (cancel) button.
138 _cancelButton = [[UIBarButtonItem alloc] 89 _cancelButton = [[UIBarButtonItem alloc]
139 initWithTitle:l10n_util::GetNSString(IDS_CANCEL) 90 initWithTitle:l10n_util::GetNSString(IDS_CANCEL)
140 style:UIBarButtonItemStylePlain 91 style:UIBarButtonItemStylePlain
141 target:nil 92 target:nil
142 action:@selector(onCancel)]; 93 action:@selector(onCancel)];
143 [_cancelButton setTitleTextAttributes:@{ 94 [_cancelButton setTitleTextAttributes:@{
144 NSForegroundColorAttributeName : [UIColor lightGrayColor] 95 NSForegroundColorAttributeName : [UIColor lightGrayColor]
145 } 96 }
146 forState:UIControlStateDisabled]; 97 forState:UIControlStateDisabled];
147 [_cancelButton 98 [_cancelButton
148 setAccessibilityLabel:l10n_util::GetNSString(IDS_ACCNAME_CANCEL)]; 99 setAccessibilityLabel:l10n_util::GetNSString(IDS_ACCNAME_CANCEL)];
149 [self navigationItem].leftBarButtonItem = _cancelButton; 100 [self navigationItem].leftBarButtonItem = _cancelButton;
150 101
151 // Set up trailing (pay) button. 102 // Set up trailing (pay) button.
152 _payButton = [[MDCButton alloc] init]; 103 _payButton = [[MDCButton alloc] init];
153 [_payButton setTitle:l10n_util::GetNSString(IDS_PAYMENTS_PAY_BUTTON) 104 [_payButton setTitle:l10n_util::GetNSString(IDS_PAYMENTS_PAY_BUTTON)
154 forState:UIControlStateNormal]; 105 forState:UIControlStateNormal];
155 [_payButton setCustomTitleColor:[UIColor whiteColor]]; 106 [_payButton setCustomTitleColor:[UIColor whiteColor]];
156 [_payButton setInkColor:[UIColor colorWithWhite:1 alpha:0.2]]; 107 [_payButton setInkColor:[UIColor colorWithWhite:1 alpha:0.2]];
157 [_payButton addTarget:self 108 [_payButton addTarget:self
158 action:@selector(onConfirm) 109 action:@selector(onConfirm)
159 forControlEvents:UIControlEventTouchUpInside]; 110 forControlEvents:UIControlEventTouchUpInside];
160 [_payButton sizeToFit]; 111 [_payButton sizeToFit];
161 [_payButton setEnabled:(paymentRequest->selected_credit_card() != nil)];
162 [_payButton setAutoresizingMask:UIViewAutoresizingFlexibleTrailingMargin() | 112 [_payButton setAutoresizingMask:UIViewAutoresizingFlexibleTrailingMargin() |
163 UIViewAutoresizingFlexibleTopMargin | 113 UIViewAutoresizingFlexibleTopMargin |
164 UIViewAutoresizingFlexibleBottomMargin]; 114 UIViewAutoresizingFlexibleBottomMargin];
165 115
166 // The navigation bar will set the rightBarButtonItem's height to the full 116 // The navigation bar will set the rightBarButtonItem's height to the full
167 // height of the bar. We don't want that for the button so we use a UIView 117 // height of the bar. We don't want that for the button so we use a UIView
168 // here to contain the button instead and the button is vertically centered 118 // here to contain the button instead and the button is vertically centered
169 // inside the full bar height. 119 // inside the full bar height.
170 UIView* buttonView = [[UIView alloc] initWithFrame:CGRectZero]; 120 UIView* buttonView = [[UIView alloc] initWithFrame:CGRectZero];
171 [buttonView addSubview:_payButton]; 121 [buttonView addSubview:_payButton];
172 // Navigation bar button items are aligned with the trailing edge of the 122 // Navigation bar button items are aligned with the trailing edge of the
173 // screen. Make the enclosing view larger here. The pay button will be 123 // screen. Make the enclosing view larger here. The pay button will be
174 // aligned with the leading edge of the enclosing view leaving an inset on 124 // aligned with the leading edge of the enclosing view leaving an inset on
175 // the trailing edge. 125 // the trailing edge.
176 CGRect buttonViewBounds = buttonView.bounds; 126 CGRect buttonViewBounds = buttonView.bounds;
177 buttonViewBounds.size.width = 127 buttonViewBounds.size.width =
178 [_payButton frame].size.width + kButtonEdgeInset; 128 [_payButton frame].size.width + kButtonEdgeInset;
179 buttonView.bounds = buttonViewBounds; 129 buttonView.bounds = buttonViewBounds;
180 130
181 UIBarButtonItem* payButtonItem = 131 UIBarButtonItem* payButtonItem =
182 [[UIBarButtonItem alloc] initWithCustomView:buttonView]; 132 [[UIBarButtonItem alloc] initWithCustomView:buttonView];
183 [self navigationItem].rightBarButtonItem = payButtonItem; 133 [self navigationItem].rightBarButtonItem = payButtonItem;
184
185 _paymentRequest = paymentRequest;
186
187 // By default, data source is shown.
188 _showPaymentDataSource = TRUE;
189 } 134 }
190 return self; 135 return self;
191 } 136 }
192 137
193 - (void)onCancel { 138 - (void)onCancel {
194 [_delegate paymentRequestViewControllerDidCancel:self]; 139 [_delegate paymentRequestViewControllerDidCancel:self];
195 } 140 }
196 141
197 - (void)onConfirm { 142 - (void)onConfirm {
198 [_delegate paymentRequestViewControllerDidConfirm:self]; 143 [_delegate paymentRequestViewControllerDidConfirm:self];
199 } 144 }
200 145
146 #pragma mark - Setters
147
148 - (void)setDataSource:(id<PaymentRequestViewControllerDataSource>)dataSource {
149 _dataSource = dataSource;
150 [_payButton setEnabled:[_dataSource canPay]];
151 }
152
201 #pragma mark - CollectionViewController methods 153 #pragma mark - CollectionViewController methods
202 154
203 - (void)loadModel { 155 - (void)loadModel {
204 [super loadModel]; 156 [super loadModel];
205 CollectionViewModel* model = self.collectionViewModel; 157 CollectionViewModel* model = self.collectionViewModel;
206 158
207 // Summary section. 159 // Summary section.
208 [model addSectionWithIdentifier:SectionIdentifierSummary]; 160 [model addSectionWithIdentifier:SectionIdentifierSummary];
209 161
210 PageInfoItem* pageInfo = 162 PageInfoItem* pageInfo =
211 [[PageInfoItem alloc] initWithType:ItemTypeSummaryPageInfo]; 163 [[PageInfoItem alloc] initWithType:ItemTypeSummaryPageInfo];
212 pageInfo.pageFavicon = _pageFavicon; 164 pageInfo.pageFavicon = _pageFavicon;
213 pageInfo.pageTitle = _pageTitle; 165 pageInfo.pageTitle = _pageTitle;
214 pageInfo.pageHost = _pageHost; 166 pageInfo.pageHost = _pageHost;
215 pageInfo.connectionSecure = _connectionSecure; 167 pageInfo.connectionSecure = _connectionSecure;
216 [model setHeader:pageInfo forSectionWithIdentifier:SectionIdentifierSummary]; 168 [model setHeader:pageInfo forSectionWithIdentifier:SectionIdentifierSummary];
217 169
218 if (_pending) { 170 if (_pending) {
219 [_payButton setEnabled:NO]; 171 [_payButton setEnabled:NO];
220 [_cancelButton setEnabled:NO]; 172 [_cancelButton setEnabled:NO];
221 173
222 StatusItem* statusItem = [[StatusItem alloc] initWithType:ItemTypeSpinner]; 174 StatusItem* statusItem = [[StatusItem alloc] initWithType:ItemTypeSpinner];
223 statusItem.text = l10n_util::GetNSString(IDS_PAYMENTS_PROCESSING_MESSAGE); 175 statusItem.text = l10n_util::GetNSString(IDS_PAYMENTS_PROCESSING_MESSAGE);
224 [model addItem:statusItem toSectionWithIdentifier:SectionIdentifierSummary]; 176 [model addItem:statusItem toSectionWithIdentifier:SectionIdentifierSummary];
225 return; 177 return;
226 } 178 }
227 179
228 PriceItem* paymentSummaryItem = 180 [self addPaymentSummaryItem];
229 [[PriceItem alloc] initWithType:ItemTypeSummaryTotal];
230 _paymentSummaryItem = paymentSummaryItem;
231 [self fillPaymentSummaryItem:paymentSummaryItem
232 withPaymentItem:_paymentRequest->payment_details().total
233 withTotalValueChanged:NO];
234 if (!_paymentRequest->payment_details().display_items.empty()) {
235 paymentSummaryItem.accessoryType =
236 MDCCollectionViewCellAccessoryDisclosureIndicator;
237 paymentSummaryItem.accessibilityTraits |= UIAccessibilityTraitButton;
238 }
239 [model addItem:paymentSummaryItem
240 toSectionWithIdentifier:SectionIdentifierSummary];
241 181
242 // Shipping section. 182 // Shipping section.
243 [model addSectionWithIdentifier:SectionIdentifierShipping]; 183 if ([_dataSource requestShipping]) {
184 [model addSectionWithIdentifier:SectionIdentifierShipping];
244 185
245 PaymentsTextItem* shippingTitle = 186 CollectionViewItem* shippingSectionHeaderItem =
246 [[PaymentsTextItem alloc] initWithType:ItemTypeShippingTitle]; 187 [_dataSource shippingSectionHeaderItem];
247 shippingTitle.text = 188 [shippingSectionHeaderItem setType:ItemTypeShippingTitle];
248 GetShippingSectionTitle(_paymentRequest->shipping_type()); 189 [model setHeader:shippingSectionHeaderItem
249 [model setHeader:shippingTitle 190 forSectionWithIdentifier:SectionIdentifierShipping];
250 forSectionWithIdentifier:SectionIdentifierShipping];
251 191
252 CollectionViewItem* shippingAddressItem = nil; 192 [self populateShippingSection];
253 if (_paymentRequest->selected_shipping_profile()) {
254 AutofillProfileItem* selectedShippingAddressItem =
255 [[AutofillProfileItem alloc] initWithType:ItemTypeShippingAddress];
256 shippingAddressItem = selectedShippingAddressItem;
257 _selectedShippingAddressItem = selectedShippingAddressItem;
258 [self fillShippingAddressItem:selectedShippingAddressItem
259 withAutofillProfile:_paymentRequest->selected_shipping_profile()];
260 selectedShippingAddressItem.accessoryType =
261 MDCCollectionViewCellAccessoryDisclosureIndicator;
262 selectedShippingAddressItem.accessibilityTraits |=
263 UIAccessibilityTraitButton;
264 } else {
265 CollectionViewDetailItem* addAddressItem = [[CollectionViewDetailItem alloc]
266 initWithType:ItemTypeAddShippingAddress];
267 shippingAddressItem = addAddressItem;
268 addAddressItem.text = SysUTF16ToNSString(
269 GetShippingAddressSectionString(_paymentRequest->shipping_type()));
270 addAddressItem.detailText = [l10n_util::GetNSString(IDS_ADD)
271 uppercaseStringWithLocale:[NSLocale currentLocale]];
272 addAddressItem.accessibilityTraits |= UIAccessibilityTraitButton;
273 } 193 }
274 [model addItem:shippingAddressItem
275 toSectionWithIdentifier:SectionIdentifierShipping];
276
277 CollectionViewItem* shippingOptionItem = nil;
278 if (_paymentRequest->selected_shipping_option()) {
279 PaymentsTextItem* selectedShippingOptionItem =
280 [[PaymentsTextItem alloc] initWithType:ItemTypeShippingOption];
281 shippingOptionItem = selectedShippingOptionItem;
282
283 _selectedShippingOptionItem = selectedShippingOptionItem;
284 [self fillShippingOptionItem:selectedShippingOptionItem
285 withOption:_paymentRequest->selected_shipping_option()];
286 selectedShippingOptionItem.accessoryType =
287 MDCCollectionViewCellAccessoryDisclosureIndicator;
288 selectedShippingOptionItem.accessibilityTraits |=
289 UIAccessibilityTraitButton;
290 } else {
291 CollectionViewDetailItem* selectShippingOptionItem =
292 [[CollectionViewDetailItem alloc]
293 initWithType:ItemTypeSelectShippingOption];
294 shippingOptionItem = selectShippingOptionItem;
295 selectShippingOptionItem.text = base::SysUTF16ToNSString(
296 GetShippingOptionSectionString(_paymentRequest->shipping_type()));
297 selectShippingOptionItem.accessoryType =
298 MDCCollectionViewCellAccessoryDisclosureIndicator;
299 selectShippingOptionItem.accessibilityTraits |= UIAccessibilityTraitButton;
300 }
301 [model addItem:shippingOptionItem
302 toSectionWithIdentifier:SectionIdentifierShipping];
303 194
304 // Payment method section. 195 // Payment method section.
305 [model addSectionWithIdentifier:SectionIdentifierPayment]; 196 [model addSectionWithIdentifier:SectionIdentifierPayment];
306 197 [self populatePaymentMethodSection];
307 CollectionViewItem* paymentMethodItem = nil;
308 if (_paymentRequest->selected_credit_card()) {
309 PaymentsTextItem* paymentTitle =
310 [[PaymentsTextItem alloc] initWithType:ItemTypePaymentTitle];
311 paymentTitle.text =
312 l10n_util::GetNSString(IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME);
313 [model setHeader:paymentTitle
314 forSectionWithIdentifier:SectionIdentifierPayment];
315
316 PaymentMethodItem* selectedPaymentMethodItem =
317 [[PaymentMethodItem alloc] initWithType:ItemTypePaymentMethod];
318 paymentMethodItem = selectedPaymentMethodItem;
319 _selectedPaymentMethodItem = selectedPaymentMethodItem;
320 [self fillPaymentMethodItem:selectedPaymentMethodItem
321 withCreditCard:_paymentRequest->selected_credit_card()];
322 selectedPaymentMethodItem.accessoryType =
323 MDCCollectionViewCellAccessoryDisclosureIndicator;
324 selectedPaymentMethodItem.accessibilityTraits |= UIAccessibilityTraitButton;
325 } else {
326 CollectionViewDetailItem* addPaymentMethodItem = [
327 [CollectionViewDetailItem alloc] initWithType:ItemTypeAddPaymentMethod];
328 paymentMethodItem = addPaymentMethodItem;
329 addPaymentMethodItem.text =
330 l10n_util::GetNSString(IDS_PAYMENT_REQUEST_PAYMENT_METHOD_SECTION_NAME);
331 addPaymentMethodItem.detailText = [l10n_util::GetNSString(IDS_ADD)
332 uppercaseStringWithLocale:[NSLocale currentLocale]];
333 addPaymentMethodItem.accessibilityTraits |= UIAccessibilityTraitButton;
334 }
335 [model addItem:paymentMethodItem
336 toSectionWithIdentifier:SectionIdentifierPayment];
337 198
338 // Contact Info section. 199 // Contact Info section.
339 [model addSectionWithIdentifier:SectionIdentifierContactInfo]; 200 if ([_dataSource requestContactInfo]) {
340 201 [model addSectionWithIdentifier:SectionIdentifierContactInfo];
341 CollectionViewItem* contactInfoItem = nil; 202 [self populateContactInfoSection];
342 if (_paymentRequest->selected_contact_profile()) {
343 PaymentsTextItem* contactInfoTitle =
344 [[PaymentsTextItem alloc] initWithType:ItemTypeContactInfoTitle];
345 contactInfoTitle.text =
346 l10n_util::GetNSString(IDS_PAYMENTS_CONTACT_DETAILS_LABEL);
347 [model setHeader:contactInfoTitle
348 forSectionWithIdentifier:SectionIdentifierContactInfo];
349
350 AutofillProfileItem* selectedContactInfoItem =
351 [[AutofillProfileItem alloc] initWithType:ItemTypeContactInfo];
352 contactInfoItem = selectedContactInfoItem;
353 _selectedContactInfoItem = selectedContactInfoItem;
354 [self fillContactInfoItem:selectedContactInfoItem
355 withAutofillProfile:_paymentRequest->selected_contact_profile()];
356 selectedContactInfoItem.accessoryType =
357 MDCCollectionViewCellAccessoryDisclosureIndicator;
358
359 } else {
360 CollectionViewDetailItem* addContactInfoItem =
361 [[CollectionViewDetailItem alloc] initWithType:ItemTypeAddContactInfo];
362 contactInfoItem = addContactInfoItem;
363 addContactInfoItem.text =
364 l10n_util::GetNSString(IDS_PAYMENTS_CONTACT_DETAILS_LABEL);
365 addContactInfoItem.detailText = [l10n_util::GetNSString(IDS_ADD)
366 uppercaseStringWithLocale:[NSLocale currentLocale]];
367 addContactInfoItem.accessibilityTraits |= UIAccessibilityTraitButton;
368 } 203 }
369 [model addItem:contactInfoItem
370 toSectionWithIdentifier:SectionIdentifierContactInfo];
371 204
372 // Footer Text section. 205 // Footer Text section.
373 [model addSectionWithIdentifier:SectionIdentifierFooter]; 206 [model addSectionWithIdentifier:SectionIdentifierFooter];
374 CollectionViewFooterItem* footer = 207
375 [[CollectionViewFooterItem alloc] initWithType:ItemTypeFooterText]; 208 CollectionViewFooterItem* footerItem = [_dataSource footerItem];
376 if (!_showPaymentDataSource) { 209 [footerItem setType:ItemTypeFooterText];
377 footer.text = 210 footerItem.linkDelegate = self;
378 l10n_util::GetNSString(IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS); 211 [model addItem:footerItem toSectionWithIdentifier:SectionIdentifierFooter];
379 } else if ([[_dataSource authenticatedAccountName] length]) {
380 const base::string16 accountName =
381 base::SysNSStringToUTF16([_dataSource authenticatedAccountName]);
382 const std::string formattedString = l10n_util::GetStringFUTF8(
383 IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_IN, accountName);
384 footer.text = base::SysUTF8ToNSString(formattedString);
385 } else {
386 footer.text = l10n_util::GetNSString(
387 IDS_PAYMENTS_CARD_AND_ADDRESS_SETTINGS_SIGNED_OUT);
388 }
389 footer.linkURL = GURL(kSettingsURL);
390 footer.linkDelegate = self;
391 [model addItem:footer toSectionWithIdentifier:SectionIdentifierFooter];
392 } 212 }
393 213
394 - (void)viewDidLoad { 214 - (void)viewDidLoad {
395 [super viewDidLoad]; 215 [super viewDidLoad];
396 self.collectionView.accessibilityIdentifier = kPaymentRequestCollectionViewID; 216 self.collectionView.accessibilityIdentifier = kPaymentRequestCollectionViewID;
397 217
398 // Customize collection view settings. 218 // Customize collection view settings.
399 self.styler.cellStyle = MDCCollectionViewCellStyleCard; 219 self.styler.cellStyle = MDCCollectionViewCellStyleCard;
400 self.styler.separatorInset = 220 self.styler.separatorInset =
401 UIEdgeInsetsMake(0, kSeparatorEdgeInset, 0, kSeparatorEdgeInset); 221 UIEdgeInsetsMake(0, kSeparatorEdgeInset, 0, kSeparatorEdgeInset);
402 } 222 }
403 223
404 - (void)updatePaymentSummaryWithTotalValueChanged:(BOOL)totalValueChanged { 224 - (void)updatePaymentSummaryItem {
405 [self fillPaymentSummaryItem:_paymentSummaryItem 225 CollectionViewModel* model = self.collectionViewModel;
406 withPaymentItem:_paymentRequest->payment_details().total 226
407 withTotalValueChanged:totalValueChanged]; 227 [model removeItemWithType:ItemTypeSummaryTotal
228 fromSectionWithIdentifier:SectionIdentifierSummary];
229
230 [self addPaymentSummaryItem];
231
232 // Reload the item.
408 NSIndexPath* indexPath = 233 NSIndexPath* indexPath =
409 [self.collectionViewModel indexPathForItem:_paymentSummaryItem]; 234 [model indexPathForItemType:ItemTypeSummaryTotal
235 sectionIdentifier:SectionIdentifierSummary];
410 [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]]; 236 [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]];
411 } 237 }
412 238
413 - (void)updateSelectedShippingAddressUI { 239 - (void)updateShippingSection {
414 [self fillShippingAddressItem:_selectedShippingAddressItem 240 CollectionViewModel* model = self.collectionViewModel;
415 withAutofillProfile:_paymentRequest->selected_shipping_profile()]; 241
416 NSIndexPath* indexPath = 242 [model removeItemWithType:ItemTypeShippingAddress
417 [self.collectionViewModel indexPathForItem:_selectedShippingAddressItem]; 243 fromSectionWithIdentifier:SectionIdentifierShipping];
418 [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]]; 244
245 if ([model hasItemForItemType:ItemTypeShippingOption
246 sectionIdentifier:SectionIdentifierShipping]) {
247 [model removeItemWithType:ItemTypeShippingOption
248 fromSectionWithIdentifier:SectionIdentifierShipping];
249 }
250
251 [self populateShippingSection];
252
253 // Reload the section.
254 NSInteger sectionIndex =
255 [model sectionForSectionIdentifier:SectionIdentifierShipping];
256 [self.collectionView
257 reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
258
259 // Update the pay button.
260 [_payButton setEnabled:[_dataSource canPay]];
419 } 261 }
420 262
421 - (void)updateSelectedShippingOptionUI { 263 - (void)updatePaymentMethodSection {
422 [self fillShippingOptionItem:_selectedShippingOptionItem 264 CollectionViewModel* model = self.collectionViewModel;
423 withOption:_paymentRequest->selected_shipping_option()]; 265
424 NSIndexPath* indexPath = 266 [model removeItemWithType:ItemTypePaymentMethod
425 [self.collectionViewModel indexPathForItem:_selectedShippingOptionItem]; 267 fromSectionWithIdentifier:SectionIdentifierPayment];
426 [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]]; 268
269 [self populatePaymentMethodSection];
270
271 // Reload the section.
272 NSInteger sectionIndex =
273 [model sectionForSectionIdentifier:SectionIdentifierPayment];
274 [self.collectionView
275 reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
276
277 // Update the pay button.
278 [_payButton setEnabled:[_dataSource canPay]];
427 } 279 }
428 280
429 - (void)updateSelectedPaymentMethodUI { 281 - (void)updateContactInfoSection {
430 [self fillPaymentMethodItem:_selectedPaymentMethodItem 282 CollectionViewModel* model = self.collectionViewModel;
431 withCreditCard:_paymentRequest->selected_credit_card()];
432 NSIndexPath* indexPath =
433 [self.collectionViewModel indexPathForItem:_selectedPaymentMethodItem];
434 [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]];
435 }
436 283
437 - (void)updateSelectedContactInfoUI { 284 [model removeItemWithType:ItemTypeContactInfo
438 [self fillContactInfoItem:_selectedContactInfoItem 285 fromSectionWithIdentifier:SectionIdentifierContactInfo];
439 withAutofillProfile:_paymentRequest->selected_contact_profile()];
440 NSIndexPath* indexPath =
441 [self.collectionViewModel indexPathForItem:_selectedContactInfoItem];
442 [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]];
443 }
444 286
445 #pragma mark - Helper methods 287 [self populateContactInfoSection];
446 288
447 - (void)fillPaymentSummaryItem:(PriceItem*)item 289 // Reload the section.
448 withPaymentItem:(web::PaymentItem)paymentItem 290 NSInteger sectionIndex =
449 withTotalValueChanged:(BOOL)totalValueChanged { 291 [model sectionForSectionIdentifier:SectionIdentifierContactInfo];
450 item.item = 292 [self.collectionView
451 base::SysUTF16ToNSString(_paymentRequest->payment_details().total.label); 293 reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
452 payments::CurrencyFormatter* currencyFormatter =
453 _paymentRequest->GetOrCreateCurrencyFormatter();
454 item.price = SysUTF16ToNSString(l10n_util::GetStringFUTF16(
455 IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT,
456 base::UTF8ToUTF16(currencyFormatter->formatted_currency_code()),
457 currencyFormatter->Format(base::UTF16ToASCII(paymentItem.amount.value))));
458 item.notification = totalValueChanged
459 ? l10n_util::GetNSString(IDS_PAYMENTS_UPDATED_LABEL)
460 : nil;
461 }
462 294
463 - (void)fillShippingAddressItem:(AutofillProfileItem*)item 295 // Update the pay button.
464 withAutofillProfile:(autofill::AutofillProfile*)profile { 296 [_payButton setEnabled:[_dataSource canPay]];
465 DCHECK(profile);
466 item.name = GetNameLabelFromAutofillProfile(*profile);
467 item.address = GetShippingAddressLabelFromAutofillProfile(*profile);
468 item.phoneNumber = GetPhoneNumberLabelFromAutofillProfile(*profile);
469 }
470
471 - (void)fillShippingOptionItem:(PaymentsTextItem*)item
472 withOption:(web::PaymentShippingOption*)option {
473 item.text = base::SysUTF16ToNSString(option->label);
474 payments::CurrencyFormatter* currencyFormatter =
475 _paymentRequest->GetOrCreateCurrencyFormatter();
476 item.detailText = SysUTF16ToNSString(
477 currencyFormatter->Format(base::UTF16ToASCII(option->amount.value)));
478 }
479
480 - (void)fillPaymentMethodItem:(PaymentMethodItem*)item
481 withCreditCard:(autofill::CreditCard*)creditCard {
482 item.methodID =
483 base::SysUTF16ToNSString(creditCard->NetworkAndLastFourDigits());
484 item.methodDetail = base::SysUTF16ToNSString(
485 creditCard->GetRawInfo(autofill::CREDIT_CARD_NAME_FULL));
486 int issuerNetworkIconID =
487 autofill::data_util::GetPaymentRequestData(creditCard->network())
488 .icon_resource_id;
489 item.methodTypeIcon = NativeImage(issuerNetworkIconID);
490 }
491
492 - (void)fillContactInfoItem:(AutofillProfileItem*)item
493 withAutofillProfile:(autofill::AutofillProfile*)profile {
494 DCHECK(profile);
495 item.name = GetNameLabelFromAutofillProfile(*profile);
496 item.phoneNumber = GetPhoneNumberLabelFromAutofillProfile(*profile);
497 item.email = GetEmailLabelFromAutofillProfile(*profile);
498 } 297 }
499 298
500 #pragma mark - CollectionViewFooterLinkDelegate 299 #pragma mark - CollectionViewFooterLinkDelegate
501 300
502 - (void)cell:(CollectionViewFooterCell*)cell didTapLinkURL:(GURL)url { 301 - (void)cell:(CollectionViewFooterCell*)cell didTapLinkURL:(GURL)url {
503 DCHECK_EQ(url, GURL(kSettingsURL)) << "Unknown URL tapped";
504 [_delegate paymentRequestViewControllerDidSelectSettings:self]; 302 [_delegate paymentRequestViewControllerDidSelectSettings:self];
505 } 303 }
506 304
507 #pragma mark UICollectionViewDataSource 305 #pragma mark - UICollectionViewDataSource
508 306
509 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView 307 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
510 cellForItemAtIndexPath:(nonnull NSIndexPath*)indexPath { 308 cellForItemAtIndexPath:(nonnull NSIndexPath*)indexPath {
511 UICollectionViewCell* cell = 309 UICollectionViewCell* cell =
512 [super collectionView:collectionView cellForItemAtIndexPath:indexPath]; 310 [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
513 311
514 NSInteger itemType = 312 NSInteger itemType =
515 [self.collectionViewModel itemTypeForIndexPath:indexPath]; 313 [self.collectionViewModel itemTypeForIndexPath:indexPath];
516 switch (itemType) { 314 switch (itemType) {
517 case ItemTypeAddShippingAddress: { 315 case ItemTypeShippingAddress:
518 CollectionViewDetailCell* detailCell = 316 case ItemTypePaymentMethod:
519 base::mac::ObjCCastStrict<CollectionViewDetailCell>(cell); 317 case ItemTypeShippingOption:
520 detailCell.detailTextLabel.font = [MDCTypography body2Font]; 318 case ItemTypeContactInfo: {
521 detailCell.detailTextLabel.textColor = 319 if ([cell isKindOfClass:[CollectionViewDetailCell class]]) {
522 [[MDCPalette cr_bluePalette] tint700]; 320 CollectionViewDetailCell* detailCell =
321 base::mac::ObjCCastStrict<CollectionViewDetailCell>(cell);
322 detailCell.detailTextLabel.font = [MDCTypography body2Font];
323 detailCell.detailTextLabel.textColor =
324 [[MDCPalette cr_bluePalette] tint700];
325 }
523 break; 326 break;
524 } 327 }
525 case ItemTypeFooterText: { 328 case ItemTypeFooterText: {
526 CollectionViewFooterCell* footerCell = 329 CollectionViewFooterCell* footerCell =
527 base::mac::ObjCCastStrict<CollectionViewFooterCell>(cell); 330 base::mac::ObjCCastStrict<CollectionViewFooterCell>(cell);
528 footerCell.textLabel.font = [MDCTypography body2Font]; 331 footerCell.textLabel.font = [MDCTypography body2Font];
529 footerCell.textLabel.textColor = [[MDCPalette greyPalette] tint600]; 332 footerCell.textLabel.textColor = [[MDCPalette greyPalette] tint600];
530 footerCell.textLabel.shadowColor = nil; // No shadow. 333 footerCell.textLabel.shadowColor = nil; // No shadow.
531 footerCell.horizontalPadding = kFooterCellHorizontalPadding; 334 footerCell.horizontalPadding = kFooterCellHorizontalPadding;
532 break; 335 break;
533 } 336 }
534 default: 337 default:
535 break; 338 break;
536 } 339 }
537 return cell; 340 return cell;
538 } 341 }
539 342
540 #pragma mark UICollectionViewDelegate 343 #pragma mark - UICollectionViewDelegate
541 344
542 - (void)collectionView:(UICollectionView*)collectionView 345 - (void)collectionView:(UICollectionView*)collectionView
543 didSelectItemAtIndexPath:(NSIndexPath*)indexPath { 346 didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
544 [super collectionView:collectionView didSelectItemAtIndexPath:indexPath]; 347 [super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
545 348
546 NSInteger itemType = 349 NSInteger itemType =
547 [self.collectionViewModel itemTypeForIndexPath:indexPath]; 350 [self.collectionViewModel itemTypeForIndexPath:indexPath];
548 switch (itemType) { 351 switch (itemType) {
549 case ItemTypeSummaryTotal: 352 case ItemTypeSummaryTotal:
550 if (!_paymentRequest->payment_details().display_items.empty())
551 [_delegate 353 [_delegate
552 paymentRequestViewControllerDidSelectPaymentSummaryItem:self]; 354 paymentRequestViewControllerDidSelectPaymentSummaryItem:self];
553 break; 355 break;
554 case ItemTypeShippingAddress: 356 case ItemTypeShippingAddress:
555 case ItemTypeAddShippingAddress:
556 [_delegate paymentRequestViewControllerDidSelectShippingAddressItem:self]; 357 [_delegate paymentRequestViewControllerDidSelectShippingAddressItem:self];
557 break; 358 break;
558 case ItemTypeShippingOption: 359 case ItemTypeShippingOption:
559 case ItemTypeSelectShippingOption:
560 [_delegate paymentRequestViewControllerDidSelectShippingOptionItem:self]; 360 [_delegate paymentRequestViewControllerDidSelectShippingOptionItem:self];
561 break; 361 break;
562 case ItemTypePaymentMethod: 362 case ItemTypePaymentMethod:
563 case ItemTypeAddPaymentMethod:
564 [_delegate paymentRequestViewControllerDidSelectPaymentMethodItem:self]; 363 [_delegate paymentRequestViewControllerDidSelectPaymentMethodItem:self];
565 break; 364 break;
566 case ItemTypeContactInfo: 365 case ItemTypeContactInfo:
567 case ItemTypeAddContactInfo:
568 [_delegate paymentRequestViewControllerDidSelectContactInfoItem:self]; 366 [_delegate paymentRequestViewControllerDidSelectContactInfoItem:self];
569 break; 367 break;
570 case ItemTypeFooterText: 368 case ItemTypeFooterText:
571 // Selecting the footer item should not trigger an action, unless the 369 // Selecting the footer item should not trigger an action, unless the
572 // link was clicked, which will call didTapLinkURL:. 370 // link was clicked, which will call didTapLinkURL:.
573 break; 371 break;
574 default: 372 default:
575 NOTREACHED(); 373 NOTREACHED();
576 break; 374 break;
577 } 375 }
578 } 376 }
579 377
580 #pragma mark MDCCollectionViewStylingDelegate 378 #pragma mark - MDCCollectionViewStylingDelegate
581 379
582 - (CGFloat)collectionView:(UICollectionView*)collectionView 380 - (CGFloat)collectionView:(UICollectionView*)collectionView
583 cellHeightAtIndexPath:(NSIndexPath*)indexPath { 381 cellHeightAtIndexPath:(NSIndexPath*)indexPath {
584 CollectionViewItem* item = 382 CollectionViewItem* item =
585 [self.collectionViewModel itemAtIndexPath:indexPath]; 383 [self.collectionViewModel itemAtIndexPath:indexPath];
586 switch (item.type) { 384 switch (item.type) {
587 case ItemTypeSpinner: 385 case ItemTypeSpinner:
588 case ItemTypeShippingAddress: 386 case ItemTypeShippingAddress:
387 case ItemTypeShippingOption:
589 case ItemTypePaymentMethod: 388 case ItemTypePaymentMethod:
590 case ItemTypeContactInfo: 389 case ItemTypeContactInfo:
591 case ItemTypeFooterText: 390 case ItemTypeFooterText:
592 return [MDCCollectionViewCell 391 return [MDCCollectionViewCell
593 cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds) 392 cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
594 forItem:item]; 393 forItem:item];
595 case ItemTypeShippingOption:
596 return MDCCellDefaultTwoLineHeight;
597 case ItemTypeSummaryPageInfo: 394 case ItemTypeSummaryPageInfo:
598 case ItemTypeSummaryTotal: 395 case ItemTypeSummaryTotal:
599 case ItemTypeShippingTitle:
600 case ItemTypeAddShippingAddress:
601 case ItemTypeSelectShippingOption:
602 case ItemTypePaymentTitle:
603 case ItemTypeAddPaymentMethod:
604 case ItemTypeContactInfoTitle:
605 case ItemTypeAddContactInfo:
606 return MDCCellDefaultOneLineHeight; 396 return MDCCellDefaultOneLineHeight;
607 default: 397 default:
608 NOTREACHED(); 398 NOTREACHED();
609 return MDCCellDefaultOneLineHeight; 399 return MDCCellDefaultOneLineHeight;
610 } 400 }
611 } 401 }
612 402
613 - (BOOL)collectionView:(UICollectionView*)collectionView 403 - (BOOL)collectionView:(UICollectionView*)collectionView
614 hidesInkViewAtIndexPath:(NSIndexPath*)indexPath { 404 hidesInkViewAtIndexPath:(NSIndexPath*)indexPath {
615 NSInteger type = [self.collectionViewModel itemTypeForIndexPath:indexPath]; 405 NSInteger type = [self.collectionViewModel itemTypeForIndexPath:indexPath];
616 // If there are no payment items to display, there is no effect from touching 406 // If there are no payment items to display, there is no effect from touching
617 // the total so there should not be an ink ripple. The footer should also not 407 // the total so there should not be an ink ripple. The footer should also not
618 // have a ripple. 408 // have a ripple.
619 if ((type == ItemTypeSummaryTotal && 409 if ((type == ItemTypeSummaryTotal && ![_dataSource hasPaymentItems]) ||
620 _paymentRequest->payment_details().display_items.empty()) ||
621 (type == ItemTypeFooterText)) { 410 (type == ItemTypeFooterText)) {
622 return YES; 411 return YES;
623 } else { 412 } else {
624 return NO; 413 return NO;
625 } 414 }
626 } 415 }
627 416
628 - (BOOL)collectionView:(UICollectionView*)collectionView 417 - (BOOL)collectionView:(UICollectionView*)collectionView
629 shouldHideItemBackgroundAtIndexPath:(NSIndexPath*)indexPath { 418 shouldHideItemBackgroundAtIndexPath:(NSIndexPath*)indexPath {
630 // No background on the footer text item. 419 // No background on the footer text item.
631 NSInteger sectionIdentifier = 420 NSInteger sectionIdentifier =
632 [self.collectionViewModel sectionIdentifierForSection:indexPath.section]; 421 [self.collectionViewModel sectionIdentifierForSection:indexPath.section];
633 return sectionIdentifier == SectionIdentifierFooter ? YES : NO; 422 return sectionIdentifier == SectionIdentifierFooter ? YES : NO;
634 } 423 }
635 424
425 #pragma mark - Helper methods
426
427 - (void)addPaymentSummaryItem {
428 CollectionViewItem* item = [_dataSource paymentSummaryItem];
429 [item setType:ItemTypeSummaryTotal];
430 if ([_dataSource hasPaymentItems])
431 item.accessibilityTraits |= UIAccessibilityTraitButton;
432 [self.collectionViewModel addItem:item
433 toSectionWithIdentifier:SectionIdentifierSummary];
434 }
435
436 - (void)populateShippingSection {
437 CollectionViewModel* model = self.collectionViewModel;
438
439 CollectionViewItem* shippingAddressItem = [_dataSource shippingAddressItem];
440 [shippingAddressItem setType:ItemTypeShippingAddress];
441 shippingAddressItem.accessibilityTraits |= UIAccessibilityTraitButton;
442 [model addItem:shippingAddressItem
443 toSectionWithIdentifier:SectionIdentifierShipping];
444
445 if ([_dataSource canShip]) {
446 CollectionViewItem* shippingOptionItem = [_dataSource shippingOptionItem];
447 [shippingOptionItem setType:ItemTypeShippingOption];
448 shippingOptionItem.accessibilityTraits |= UIAccessibilityTraitButton;
449 [model addItem:shippingOptionItem
450 toSectionWithIdentifier:SectionIdentifierShipping];
451 }
452 }
453
454 - (void)populatePaymentMethodSection {
455 CollectionViewModel* model = self.collectionViewModel;
456
457 CollectionViewItem* paymentMethodSectionHeaderItem =
458 [_dataSource paymentMethodSectionHeaderItem];
459 if (paymentMethodSectionHeaderItem) {
460 [paymentMethodSectionHeaderItem setType:ItemTypePaymentHeader];
461 [model setHeader:paymentMethodSectionHeaderItem
462 forSectionWithIdentifier:SectionIdentifierPayment];
463 }
464
465 CollectionViewItem* paymentMethodItem = [_dataSource paymentMethodItem];
466 [paymentMethodItem setType:ItemTypePaymentMethod];
467 paymentMethodItem.accessibilityTraits |= UIAccessibilityTraitButton;
468 [model addItem:paymentMethodItem
469 toSectionWithIdentifier:SectionIdentifierPayment];
470 }
471
472 - (void)populateContactInfoSection {
473 CollectionViewModel* model = self.collectionViewModel;
474
475 CollectionViewItem* contactInfoSectionHeaderItem =
476 [_dataSource contactInfoSectionHeaderItem];
477 if (contactInfoSectionHeaderItem) {
478 [contactInfoSectionHeaderItem setType:ItemTypeContactInfoHeader];
479 [model setHeader:contactInfoSectionHeaderItem
480 forSectionWithIdentifier:SectionIdentifierContactInfo];
481 }
482
483 CollectionViewItem* contactInfoItem = [_dataSource contactInfoItem];
484 [contactInfoItem setType:ItemTypeContactInfo];
485 contactInfoItem.accessibilityTraits |= UIAccessibilityTraitButton;
486 [model addItem:contactInfoItem
487 toSectionWithIdentifier:SectionIdentifierContactInfo];
488 }
489
636 @end 490 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698