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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/ui/payments/address_edit_mediator.mm
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator.mm b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
index cbb1291afcf70085ad1be9c75681cf8e5e1d7547..33be542413ad53f32de0fb543eee11d84d7bfe2f 100644
--- a/ios/chrome/browser/ui/payments/address_edit_mediator.mm
+++ b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
@@ -4,15 +4,39 @@
#import "ios/chrome/browser/ui/payments/address_edit_mediator.h"
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/callback.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/values.h"
+#include "components/autofill/core/browser/autofill_address_util.h"
+#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/country_combobox_model.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/strings/grit/components_strings.h"
+#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/payments/payment_request.h"
+#import "ios/chrome/browser/ui/autofill/autofill_ui_type.h"
+#import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h"
#import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h"
+#import "ios/chrome/browser/ui/payments/payment_request_editor_field.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "third_party/libaddressinput/messages.h"
+#include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
-@interface AddressEditMediator ()
+@interface AddressEditMediator () {
+ std::unique_ptr<RegionDataLoader> _regionDataLoader;
+}
// The PaymentRequest object owning an instance of web::PaymentRequest as
// provided by the page invoking the Payment Request API. This is a weak
@@ -23,14 +47,32 @@
// should outlive it.
@property(nonatomic, assign) autofill::AutofillProfile* address;
+// The map of autofill types to the cached editor fields. Helps reuse the editor
+// fields and therefore maintain their existing values when the selected country
+// changes and the editor fields get updated.
+@property(nonatomic, strong)
+ NSMutableDictionary<NSNumber*, EditorField*>* fieldsMap;
+
+// The list of current editor fields.
+@property(nonatomic, strong) NSMutableArray<EditorField*>* fields;
+
+// The reference to the autofill::ADDRESS_HOME_STATE field, if any.
+@property(nonatomic, strong) EditorField* regionField;
+
@end
@implementation AddressEditMediator
@synthesize state = _state;
@synthesize consumer = _consumer;
+@synthesize countries = _countries;
+@synthesize selectedCountryCode = _selectedCountryCode;
+@synthesize regions = _regions;
@synthesize paymentRequest = _paymentRequest;
@synthesize address = _address;
+@synthesize fieldsMap = _fieldsMap;
+@synthesize fields = _fields;
+@synthesize regionField = _regionField;
- (instancetype)initWithPaymentRequest:(PaymentRequest*)paymentRequest
address:(autofill::AutofillProfile*)address {
@@ -40,6 +82,8 @@
_address = address;
_state =
_address ? EditViewControllerStateEdit : EditViewControllerStateCreate;
+ _fieldsMap = [[NSMutableDictionary alloc] init];
+ [self loadCountries];
}
return self;
}
@@ -48,7 +92,20 @@
- (void)setConsumer:(id<PaymentRequestEditConsumer>)consumer {
_consumer = consumer;
+
+ [self.consumer setEditorFields:[self createEditorFields]];
+ if (self.regionField)
+ [self loadRegions];
+}
+
+- (void)setSelectedCountryCode:(NSString*)selectedCountryCode {
+ if (_selectedCountryCode == selectedCountryCode)
+ return;
+ _selectedCountryCode = selectedCountryCode;
+
[self.consumer setEditorFields:[self createEditorFields]];
+ if (self.regionField)
+ [self loadRegions];
}
#pragma mark - CreditCardEditViewControllerDataSource
@@ -61,10 +118,159 @@
return NO;
}
+#pragma mark - RegionDataLoaderConsumer
+
+- (void)regionDataLoaderDidSucceedWithRegions:
+ (NSMutableArray<NSString*>*)regions {
+ self.regions = regions;
+ // Notify the view controller asynchronously to allow for the view to update.
+ __weak AddressEditMediator* weakSelf = self;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakSelf.consumer setOptions:weakSelf.regions
+ forEditorField:weakSelf.regionField];
+ });
+}
+
#pragma mark - Helper methods
+// Loads the country codes and names and sets the default selected country code.
+- (void)loadCountries {
+ autofill::CountryComboboxModel countryModel;
+ countryModel.SetCountries(*_paymentRequest->GetPersonalDataManager(),
+ base::Callback<bool(const std::string&)>(),
+ GetApplicationContext()->GetApplicationLocale());
+ const autofill::CountryComboboxModel::CountryVector& countriesVector =
+ countryModel.countries();
+
+ NSMutableDictionary<NSString*, NSString*>* countries =
+ [[NSMutableDictionary alloc]
+ initWithCapacity:static_cast<NSUInteger>(countriesVector.size())];
+ for (size_t i = 0; i < countriesVector.size(); ++i) {
+ if (countriesVector[i].get()) {
+ [countries setObject:base::SysUTF16ToNSString(countriesVector[i]->name())
+ forKey:base::SysUTF8ToNSString(
+ countriesVector[i]->country_code())];
+ }
+ }
+ _countries = countries;
+ _selectedCountryCode =
+ base::SysUTF8ToNSString(countryModel.GetDefaultCountryCode());
+}
+
+// Queries the region names based on the selected country code.
+- (void)loadRegions {
+ _regionDataLoader = base::MakeUnique<RegionDataLoader>(self);
+ _regionDataLoader->LoadRegionData(
+ base::SysNSStringToUTF8(self.selectedCountryCode),
+ _paymentRequest->GetRegionDataLoader());
+}
+
+// Returns an array of editor fields based on the selected country code. Caches
+// the fields to be reused when the selected country code changes.
- (NSArray<EditorField*>*)createEditorFields {
- return @[];
+ self.fields = [[NSMutableArray alloc] init];
+
+ self.regionField = nil;
+
+ base::ListValue addressComponents;
+ std::string unused;
+ autofill::GetAddressComponents(
+ base::SysNSStringToUTF8(self.selectedCountryCode),
+ GetApplicationContext()->GetApplicationLocale(), &addressComponents,
+ &unused);
+
+ for (size_t lineIndex = 0; lineIndex < addressComponents.GetSize();
+ ++lineIndex) {
+ const base::ListValue* line = nullptr;
+ if (!addressComponents.GetList(lineIndex, &line)) {
+ NOTREACHED();
+ return @[];
+ }
+ for (size_t componentIndex = 0; componentIndex < line->GetSize();
+ ++componentIndex) {
+ const base::DictionaryValue* component = nullptr;
+ if (!line->GetDictionary(componentIndex, &component)) {
+ NOTREACHED();
+ return @[];
+ }
+
+ std::string autofillType;
+ if (!component->GetString(autofill::kFieldTypeKey, &autofillType)) {
+ NOTREACHED();
+ return @[];
+ }
+ AutofillUIType autofillUIType = AutofillUITypeFromAutofillType(
+ autofill::GetFieldTypeFromString(autofillType));
+
+ NSNumber* fieldKey = [NSNumber numberWithInt:autofillUIType];
+ EditorField* field = self.fieldsMap[fieldKey];
+ if (!field) {
+ BOOL required = autofillUIType != AutofillUITypeProfileCompanyName;
+ field =
+ [[EditorField alloc] initWithAutofillUIType:autofillUIType
+ fieldType:EditorFieldTypeTextField
+ label:nil
+ value:nil
+ required:required];
+ [self.fieldsMap setObject:field forKey:fieldKey];
+ }
+
+ std::string fieldLabel;
+ if (!component->GetString(autofill::kFieldNameKey, &fieldLabel)) {
+ NOTREACHED();
+ return @[];
+ }
+ field.label = base::SysUTF8ToNSString(fieldLabel);
+
+ // Keep a reference to the field for the autofill::ADDRESS_HOME_STATE. Set
+ // its value to "Loading..." and disable it until the regions are loaded.
+ if (autofillUIType == AutofillUITypeProfileHomeAddressState) {
+ self.regionField = field;
+ field.value = l10n_util::GetNSString(IDS_AUTOFILL_LOADING_REGIONS);
+ field.enabled = NO;
+ }
+
+ [self.fields addObject:field];
+
+ // Insert the country field right after the full name field.
+ if (autofillUIType == AutofillUITypeProfileFullName) {
+ NSNumber* countryFieldKey =
+ [NSNumber numberWithInt:AutofillUITypeProfileHomeAddressCountry];
+ EditorField* field = self.fieldsMap[countryFieldKey];
+ if (!field) {
+ NSString* label = l10n_util::GetNSString(
+ IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL);
+ field = [[EditorField alloc]
+ initWithAutofillUIType:AutofillUITypeProfileHomeAddressCountry
+ fieldType:EditorFieldTypeSelector
+ label:label
+ value:nil
+ required:YES];
+ [self.fieldsMap setObject:field forKey:countryFieldKey];
+ }
+ field.value = self.selectedCountryCode;
+ field.displayValue = self.countries[self.selectedCountryCode];
+ [self.fields addObject:field];
+ }
+ }
+ }
+
+ // Always add phone number field at the end.
+ NSNumber* phoneNumberFieldKey =
+ [NSNumber numberWithInt:AutofillUITypeProfileHomePhoneWholeNumber];
+ EditorField* field = self.fieldsMap[phoneNumberFieldKey];
+ if (!field) {
+ field = [[EditorField alloc]
+ initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber
+ fieldType:EditorFieldTypeTextField
+ label:l10n_util::GetNSString(IDS_IOS_AUTOFILL_PHONE)
+ value:nil
+ required:YES];
+ [self.fieldsMap setObject:field forKey:phoneNumberFieldKey];
+ }
+ [self.fields addObject:field];
+
+ return self.fields;
}
@end
« 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