Commit cfbc4807 authored by sczs's avatar sczs Committed by Commit Bot

[ios] Adds editing capabilities to SaveCard Infobar Modal

- Adds a public flag to SaveCardTVC (supportsEditing), if YES then
cardholder name, expiration month and year will be editable.
- Implements updateSaveCardButtonState which checks the correctness
of the Data: No empty cardholder name, and a valid expiration date.
meaning that the year is the current one or older, and the month has a
valid value for the selected year.
- If one of the previous check doesn't pass then the Save Card button
is disabled.

Bug: 1014652
Change-Id: I61625a504a7da9617f842436862d58a32871882d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1932799
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Reviewed-by: default avatarPeter Lee <pkl@chromium.org>
Reviewed-by: default avatarChris Lu <thegreenfrog@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719962}
parent b4a04f01
......@@ -166,6 +166,9 @@
self.saveCardInfoBarDelegate->expiration_date_year());
self.modalViewController.currentCardSaved = !self.infobarAccepted;
self.modalViewController.legalMessages = [self legalMessagesForModal];
// TODO(crbug.com/1029067):Change NO to
// self.saveCardInfoBarDelegate->upload(). Once we want to enable editing.
self.modalViewController.supportsEditing = NO;
return YES;
}
......
......@@ -43,6 +43,9 @@
// YES if the Card being displayed has been saved.
@property(nonatomic, assign) BOOL currentCardSaved;
// Set to YES if the Modal should support editing.
@property(nonatomic, assign) BOOL supportsEditing;
@end
#endif // IOS_CHROME_BROWSER_UI_INFOBARS_MODALS_INFOBAR_SAVE_CARD_TABLE_VIEW_CONTROLLER_H_
......@@ -25,6 +25,11 @@
#error "This file requires ARC support."
#endif
namespace {
// Number of Months in a year.
const int kNumberOfMonthsInYear = 12;
} // namespace
typedef NS_ENUM(NSInteger, SectionIdentifier) {
SectionIdentifierContent = kSectionIdentifierEnumZero,
};
......@@ -50,6 +55,14 @@ typedef NS_ENUM(NSInteger, ItemType) {
// query the corresponding SaveCardMessageWithLinks from legalMessages when
// configuring the cell.
@property(nonatomic, assign) int legalMessagesStartingIndex;
// Item for displaying and editing the cardholder name.
@property(nonatomic, strong) TableViewTextEditItem* cardholderNameItem;
// Item for displaying and editing the expiration month.
@property(nonatomic, strong) TableViewTextEditItem* expirationMonthItem;
// Item for displaying and editing the expiration year.
@property(nonatomic, strong) TableViewTextEditItem* expirationYearItem;
// Item for displaying the save card button .
@property(nonatomic, strong) TableViewTextButtonItem* saveCardButtonItem;
@end
......@@ -123,35 +136,29 @@ typedef NS_ENUM(NSInteger, ItemType) {
[model addItem:cardLastDigitsItem
toSectionWithIdentifier:SectionIdentifierContent];
// TODO(crbug.com/1014652): Change textFieldEnabled to YES once editing its
// supported.
TableViewTextEditItem* cardholderNameItem =
self.cardholderNameItem =
[self textEditItemWithType:ItemTypeCardExpireYear
textFieldName:l10n_util::GetNSString(
IDS_IOS_AUTOFILL_CARDHOLDER_NAME)
textFieldValue:self.cardholderName
textFieldEnabled:NO];
[model addItem:cardholderNameItem
textFieldEnabled:self.supportsEditing];
[model addItem:self.cardholderNameItem
toSectionWithIdentifier:SectionIdentifierContent];
// TODO(crbug.com/1014652): Change textFieldEnabled to YES once editing its
// supported.
TableViewTextEditItem* expireMonthItem = [self
self.expirationMonthItem = [self
textEditItemWithType:ItemTypeCardExpireYear
textFieldName:l10n_util::GetNSString(IDS_IOS_AUTOFILL_EXP_MONTH)
textFieldValue:self.expirationMonth
textFieldEnabled:NO];
[model addItem:expireMonthItem
textFieldEnabled:self.supportsEditing];
[model addItem:self.expirationMonthItem
toSectionWithIdentifier:SectionIdentifierContent];
// TODO(crbug.com/1014652): Change textFieldEnabled to YES once editing its
// supported.
TableViewTextEditItem* expireYearItem = [self
self.expirationYearItem = [self
textEditItemWithType:ItemTypeCardExpireYear
textFieldName:l10n_util::GetNSString(IDS_IOS_AUTOFILL_EXP_YEAR)
textFieldValue:self.expirationYear
textFieldEnabled:NO];
[model addItem:expireYearItem
textFieldEnabled:self.supportsEditing];
[model addItem:self.expirationYearItem
toSectionWithIdentifier:SectionIdentifierContent];
// Set legalMessagesStartingIndex right before adding any
......@@ -167,14 +174,14 @@ typedef NS_ENUM(NSInteger, ItemType) {
toSectionWithIdentifier:SectionIdentifierContent];
}
TableViewTextButtonItem* saveCardButtonItem =
self.saveCardButtonItem =
[[TableViewTextButtonItem alloc] initWithType:ItemTypeCardSave];
saveCardButtonItem.textAlignment = NSTextAlignmentNatural;
saveCardButtonItem.buttonText =
self.saveCardButtonItem.textAlignment = NSTextAlignmentNatural;
self.saveCardButtonItem.buttonText =
l10n_util::GetNSString(IDS_IOS_AUTOFILL_SAVE_CARD);
saveCardButtonItem.enabled = self.currentCardSaved;
saveCardButtonItem.disableButtonIntrinsicWidth = YES;
[model addItem:saveCardButtonItem
self.saveCardButtonItem.enabled = self.currentCardSaved;
self.saveCardButtonItem.disableButtonIntrinsicWidth = YES;
[model addItem:self.saveCardButtonItem
toSectionWithIdentifier:SectionIdentifierContent];
}
......@@ -286,22 +293,24 @@ typedef NS_ENUM(NSInteger, ItemType) {
#pragma mark - Private Methods
// Updates |self.saveCardButtonItem| enabled state taking into account the
// current editable items.
- (void)updateSaveCardButtonState {
// TODO(crbug.com/1014652): Implement
// TODO(crbug.com/1014652):Ideally the InfobarDelegate should update the
// button text. Once we have a consumer protocol we should be able to create a
// delegate that asks the InfobarDelegate for the correct text.
BOOL newButtonState = [self isCurrentInputValid];
if ([self.saveCardButtonItem isEnabled] != newButtonState) {
self.saveCardButtonItem.enabled = newButtonState;
[self reconfigureCellsForItems:@[ self.saveCardButtonItem ]];
}
}
- (void)saveCardButtonWasPressed:(UIButton*)sender {
base::RecordAction(
base::UserMetricsAction("MobileMessagesModalAcceptedTapped"));
[self.metricsRecorder recordModalEvent:MobileMessagesModalEvent::Accepted];
// TODO(crbug.com/1014652): Use current item values once editing is supported.
[self.saveCardModalDelegate saveCardWithCardholderName:self.cardholderName
expirationMonth:self.expirationMonth
expirationYear:self.expirationYear];
[self.saveCardModalDelegate
saveCardWithCardholderName:self.cardholderNameItem.textFieldValue
expirationMonth:self.expirationMonthItem.textFieldValue
expirationYear:self.expirationYearItem.textFieldValue];
}
- (void)nameEditDidBegin {
......@@ -345,4 +354,82 @@ typedef NS_ENUM(NSInteger, ItemType) {
return textEditItem;
}
// YES if the current values of the Card are valid.
// TODO(crbug.com/1029067):Ideally the InfobarDelegate should validate
// the correctness of the input.
- (BOOL)isCurrentInputValid {
if (![self isCardholderNameValid:self.cardholderNameItem.textFieldValue])
return NO;
if (![self isExpirationMonthValid:self.expirationMonthItem.textFieldValue
forYear:self.expirationYearItem.textFieldValue])
return NO;
if (![self isExpirationYearValid:self.expirationYearItem.textFieldValue])
return NO;
return YES;
}
// YES if |cardholderName| is valid.
- (BOOL)isCardholderNameValid:(NSString*)cardholderName {
// Check that the name is not empty or only whitespace.
NSCharacterSet* set = [NSCharacterSet whitespaceCharacterSet];
if (![[cardholderName stringByTrimmingCharactersInSet:set] length])
return NO;
return YES;
}
// YES if |expirationMonth| is valid for |expirationYear|.
- (BOOL)isExpirationMonthValid:(NSString*)expirationMonth
forYear:(NSString*)expirationYear {
NSNumber* expirationMonthNumber = [self numberFromString:expirationMonth];
if (!expirationMonthNumber)
return NO;
int expirationMonthInteger = [expirationMonthNumber intValue];
if (expirationMonthInteger <= 0 ||
expirationMonthInteger > kNumberOfMonthsInYear)
return NO;
if ([self currentYearIntValue] ==
[[self numberFromString:expirationYear] intValue])
return expirationMonthInteger >= [self currentMonthIntValue];
return YES;
}
// YES if |expirationYear| is valid for the current date.
- (BOOL)isExpirationYearValid:(NSString*)expirationYear {
NSNumber* expirationYearNumber = [self numberFromString:expirationYear];
if (!expirationYearNumber)
return NO;
return [self currentYearIntValue] <= [expirationYearNumber intValue];
}
// The current month int value.
- (int)currentMonthIntValue {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM"];
NSString* monthString = [dateFormatter stringFromDate:[NSDate date]];
return [[self numberFromString:monthString] intValue];
}
// The current year int value.
- (int)currentYearIntValue {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy"];
NSString* yearString = [dateFormatter stringFromDate:[NSDate date]];
return [[self numberFromString:yearString] intValue];
}
// Converts |string| into an NSNumber. returns nil if |string| is invalid.
- (NSNumber*)numberFromString:(NSString*)string {
NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
return [numberFormatter numberFromString:string];
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment