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 #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 |
OLD | NEW |