From c9f3da4d64e438ca6f4d330e361a235a2fd1a751 Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Tue, 16 Nov 2021 16:05:01 +0100 Subject: [PATCH 1/8] [Components] Add custom add card confirmation button --- BraintreeDropIn.xcodeproj/project.pbxproj | 8 ++ .../Components/SBTAddCardButtonFormField.h | 22 +++++ .../Components/SBTAddCardButtonFormField.m | 82 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.h create mode 100644 Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.m diff --git a/BraintreeDropIn.xcodeproj/project.pbxproj b/BraintreeDropIn.xcodeproj/project.pbxproj index 2e8f6d4c..2a8a983f 100644 --- a/BraintreeDropIn.xcodeproj/project.pbxproj +++ b/BraintreeDropIn.xcodeproj/project.pbxproj @@ -79,6 +79,8 @@ 425B83982347D3990015D1A4 /* BTUIKAppearanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425B83972347D3990015D1A4 /* BTUIKAppearanceTests.swift */; }; 42D53E782614DA3600D19615 /* BTUIKCardholderNameFormFieldTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42D53E772614DA3600D19615 /* BTUIKCardholderNameFormFieldTests.swift */; }; 42EA70662616682800B7E626 /* BTDropInResult_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 42EA70652616682800B7E626 /* BTDropInResult_Internal.h */; }; + 4C2901B02743FC0700505D46 /* SBTAddCardButtonFormField.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C2901AF2743FC0700505D46 /* SBTAddCardButtonFormField.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4C2901B22743FC1B00505D46 /* SBTAddCardButtonFormField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C2901B12743FC1B00505D46 /* SBTAddCardButtonFormField.m */; }; 8005E86125BB32A6003EC2AC /* MockVenmoDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8005E86025BB32A6003EC2AC /* MockVenmoDriver.swift */; }; 8005E86625BB34B5003EC2AC /* MockAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8005E86525BB34B5003EC2AC /* MockAPIClient.swift */; }; 8038FA13269789ED007BE751 /* MockPPDataCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8038FA12269789ED007BE751 /* MockPPDataCollector.swift */; }; @@ -234,6 +236,8 @@ 42A10AD8230EE4D600892302 /* UnitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Bridging-Header.h"; sourceTree = ""; }; 42D53E772614DA3600D19615 /* BTUIKCardholderNameFormFieldTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BTUIKCardholderNameFormFieldTests.swift; sourceTree = ""; }; 42EA70652616682800B7E626 /* BTDropInResult_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTDropInResult_Internal.h; sourceTree = ""; }; + 4C2901AF2743FC0700505D46 /* SBTAddCardButtonFormField.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SBTAddCardButtonFormField.h; sourceTree = ""; }; + 4C2901B12743FC1B00505D46 /* SBTAddCardButtonFormField.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SBTAddCardButtonFormField.m; sourceTree = ""; }; 53E78BDC22248A29000388D3 /* BTUIKHipercardVectorArtView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTUIKHipercardVectorArtView.h; sourceTree = ""; }; 53E78BDF22248A29000388D3 /* BTUIKHipercardVectorArtView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTUIKHipercardVectorArtView.m; sourceTree = ""; }; 53E78BE422248BC3000388D3 /* BTUIKLargeHiperVectorArtView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTUIKLargeHiperVectorArtView.h; sourceTree = ""; }; @@ -486,6 +490,8 @@ D6C2F3332239917F00DFF7E5 /* BTUIKSwitchFormField.m */, A52901161D8903A600032220 /* BTUIKTextField.h */, A52900E11D8903A600032220 /* BTUIKTextField.m */, + 4C2901AF2743FC0700505D46 /* SBTAddCardButtonFormField.h */, + 4C2901B12743FC1B00505D46 /* SBTAddCardButtonFormField.m */, ); path = Components; sourceTree = ""; @@ -733,6 +739,7 @@ buildActionMask = 2147483647; files = ( 4234907A260BA5800006D38B /* BTUIKInputAccessoryToolbar.h in Headers */, + 4C2901B02743FC0700505D46 /* SBTAddCardButtonFormField.h in Headers */, 42349098260BA6000006D38B /* BTDropInLocalization.h in Headers */, 42349062260BA5800006D38B /* BTUIKSecurityCodeFormField.h in Headers */, 8068E589256D9C68002904E6 /* BTUIKBarButtonItem_Internal_Declaration.h in Headers */, @@ -1031,6 +1038,7 @@ 80BBF006260BC77E005D646D /* BTUIKJCBVectorArtView.m in Sources */, A56C41901D833568000DFFAB /* BTDropInController.m in Sources */, 80BBEFAF260BC75C005D646D /* BTUIKLargeVisaVectorArtView.m in Sources */, + 4C2901B22743FC1B00505D46 /* SBTAddCardButtonFormField.m in Sources */, A56C41A21D8335BB000DFFAB /* BTEnrollmentVerificationViewController.m in Sources */, 4234905E260BA5800006D38B /* BTUIKPostalCodeFormField.m in Sources */, 42349006260BA3730006D38B /* BTUIKCardExpiryFormat.m in Sources */, diff --git a/Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.h b/Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.h new file mode 100644 index 00000000..dc984839 --- /dev/null +++ b/Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.h @@ -0,0 +1,22 @@ +// Copyright © 2019 Subito.it. All rights reserved. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SBTAddCardButtonFormField; + +@protocol SBTAddCardButtonFormFieldDelegate + +- (void)addCardFieldTapped:(SBTAddCardButtonFormField *)field; + +@end + +@interface SBTAddCardButtonFormField : UIView + +@property (nonatomic, weak) id delegate; +@property (nonatomic, assign, getter=isEnabled) BOOL enabled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.m b/Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.m new file mode 100644 index 00000000..a9f5dc7b --- /dev/null +++ b/Sources/BraintreeDropIn/Components/SBTAddCardButtonFormField.m @@ -0,0 +1,82 @@ +// Copyright © 2019 Subito.it. All rights reserved. + +#import "SBTAddCardButtonFormField.h" +#import "BTDropInLocalization_Internal.h" +#import "BTUIKAppearance.h" + +@interface UIImage (Color) + ++ (UIImage *)sbt_resizableImageWithColor:(UIColor *)color cornerRadius:(CGFloat)radius; + +@end + +@implementation UIImage (Color) + ++ (UIImage *)sbt_resizableImageWithColor:(UIColor *)color cornerRadius:(CGFloat)radius { + CGSize size = CGSizeMake((radius * 2.0) + 1.0, (radius * 2.0) + 1.0); + CGRect rect = CGRectMake(0.0, 0.0, size.width, size.height); + + UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size]; + UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { + CGContextRef contextRef = context.CGContext; + CGContextSetFillColorWithColor(contextRef, color.CGColor); + CGContextAddPath(contextRef, [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath); + CGContextFillPath(contextRef); + }]; + + UIEdgeInsets capInsets = UIEdgeInsetsMake(radius, radius, radius, radius); + return [image resizableImageWithCapInsets:capInsets]; +} + +@end + +@interface SBTAddCardButtonFormField () + +@property (nonatomic, strong) UIButton *addButton; + +@end + +@implementation SBTAddCardButtonFormField + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + UIImage *normalImage = [UIImage sbt_resizableImageWithColor:BTUIKAppearance.sharedInstance.tintColor cornerRadius:4.0]; + UIImage *disabledImage = [UIImage sbt_resizableImageWithColor:BTUIKAppearance.sharedInstance.disabledColor cornerRadius:4.0]; + UIImage *highlightedImage = [UIImage sbt_resizableImageWithColor:BTUIKAppearance.sharedInstance.highlightedTintColor cornerRadius:4.0]; + + _addButton = [UIButton new]; + _addButton.translatesAutoresizingMaskIntoConstraints = NO; + _addButton.titleLabel.font = [BTUIKAppearance.sharedInstance.headlineFont fontWithSize:UIFont.labelFontSize]; + [_addButton setBackgroundImage:normalImage forState:UIControlStateNormal]; + [_addButton setBackgroundImage:disabledImage forState:UIControlStateDisabled]; + [_addButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; + [_addButton setTitle:BTDropInLocalizedString(ADD_CARD_ACTION) forState:UIControlStateNormal]; + [_addButton addTarget:self action:@selector(tapped) forControlEvents:UIControlEventTouchUpInside]; + + [self addSubview:_addButton]; + + NSLayoutConstraint *heightConstraint = [_addButton.heightAnchor constraintEqualToConstant:44.0]; + heightConstraint.priority = UILayoutPriorityDefaultHigh; + + [NSLayoutConstraint activateConstraints:@[ + heightConstraint, + [_addButton.topAnchor constraintEqualToAnchor:self.topAnchor], + [_addButton.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], + [_addButton.leadingAnchor constraintEqualToAnchor:self.layoutMarginsGuide.leadingAnchor], + [_addButton.trailingAnchor constraintEqualToAnchor:self.layoutMarginsGuide.trailingAnchor] + ]]; + } + return self; +} + +- (void)setEnabled:(BOOL)enabled { + _enabled = enabled; + [self.addButton setEnabled:enabled]; +} + +- (void)tapped { + [self.delegate addCardFieldTapped:self]; +} + +@end + From 5038c2fe9bcc309ed586617a690e3f2cbb665f59 Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Tue, 16 Nov 2021 16:24:13 +0100 Subject: [PATCH 2/8] [Card Form] Replace bar button item with form field --- Demo/UITests/BraintreeDropIn_UITests.swift | 3 +- .../BTCardFormViewController.m | 58 +++++++++++-------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Demo/UITests/BraintreeDropIn_UITests.swift b/Demo/UITests/BraintreeDropIn_UITests.swift index 49608d57..48d1d7df 100644 --- a/Demo/UITests/BraintreeDropIn_UITests.swift +++ b/Demo/UITests/BraintreeDropIn_UITests.swift @@ -429,7 +429,8 @@ class BraintreeDropIn_CardholderNameRequired_UITests: XCTestCase { postalCodeField.forceTapElement() postalCodeField.typeText("12345") - XCTAssertFalse(app.buttons["Add Card"].isEnabled) + app.buttons["Add Card"].forceTapElement() + waitForElementToBeHittable(app.staticTexts["Attenzione"]) } func testDropIn_cardholderNameRequired_canAddCardWithName() { diff --git a/Sources/BraintreeDropIn/BTCardFormViewController.m b/Sources/BraintreeDropIn/BTCardFormViewController.m index 2ef0702a..7f299273 100644 --- a/Sources/BraintreeDropIn/BTCardFormViewController.m +++ b/Sources/BraintreeDropIn/BTCardFormViewController.m @@ -11,6 +11,7 @@ #import "BTUIKCardListLabel.h" #import "BTUIKViewUtil.h" #import "BTDropInLocalization_Internal.h" +#import "SBTAddCardButtonFormField.h" #if __has_include() // CocoaPods #import @@ -24,11 +25,12 @@ #import #endif -@interface BTCardFormViewController () +@interface BTCardFormViewController () @property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) UIView *scrollViewContentWrapper; @property (nonatomic, strong) UIStackView *stackView; +@property (nonatomic, strong) SBTAddCardButtonFormField *addCardField; @property (nonatomic, strong, readwrite) BTUIKCardNumberFormField *cardNumberField; @property (nonatomic, strong, readwrite) BTUIKCardholderNameFormField *cardholderNameField; @property (nonatomic, strong, readwrite) BTUIKExpiryFormField *expirationDateField; @@ -186,6 +188,8 @@ - (void)setupForm { self.mobileCountryCodeField.delegate = self; self.mobilePhoneField = [[BTUIKMobileNumberFormField alloc] init]; self.mobilePhoneField.delegate = self; + self.addCardField = [[SBTAddCardButtonFormField alloc] init]; + self.addCardField.delegate = self; self.cardNumberHeader = [BTDropInUIUtilities newStackView]; self.cardNumberHeader.layoutMargins = UIEdgeInsetsMake(0, [BTUIKAppearance verticalFormSpace], 0, [BTUIKAppearance verticalFormSpace]); @@ -199,7 +203,7 @@ - (void)setupForm { [BTDropInUIUtilities addSpacerToStackView:self.cardNumberHeader beforeView:cardNumberHeaderLabel size: [BTUIKAppearance verticalFormSpace]]; [self.stackView addArrangedSubview:self.cardNumberHeader]; - self.formFields = @[self.cardNumberField, self.cardholderNameField, self.expirationDateField, self.securityCodeField, self.postalCodeField, self.mobileCountryCodeField, self.mobilePhoneField]; + self.formFields = @[self.cardNumberField, self.cardholderNameField, self.expirationDateField, self.securityCodeField, self.postalCodeField, self.mobileCountryCodeField, self.mobilePhoneField, self.addCardField]; for (BTUIKFormField *formField in self.formFields) { [self.stackView addArrangedSubview:formField]; @@ -213,6 +217,7 @@ - (void)setupForm { self.postalCodeField.hidden = YES; self.mobileCountryCodeField.hidden = YES; self.mobilePhoneField.hidden = YES; + self.addCardField.hidden = YES; // Privacy Policy label UILabel *privacyPolicyLabel = [[UILabel alloc] init]; @@ -356,6 +361,7 @@ - (void)setCollapsed:(BOOL)collapsed { self.mobilePhoneField.hidden = ![self.requiredFields containsObject:self.mobilePhoneField] || collapsed; self.enrollmentFooter.hidden = self.mobilePhoneField.hidden; self.shouldVaultCardSwitchField.hidden = ![self shouldDisplaySaveCardToggle] || collapsed; + self.addCardField.hidden = self.collapsed; [self updateFormBorders]; } completion:^(__unused BOOL finished) { self.cardNumberFooter.hidden = !collapsed; @@ -368,9 +374,9 @@ - (void)setCollapsed:(BOOL)collapsed { self.mobilePhoneField.hidden = ![self.requiredFields containsObject:self.mobilePhoneField] || collapsed; self.enrollmentFooter.hidden = self.mobilePhoneField.hidden; self.shouldVaultCardSwitchField.hidden = ![self shouldDisplaySaveCardToggle] || collapsed; + self.addCardField.hidden = self.collapsed; [self updateFormBorders]; - [self updateSubmitButton]; }]; }); } @@ -383,15 +389,11 @@ - (BOOL)shouldDisplaySaveCardToggle { - (void)resetForm { self.navigationItem.leftBarButtonItem = [[BTUIKBarButtonItem alloc] initWithTitle:BTDropInLocalizedString(CANCEL_ACTION) style:UIBarButtonItemStylePlain target:self action:@selector(cancelTapped)]; - BTUIKBarButtonItem *addButton = [[BTUIKBarButtonItem alloc] initWithTitle:BTDropInLocalizedString(ADD_CARD_ACTION) style:UIBarButtonItemStylePlain target:self action:@selector(tokenizeCard)]; - addButton.bold = YES; - self.navigationItem.rightBarButtonItem = addButton; - - self.navigationItem.rightBarButtonItem.enabled = NO; - self.navigationItem.rightBarButtonItem.accessibilityHint = BTDropInLocalizedString(REVIEW_AND_TRY_AGAIN); for (BTUIKFormField *formField in self.formFields) { - formField.text = @""; + if ([formField respondsToSelector:@selector(setText:)]) { + formField.text = @""; + } formField.hidden = YES; } // Using ivar so that setter is not called @@ -478,16 +480,6 @@ - (BOOL)isFormValid { return isFormValid; } -- (void)updateSubmitButton { - if (!self.collapsed && [self isFormValid]) { - self.navigationItem.rightBarButtonItem.enabled = YES; - self.navigationItem.rightBarButtonItem.accessibilityHint = nil; - } else { - self.navigationItem.rightBarButtonItem.enabled = NO; - self.navigationItem.rightBarButtonItem.accessibilityHint = BTDropInLocalizedString(REVIEW_AND_TRY_AGAIN); - } -} - - (void)advanceFocusFromField:(BTUIKFormField *)currentField { NSUInteger currentIdx = [self.requiredFields indexOfObject:currentField]; if (currentIdx != NSNotFound && currentIdx < self.requiredFields.count - 1) { @@ -588,9 +580,9 @@ - (void)basicTokenization { spinner.activityIndicatorViewStyle = [BTUIKAppearance sharedInstance].activityIndicatorViewStyle; [spinner startAnimating]; - UIBarButtonItem *addCardButton = self.navigationItem.rightBarButtonItem; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner]; self.view.userInteractionEnabled = NO; + [self.addCardField setEnabled:NO]; __block UINavigationController *navController = self.navigationController; #pragma clang diagnostic push @@ -600,8 +592,9 @@ - (void)basicTokenization { #pragma clang diagnostic pop dispatch_async(dispatch_get_main_queue(), ^{ self.view.userInteractionEnabled = YES; + [self.addCardField setEnabled:YES]; - self.navigationItem.rightBarButtonItem = addCardButton; + self.navigationItem.rightBarButtonItem = nil; if (error != nil) { NSString *message = BTDropInLocalizedString(REVIEW_AND_TRY_AGAIN); @@ -634,6 +627,7 @@ - (void)enrollCard { currentViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner]; self.view.userInteractionEnabled = NO; + [self.addCardField setEnabled:NO]; }); [cardClient enrollCard:cardRequest completion:^(NSString * _Nullable enrollmentID, BOOL smsCodeRequired, NSError * _Nullable error) { @@ -684,6 +678,7 @@ - (void)enrollCard { enrollmentController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner]; self.view.userInteractionEnabled = NO; + [self.addCardField setEnabled:NO]; }); #pragma clang diagnostic push @@ -695,6 +690,7 @@ - (void)enrollCard { #pragma clang diagnostic pop dispatch_async(dispatch_get_main_queue(), ^{ self.view.userInteractionEnabled = YES; + [self.addCardField setEnabled:YES]; enrollmentController.navigationItem.rightBarButtonItem = originalRightBarButtonItem; if (error) { [enrollmentController smsErrorHidden:NO]; @@ -770,8 +766,6 @@ - (void)formFieldDidBeginEditing:(__unused BTUIKFormField *)formField { } - (void)formFieldDidChange:(BTUIKFormField *)formField { - [self updateSubmitButton]; - // When focus moves from card number field, display the error state if the value in the field is invalid if (formField == self.cardNumberField && self.cardNumberField.state == BTUIKCardNumberFormFieldStateDefault) { [self cardNumberErrorHidden:self.cardNumberField.displayAsValid]; @@ -823,4 +817,20 @@ - (BOOL)textFieldShouldReturn:(__unused UITextField *)textField { return YES; } +#pragma mark SBTAddCardButtonFormFieldDelegate + +- (void)addCardFieldTapped:(SBTAddCardButtonFormField __unused *)field { + if ([self isFormValid]) { + [self tokenizeCard]; + } else { + NSString *alertTitle = @"Attenzione"; + NSString *alertMessage = @"Controlla di aver compilato tutti i campi correttamente"; + UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alertTitle message:alertMessage preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:alertAction]; + + [self presentViewController:alertController animated:YES completion:nil]; + } +} + @end From 43e725549fa1de0299a55c1479381d46c3da01f2 Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Wed, 17 Apr 2024 14:45:09 +0200 Subject: [PATCH 3/8] [Card Form] Add spacing between add card button and privacy policy label --- Sources/BraintreeDropIn/BTCardFormViewController.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/BraintreeDropIn/BTCardFormViewController.m b/Sources/BraintreeDropIn/BTCardFormViewController.m index 7f299273..ac7ed6b5 100644 --- a/Sources/BraintreeDropIn/BTCardFormViewController.m +++ b/Sources/BraintreeDropIn/BTCardFormViewController.m @@ -235,6 +235,9 @@ - (void)setupForm { [BTDropInUIUtilities addSpacerToStackView:self.stackView beforeView:self.cardholderNameField size: [BTUIKAppearance verticalFormSpace]]; [BTDropInUIUtilities addSpacerToStackView:self.stackView beforeView:self.mobileCountryCodeField size: [BTUIKAppearance verticalFormSpace]]; + // Spacing between add card field and privacy policy label + [self.stackView setCustomSpacing:[BTUIKAppearance verticalFormSpaceTight] afterView:self.addCardField]; + self.cardNumberFooter = [BTDropInUIUtilities newStackView]; self.cardNumberFooter.layoutMargins = UIEdgeInsetsMake(0, [BTUIKAppearance verticalFormSpace], 0, [BTUIKAppearance verticalFormSpace]); self.cardNumberFooter.layoutMarginsRelativeArrangement = true; From a852f56e90d045b6314863d28cbc684a33f64ae3 Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Thu, 17 Feb 2022 10:19:13 +0100 Subject: [PATCH 4/8] [Localization] Customize SELECT_PAYMENT_LABEL string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed to “Metodo di pagamento” --- Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings b/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings index 83bec497..2d9fcd5c 100644 --- a/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings +++ b/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings @@ -42,7 +42,7 @@ "OTHER_LABEL" = "Altro"; "CREDIT_OR_DEBIT_CARD_LABEL" = "Carta di credito o di debito"; "RECENT_LABEL" = "Recenti"; -"SELECT_PAYMENT_LABEL" = "Seleziona metodo di pagamento"; +"SELECT_PAYMENT_LABEL" = "Metodo di pagamento"; "CONFIRM_ENROLLMENT_LABEL" = "Conferma registrazione"; "CONFIRM_ACTION" = "Conferma"; From c45a78337657c93f18507e230a0ee4b174261717 Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Tue, 16 Nov 2021 16:40:44 +0100 Subject: [PATCH 5/8] [Card Form] Animate footer dis/appearing as for other fields --- Sources/BraintreeDropIn/BTCardFormViewController.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/BraintreeDropIn/BTCardFormViewController.m b/Sources/BraintreeDropIn/BTCardFormViewController.m index ac7ed6b5..66b7f859 100644 --- a/Sources/BraintreeDropIn/BTCardFormViewController.m +++ b/Sources/BraintreeDropIn/BTCardFormViewController.m @@ -356,6 +356,7 @@ - (void)setCollapsed:(BOOL)collapsed { dispatch_async(dispatch_get_main_queue(), ^{ [UIView animateWithDuration:0.15 delay:0.0 options:UIViewAnimationOptionAllowAnimatedContent|UIViewAnimationOptionBeginFromCurrentState animations:^{ self.cardNumberHeader.hidden = !collapsed; + self.cardNumberFooter.hidden = !collapsed; self.cardholderNameField.hidden = (self.dropInRequest.cardholderNameSetting == BTFormFieldDisabled) || collapsed; self.expirationDateField.hidden = collapsed; self.securityCodeField.hidden = ![self.requiredFields containsObject:self.securityCodeField] || collapsed; From b9d4f730c92f3a01fdbada7a79507f79d9e23a2a Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Thu, 17 Feb 2022 10:20:19 +0100 Subject: [PATCH 6/8] [Localization] Customize CREDIT_OR_DEBIT_CARD_LABEL string Changed to "Carta di credito o di debito (bancomat)" --- Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings b/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings index 2d9fcd5c..e655bf10 100644 --- a/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings +++ b/Sources/BraintreeDropIn/Resources/it.lproj/BTUI.strings @@ -40,7 +40,7 @@ "MONTH_LABEL" = "Mese"; "OTHER_LABEL" = "Altro"; -"CREDIT_OR_DEBIT_CARD_LABEL" = "Carta di credito o di debito"; +"CREDIT_OR_DEBIT_CARD_LABEL" = "Carta di credito o di debito (bancomat)"; "RECENT_LABEL" = "Recenti"; "SELECT_PAYMENT_LABEL" = "Metodo di pagamento"; From 6a275e39e3568d0221af8dcb254e6a7bbb64f46a Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Thu, 18 Nov 2021 12:53:13 +0100 Subject: [PATCH 7/8] [Payment Selection] Improve Dynamic Type support --- .../BraintreeDropIn/Custom Views/BTDropInPaymentSelectionCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeDropIn/Custom Views/BTDropInPaymentSelectionCell.m b/Sources/BraintreeDropIn/Custom Views/BTDropInPaymentSelectionCell.m index ab05c65f..91964396 100644 --- a/Sources/BraintreeDropIn/Custom Views/BTDropInPaymentSelectionCell.m +++ b/Sources/BraintreeDropIn/Custom Views/BTDropInPaymentSelectionCell.m @@ -27,7 +27,7 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus self.label = [[UILabel alloc] init]; [BTUIKAppearance styleLabelPrimary:self.label]; - self.label.numberOfLines = 2; + self.label.numberOfLines = 0; self.label.translatesAutoresizingMaskIntoConstraints = NO; [self.labelContainer addArrangedSubview:self.label]; From 445609c3741bfe477ee28d29edb445a21cccdeb6 Mon Sep 17 00:00:00 2001 From: Davide Mazzoni Date: Mon, 21 Feb 2022 14:14:31 +0100 Subject: [PATCH 8/8] [PayPal] Support disabling vaulted PayPal accounts with PayPal enabled --- Sources/BraintreeDropIn/BTPaymentMethodNonce+DropIn.m | 2 +- Sources/BraintreeDropIn/Models/BTDropInRequest.m | 1 + .../BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h | 3 +++ UnitTests/BTDropInRequestTests.m | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/BraintreeDropIn/BTPaymentMethodNonce+DropIn.m b/Sources/BraintreeDropIn/BTPaymentMethodNonce+DropIn.m index 781d4793..7ebe42c5 100644 --- a/Sources/BraintreeDropIn/BTPaymentMethodNonce+DropIn.m +++ b/Sources/BraintreeDropIn/BTPaymentMethodNonce+DropIn.m @@ -37,7 +37,7 @@ - (NSString *)paymentDescription { - (BOOL)shouldDisplayVaultedNonceForRequest:(BTDropInRequest *)request config:(BTConfiguration *)configuration { if ([self isKindOfClass:BTCardNonce.class] && (request.cardDisabled || configuration.supportedCardTypes.count == 0)) { return NO; - } else if ([self isKindOfClass:BTPayPalAccountNonce.class] && (request.paypalDisabled || !configuration.isPayPalEnabled)) { + } else if ([self isKindOfClass:BTPayPalAccountNonce.class] && (request.paypalDisabled || request.vaultedPaypalAccountsDisabled || !configuration.isPayPalEnabled)) { return NO; } else if ([self isKindOfClass:BTVenmoAccountNonce.class] && (request.venmoDisabled || !configuration.isVenmoEnabled)) { return NO; diff --git a/Sources/BraintreeDropIn/Models/BTDropInRequest.m b/Sources/BraintreeDropIn/Models/BTDropInRequest.m index 7957fe2b..c28e9e6b 100644 --- a/Sources/BraintreeDropIn/Models/BTDropInRequest.m +++ b/Sources/BraintreeDropIn/Models/BTDropInRequest.m @@ -32,6 +32,7 @@ - (id)copyWithZone:(__unused NSZone *)zone { request.vaultManager = self.vaultManager; request.vaultCard = self.vaultCard; request.allowVaultCardOverride = self.allowVaultCardOverride; + request.vaultedPaypalAccountsDisabled = self.vaultedPaypalAccountsDisabled; return request; } diff --git a/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h b/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h index 2aa928d5..e768f68c 100644 --- a/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h +++ b/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h @@ -43,6 +43,9 @@ typedef NS_ENUM(NSInteger, BTFormFieldSetting) { /// Defaults to false. Set to true to hide all card logos for your account. @property (nonatomic, assign) BOOL cardLogosDisabled; +/// Defaults to false. Set to true to hide vaulted PayPal accounts even if enabled for your account. +@property (nonatomic, assign) BOOL vaultedPaypalAccountsDisabled; + /// Optional: Enable 3DS verification and specify options and additional information. /// /// Note: To encourage 3DS 2.0 flows, set `billingAddress`, `amount`, `email`, `mobilePhone` for best results. diff --git a/UnitTests/BTDropInRequestTests.m b/UnitTests/BTDropInRequestTests.m index 58518d46..0379cac2 100644 --- a/UnitTests/BTDropInRequestTests.m +++ b/UnitTests/BTDropInRequestTests.m @@ -52,6 +52,7 @@ - (void)test_copyProperties { originalRequest.vaultManager = YES; originalRequest.vaultCard = NO; originalRequest.allowVaultCardOverride = YES; + originalRequest.vaultedPaypalAccountsDisabled = YES; BTDropInRequest *copiedRequest = [originalRequest copy]; @@ -67,6 +68,7 @@ - (void)test_copyProperties { XCTAssertEqual(originalRequest.vaultManager, copiedRequest.vaultManager); XCTAssertEqual(originalRequest.vaultCard, copiedRequest.vaultCard); XCTAssertEqual(originalRequest.allowVaultCardOverride, copiedRequest.allowVaultCardOverride); + XCTAssertEqual(originalRequest.vaultedPaypalAccountsDisabled, copiedRequest.vaultedPaypalAccountsDisabled); XCTAssertEqual(originalRequest.threeDSecureRequest, copiedRequest.threeDSecureRequest); XCTAssertEqual(BTThreeDSecureVersion2, copiedRequest.threeDSecureRequest.versionRequested);