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

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

Issue 2893353002: [Payment Request] Address edit view controller (Part 2) (Closed)
Patch Set: Initial Created 3 years, 7 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/address_edit_mediator.h" 5 #import "ios/chrome/browser/ui/payments/address_edit_mediator.h"
6 6
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <utility>
11
12 #include "base/callback.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "base/values.h"
16 #include "components/autofill/core/browser/autofill_address_util.h"
17 #include "components/autofill/core/browser/autofill_country.h"
7 #include "components/autofill/core/browser/autofill_profile.h" 18 #include "components/autofill/core/browser/autofill_profile.h"
19 #include "components/autofill/core/browser/country_combobox_model.h"
20 #include "components/autofill/core/browser/field_types.h"
21 #include "components/autofill/core/browser/personal_data_manager.h"
22 #include "components/strings/grit/components_strings.h"
23 #include "ios/chrome/browser/application_context.h"
8 #include "ios/chrome/browser/payments/payment_request.h" 24 #include "ios/chrome/browser/payments/payment_request.h"
25 #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h"
26 #import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h"
9 #import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h" 27 #import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h"
28 #import "ios/chrome/browser/ui/payments/payment_request_editor_field.h"
29 #include "ios/chrome/grit/ios_strings.h"
30 #include "third_party/libaddressinput/messages.h"
31 #include "ui/base/l10n/l10n_util.h"
10 32
11 #if !defined(__has_feature) || !__has_feature(objc_arc) 33 #if !defined(__has_feature) || !__has_feature(objc_arc)
12 #error "This file requires ARC support." 34 #error "This file requires ARC support."
13 #endif 35 #endif
14 36
15 @interface AddressEditMediator () 37 @interface AddressEditMediator () {
38 std::unique_ptr<RegionDataLoader> _regionDataLoader;
39 }
16 40
17 // The PaymentRequest object owning an instance of web::PaymentRequest as 41 // The PaymentRequest object owning an instance of web::PaymentRequest as
18 // provided by the page invoking the Payment Request API. This is a weak 42 // provided by the page invoking the Payment Request API. This is a weak
19 // pointer and should outlive this class. 43 // pointer and should outlive this class.
20 @property(nonatomic, assign) PaymentRequest* paymentRequest; 44 @property(nonatomic, assign) PaymentRequest* paymentRequest;
21 45
22 // The address to be edited, if any. This pointer is not owned by this class and 46 // The address to be edited, if any. This pointer is not owned by this class and
23 // should outlive it. 47 // should outlive it.
24 @property(nonatomic, assign) autofill::AutofillProfile* address; 48 @property(nonatomic, assign) autofill::AutofillProfile* address;
25 49
50 // The map of autofill types to the cached editor fields. Helps reuse the editor
51 // fields and therefore maintain their existing values when the selected country
52 // changes and the editor fields get updated.
53 @property(nonatomic, strong)
54 NSMutableDictionary<NSNumber*, EditorField*>* fieldsMap;
55
56 // The list of current editor fields.
57 @property(nonatomic, strong) NSMutableArray<EditorField*>* fields;
58
59 // The reference to the autofill::ADDRESS_HOME_STATE field, if any.
60 @property(nonatomic, strong) EditorField* regionField;
61
26 @end 62 @end
27 63
28 @implementation AddressEditMediator 64 @implementation AddressEditMediator
29 65
30 @synthesize state = _state; 66 @synthesize state = _state;
31 @synthesize consumer = _consumer; 67 @synthesize consumer = _consumer;
68 @synthesize countries = _countries;
69 @synthesize selectedCountryCode = _selectedCountryCode;
70 @synthesize regions = _regions;
32 @synthesize paymentRequest = _paymentRequest; 71 @synthesize paymentRequest = _paymentRequest;
33 @synthesize address = _address; 72 @synthesize address = _address;
73 @synthesize fieldsMap = _fieldsMap;
74 @synthesize fields = _fields;
75 @synthesize regionField = _regionField;
34 76
35 - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest 77 - (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest
36 address:(autofill::AutofillProfile*)address { 78 address:(autofill::AutofillProfile*)address {
37 self = [super init]; 79 self = [super init];
38 if (self) { 80 if (self) {
39 _paymentRequest = paymentRequest; 81 _paymentRequest = paymentRequest;
40 _address = address; 82 _address = address;
41 _state = 83 _state =
42 _address ? EditViewControllerStateEdit : EditViewControllerStateCreate; 84 _address ? EditViewControllerStateEdit : EditViewControllerStateCreate;
85 _fieldsMap = [[NSMutableDictionary alloc] init];
86 [self loadCountries];
43 } 87 }
44 return self; 88 return self;
45 } 89 }
46 90
47 #pragma mark - Setters 91 #pragma mark - Setters
48 92
49 - (void)setConsumer:(id<PaymentRequestEditConsumer>)consumer { 93 - (void)setConsumer:(id<PaymentRequestEditConsumer>)consumer {
50 _consumer = consumer; 94 _consumer = consumer;
95
51 [self.consumer setEditorFields:[self createEditorFields]]; 96 [self.consumer setEditorFields:[self createEditorFields]];
97 if (self.regionField)
98 [self loadRegions];
99 }
100
101 - (void)setSelectedCountryCode:(NSString*)selectedCountryCode {
102 if (_selectedCountryCode == selectedCountryCode)
103 return;
104 _selectedCountryCode = selectedCountryCode;
105
106 [self.consumer setEditorFields:[self createEditorFields]];
107 if (self.regionField)
108 [self loadRegions];
52 } 109 }
53 110
54 #pragma mark - CreditCardEditViewControllerDataSource 111 #pragma mark - CreditCardEditViewControllerDataSource
55 112
56 - (CollectionViewItem*)headerItem { 113 - (CollectionViewItem*)headerItem {
57 return nil; 114 return nil;
58 } 115 }
59 116
60 - (BOOL)shouldHideBackgroundForHeaderItem { 117 - (BOOL)shouldHideBackgroundForHeaderItem {
61 return NO; 118 return NO;
62 } 119 }
63 120
121 #pragma mark - RegionDataLoaderConsumer
122
123 - (void)regionDataLoaderDidSucceedWithRegions:
124 (NSMutableArray<NSString*>*)regions {
125 self.regions = regions;
126 // Notify the view controller asynchronously to allow for the view to update.
127 __weak AddressEditMediator* weakSelf = self;
128 dispatch_async(dispatch_get_main_queue(), ^{
129 [weakSelf.consumer setOptions:weakSelf.regions
130 forEditorField:weakSelf.regionField];
131 });
132 }
133
64 #pragma mark - Helper methods 134 #pragma mark - Helper methods
65 135
136 // Loads the country codes and names and sets the default selected country code.
137 - (void)loadCountries {
138 autofill::CountryComboboxModel countryModel;
139 countryModel.SetCountries(*_paymentRequest->GetPersonalDataManager(),
140 base::Callback<bool(const std::string&)>(),
141 GetApplicationContext()->GetApplicationLocale());
142 const autofill::CountryComboboxModel::CountryVector& countriesVector =
143 countryModel.countries();
144
145 NSMutableDictionary<NSString*, NSString*>* countries =
146 [[NSMutableDictionary alloc]
147 initWithCapacity:static_cast<NSUInteger>(countriesVector.size())];
148 for (size_t i = 0; i < countriesVector.size(); ++i) {
149 if (countriesVector[i].get()) {
150 [countries setObject:base::SysUTF16ToNSString(countriesVector[i]->name())
151 forKey:base::SysUTF8ToNSString(
152 countriesVector[i]->country_code())];
153 }
154 }
155 _countries = countries;
156 _selectedCountryCode =
157 base::SysUTF8ToNSString(countryModel.GetDefaultCountryCode());
158 }
159
160 // Queries the region names based on the selected country code.
161 - (void)loadRegions {
162 _regionDataLoader = base::MakeUnique<RegionDataLoader>(self);
163 _regionDataLoader->LoadRegionData(
164 base::SysNSStringToUTF8(self.selectedCountryCode),
165 _paymentRequest->GetRegionDataLoader());
166 }
167
168 // Returns an array of editor fields based on the selected country code. Caches
169 // the fields to be reused when the selected country code changes.
66 - (NSArray<EditorField*>*)createEditorFields { 170 - (NSArray<EditorField*>*)createEditorFields {
67 return @[]; 171 self.fields = [[NSMutableArray alloc] init];
172
173 self.regionField = nil;
174
175 base::ListValue addressComponents;
176 std::string unused;
177 autofill::GetAddressComponents(
178 base::SysNSStringToUTF8(self.selectedCountryCode),
179 GetApplicationContext()->GetApplicationLocale(), &addressComponents,
180 &unused);
181
182 for (size_t lineIndex = 0; lineIndex < addressComponents.GetSize();
183 ++lineIndex) {
184 const base::ListValue* line = nullptr;
185 if (!addressComponents.GetList(lineIndex, &line)) {
186 NOTREACHED();
187 return @[];
188 }
189 for (size_t componentIndex = 0; componentIndex < line->GetSize();
190 ++componentIndex) {
191 const base::DictionaryValue* component = nullptr;
192 if (!line->GetDictionary(componentIndex, &component)) {
193 NOTREACHED();
194 return @[];
195 }
196
197 std::string autofillType;
198 if (!component->GetString(autofill::kFieldTypeKey, &autofillType)) {
199 NOTREACHED();
200 return @[];
201 }
202 AutofillUIType autofillUIType = AutofillUITypeFromAutofillType(
203 autofill::GetFieldTypeFromString(autofillType));
204
205 NSNumber* fieldKey = [NSNumber numberWithInt:autofillUIType];
206 EditorField* field = self.fieldsMap[fieldKey];
207 if (!field) {
208 BOOL required = autofillUIType != AutofillUITypeProfileCompanyName;
209 field =
210 [[EditorField alloc] initWithAutofillUIType:autofillUIType
211 fieldType:EditorFieldTypeTextField
212 label:nil
213 value:nil
214 required:required];
215 [self.fieldsMap setObject:field forKey:fieldKey];
216 }
217
218 std::string fieldLabel;
219 if (!component->GetString(autofill::kFieldNameKey, &fieldLabel)) {
220 NOTREACHED();
221 return @[];
222 }
223 field.label = base::SysUTF8ToNSString(fieldLabel);
224
225 // Keep a reference to the field for the autofill::ADDRESS_HOME_STATE. Set
226 // its value to "Loading..." and disable it until the regions are loaded.
227 if (autofillUIType == AutofillUITypeProfileHomeAddressState) {
228 self.regionField = field;
229 field.value = l10n_util::GetNSString(IDS_AUTOFILL_LOADING_REGIONS);
230 field.enabled = NO;
231 }
232
233 [self.fields addObject:field];
234
235 // Insert the country field right after the full name field.
236 if (autofillUIType == AutofillUITypeProfileFullName) {
237 NSNumber* countryFieldKey =
238 [NSNumber numberWithInt:AutofillUITypeProfileHomeAddressCountry];
239 EditorField* field = self.fieldsMap[countryFieldKey];
240 if (!field) {
241 NSString* label = l10n_util::GetNSString(
242 IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL);
243 field = [[EditorField alloc]
244 initWithAutofillUIType:AutofillUITypeProfileHomeAddressCountry
245 fieldType:EditorFieldTypeSelector
246 label:label
247 value:nil
248 required:YES];
249 [self.fieldsMap setObject:field forKey:countryFieldKey];
250 }
251 field.value = self.selectedCountryCode;
252 field.displayValue = self.countries[self.selectedCountryCode];
253 [self.fields addObject:field];
254 }
255 }
256 }
257
258 // Always add phone number field at the end.
259 NSNumber* phoneNumberFieldKey =
260 [NSNumber numberWithInt:AutofillUITypeProfileHomePhoneWholeNumber];
261 EditorField* field = self.fieldsMap[phoneNumberFieldKey];
262 if (!field) {
263 field = [[EditorField alloc]
264 initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber
265 fieldType:EditorFieldTypeTextField
266 label:l10n_util::GetNSString(IDS_IOS_AUTOFILL_PHONE)
267 value:nil
268 required:YES];
269 [self.fieldsMap setObject:field forKey:phoneNumberFieldKey];
270 }
271 [self.fields addObject:field];
272
273 return self.fields;
68 } 274 }
69 275
70 @end 276 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/payments/address_edit_mediator.h ('k') | ios/chrome/browser/ui/payments/payment_request_edit_consumer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698