Skip to content

Commit

Permalink
Merge pull request #1529 from stripe-ios/kg-backendconsent
Browse files Browse the repository at this point in the history
Financial Connections: Refactored bold logic and refactored ClickableLabel
  • Loading branch information
kgaidis-stripe authored Oct 25, 2022
2 parents b86ddf9 + 6dd31dc commit aabbc75
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class ConnectAccountViewController: UIViewController {
self?.displayAlert("Failed!")
print(error)
}
self?.financialConnectionsSheet = nil // clear out strong reference
})
// Re-enable button
updateButtonState(isLoading: false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
3CE96D3427585BC6006B7059 /* FinancialConnectionsAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE96D3327585BC6006B7059 /* FinancialConnectionsAPIClient.swift */; };
3CE96D3627585F01006B7059 /* FinancialConnectionsSessionManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE96D3527585F01006B7059 /* FinancialConnectionsSessionManifest.swift */; };
3CE96D3A27586387006B7059 /* FinancialConnectionsSessionsGenerateHostedUrlBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CE96D3927586387006B7059 /* FinancialConnectionsSessionsGenerateHostedUrlBody.swift */; };
3CFC631A28EDCF8E00DF9D28 /* ContinueStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFC631928EDCF8E00DF9D28 /* ContinueStateView.swift */; };
6A0019D82880865E009D662A /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0019D72880865E009D662A /* StringExtensionsTests.swift */; };
6A0019DC2885EAAA009D662A /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 6A0019DB2885EAAA009D662A /* [email protected] */; };
6A0019DE2886F3B9009D662A /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0019DD2886F3B9009D662A /* UIViewController+Extensions.swift */; };
Expand Down Expand Up @@ -128,6 +129,7 @@
6A99EF6228E51F1F00C76293 /* LinkingAccountsLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A99EF6128E51F1F00C76293 /* LinkingAccountsLoadingView.swift */; };
6A99EF6428E5CFBD00C76293 /* AccountNumberRetrievalErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A99EF6328E5CFBD00C76293 /* AccountNumberRetrievalErrorView.swift */; };
6A99EF6628E708D200C76293 /* Button+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A99EF6528E708D200C76293 /* Button+Extensions.swift */; };
6AA280EC290098EF0071DEB5 /* PaneWithCustomHeaderLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AA280EB290098EF0071DEB5 /* PaneWithCustomHeaderLayoutView.swift */; };
6AB0199028E7C882004DB6E3 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 6AB0198E28E7C882004DB6E3 /* [email protected] */; };
6AB0199128E7C882004DB6E3 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 6AB0198F28E7C882004DB6E3 /* [email protected] */; };
6ABE2D04285A2DEF0064B3A4 /* ConsentBodyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6ABE2D03285A2DEF0064B3A4 /* ConsentBodyView.swift */; };
Expand All @@ -152,7 +154,6 @@
6AE5171C28AAF099006E8314 /* SuccessBodyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE5171B28AAF099006E8314 /* SuccessBodyView.swift */; };
6AE5171E28ABEF5A006E8314 /* SuccessAccountListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE5171D28ABEF5A006E8314 /* SuccessAccountListView.swift */; };
6AFD485128871A98003439CB /* FeaturedInstitutionGridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AFD485028871A98003439CB /* FeaturedInstitutionGridView.swift */; };
3CFC631A28EDCF8E00DF9D28 /* ContinueStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFC631928EDCF8E00DF9D28 /* ContinueStateView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -271,6 +272,7 @@
3CE96D3327585BC6006B7059 /* FinancialConnectionsAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FinancialConnectionsAPIClient.swift; sourceTree = "<group>"; };
3CE96D3527585F01006B7059 /* FinancialConnectionsSessionManifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FinancialConnectionsSessionManifest.swift; sourceTree = "<group>"; };
3CE96D3927586387006B7059 /* FinancialConnectionsSessionsGenerateHostedUrlBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FinancialConnectionsSessionsGenerateHostedUrlBody.swift; sourceTree = "<group>"; };
3CFC631928EDCF8E00DF9D28 /* ContinueStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContinueStateView.swift; sourceTree = "<group>"; };
6A0019D72880865E009D662A /* StringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = "<group>"; };
6A0019DB2885EAAA009D662A /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
6A0019DD2886F3B9009D662A /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extensions.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -342,6 +344,7 @@
6A99EF6128E51F1F00C76293 /* LinkingAccountsLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkingAccountsLoadingView.swift; sourceTree = "<group>"; };
6A99EF6328E5CFBD00C76293 /* AccountNumberRetrievalErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountNumberRetrievalErrorView.swift; sourceTree = "<group>"; };
6A99EF6528E708D200C76293 /* Button+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Button+Extensions.swift"; sourceTree = "<group>"; };
6AA280EB290098EF0071DEB5 /* PaneWithCustomHeaderLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaneWithCustomHeaderLayoutView.swift; sourceTree = "<group>"; };
6AB0198E28E7C882004DB6E3 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
6AB0198F28E7C882004DB6E3 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
6ABE2D03285A2DEF0064B3A4 /* ConsentBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsentBodyView.swift; sourceTree = "<group>"; };
Expand All @@ -366,7 +369,6 @@
6AE5171B28AAF099006E8314 /* SuccessBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessBodyView.swift; sourceTree = "<group>"; };
6AE5171D28ABEF5A006E8314 /* SuccessAccountListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessAccountListView.swift; sourceTree = "<group>"; };
6AFD485028871A98003439CB /* FeaturedInstitutionGridView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedInstitutionGridView.swift; sourceTree = "<group>"; };
3CFC631928EDCF8E00DF9D28 /* ContinueStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContinueStateView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -789,6 +791,7 @@
6A9117ED287F535C007633D4 /* DataAccessNoticeView.swift */,
6A038F08288F040800D3331D /* ReusableInformationView.swift */,
6A8B4B0228CFC7C600128356 /* PaneLayoutView.swift */,
6AA280EB290098EF0071DEB5 /* PaneWithCustomHeaderLayoutView.swift */,
6A8B4B0428CFD31800128356 /* PaneWithHeaderLayoutView.swift */,
6A7C861628D273940025B8DF /* SuccessIconView.swift */,
6AE2E5AC28DB916E00623523 /* MerchantDataAccessView.swift */,
Expand Down Expand Up @@ -1065,6 +1068,7 @@
6A8B4AFA28CAD40600128356 /* AccountPickerHelpers.swift in Sources */,
3CFC631A28EDCF8E00DF9D28 /* ContinueStateView.swift in Sources */,
3C34E0E92798EB33002618E4 /* FinancialConnectionsSession.swift in Sources */,
6AA280EC290098EF0071DEB5 /* PaneWithCustomHeaderLayoutView.swift in Sources */,
3CAD99B2284ADDD400B163EB /* HostController.swift in Sources */,
6A9117E7287CB20D007633D4 /* String+Extensions.swift in Sources */,
6A2318D428B3C36000F2A7D8 /* AccountPickerSelectionListView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import UIKit

extension NSMutableAttributedString {

/// Adds `boldFont` as an attribute in all the places that are surrounded by asterisks (ex. `*bold string here*).
/// Adds `boldFont` as an attribute in all the places that are surrounded by asterisks (ex. `**bold string here**).
///
/// For example, `Click *here*` returns `Click here` with "here" being applied the `boldFont` as attribute.
/// For example, `Click **here**` returns `Click here` with "here" being applied the `boldFont` as attribute.
func addBoldFontAttributesByMarkdownRules(boldFont: UIFont) {
guard
// The regex will find all occurrances of tokens formatted as: `*bold string here*`
let regularExpression = try? NSRegularExpression(pattern: #"\*[^\*\n]*\*"#, options: NSRegularExpression.Options(rawValue: 0))
// The regex will find all occurrances of tokens formatted as: `**bold string here**`
let regularExpression = try? NSRegularExpression(pattern: #"\*\*[^\*\n]+\*\*"#, options: NSRegularExpression.Options(rawValue: 0))
else {
return
}
Expand All @@ -29,9 +29,9 @@ extension NSMutableAttributedString {
range: NSRange(location: 0, length: string.count)
)
{
// range where `*bold string here*` token is
// range where `**bold string here**` token is
let markdownBoldRange = textCheckingResult.range
// the string `*bold string here*`
// the string `**bold string here**`
let markdownBoldString = attributedSubstring(from: markdownBoldRange)

// the string `bold string here`
Expand All @@ -56,10 +56,10 @@ extension NSAttributedString {

/// Extracts a substring out of the first set of asterisks.
///
/// For example, `Bold Text` out of `*Bold Text*`.
/// For example, `Bold Text` out of `**Bold Text**`.
fileprivate func extractStringInAsterisks() -> NSAttributedString? {
guard
let regularExpression = try? NSRegularExpression(pattern: #"(?<=\*)[^\*\n]*(?=\*)"#, options: NSRegularExpression.Options(rawValue: 0))
let regularExpression = try? NSRegularExpression(pattern: #"(?<=\*\*)[^\*\n]*(?=\*\*)"#, options: NSRegularExpression.Options(rawValue: 0))
else {
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ private func CreateLabelView(text: String, action: @escaping (URL) -> Void) -> U
// skip `imageView.heightAnchor` so the labels naturally expand
])

let label = ClickableLabel()
let label = ClickableLabel(
font: UIFont.stripeFont(forTextStyle: .detail),
boldFont: UIFont.stripeFont(forTextStyle: .detailEmphasized),
linkFont: UIFont.stripeFont(forTextStyle: .detailEmphasized),
textColor: .textSecondary
)
label.setText(text, action: action)

let horizontalStackView = UIStackView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ class ConsentFooterView: UIView {

backgroundColor = .customBackgroundColor

let termsAndPrivacyPolicyLabel = ClickableLabel()
termsAndPrivacyPolicyLabel.setText(
footerText,
let termsAndPrivacyPolicyLabel = ClickableLabel(
font: UIFont.stripeFont(forTextStyle: .detail),
boldFont: UIFont.stripeFont(forTextStyle: .detailEmphasized),
linkFont: UIFont.stripeFont(forTextStyle: .detailEmphasized),
textColor: .textSecondary,
alignCenter: true
)
termsAndPrivacyPolicyLabel.setText(footerText)

let verticalStackView = UIStackView(
arrangedSubviews: [
Expand All @@ -65,10 +68,15 @@ class ConsentFooterView: UIView {
text = "[\(localizedText)](https://www.urlIsIgnored.com)"
}

let manuallyVerifyLabel = ClickableLabel()
let manuallyVerifyLabel = ClickableLabel(
font: UIFont.stripeFont(forTextStyle: .detail),
boldFont: UIFont.stripeFont(forTextStyle: .detailEmphasized),
linkFont: UIFont.stripeFont(forTextStyle: .detailEmphasized),
textColor: .textSecondary,
alignCenter: true
)
manuallyVerifyLabel.setText(
text,
alignCenter: true,
action: { _ in
didSelectManuallyVerify()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct ConsentModel {
private let businessName: String

var headerText: String {
return "\(businessName) works with Stripe to link your accounts."
return "\(businessName) works with **Stripe** to link your accounts."
}

var bodyItems: [BodyBulletItem] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ class ConsentViewController: UIViewController {
private let dataSource: ConsentDataSource
weak var delegate: ConsentViewControllerDelegate?

private lazy var titleLabel: ClickableLabel = {
let titleLabel = ClickableLabel(
font: .stripeFont(forTextStyle: .subtitle),
boldFont: .stripeFont(forTextStyle: .subtitle),
linkFont: .stripeFont(forTextStyle: .subtitle),
textColor: .textPrimary
)
return titleLabel
}()
private lazy var footerView: ConsentFooterView = {
return ConsentFooterView(
footerText: dataSource.consentModel.footerText,
Expand All @@ -48,8 +57,10 @@ class ConsentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .customBackgroundColor
let paneLayoutView = PaneWithHeaderLayoutView(
title: dataSource.consentModel.headerText,

titleLabel.setText(dataSource.consentModel.headerText)
let paneLayoutView = PaneWithCustomHeaderLayoutView(
headerView: titleLabel,
contentView: ConsentBodyView(
bulletItems: dataSource.consentModel.bodyItems,
dataAccessNoticeModel: dataSource.consentModel.dataAccessNoticeModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,27 +82,25 @@ private func CreateTitleLabel() -> UIView {
private func CreateSubtitleLabel(
didSelectEnterYourBankDetailsManually: (() -> Void)?
) -> UIView {
let subtitleLabel = ClickableLabel()
let subtitleLabel = ClickableLabel(
font: .stripeFont(forTextStyle: .caption),
boldFont: .stripeFont(forTextStyle: .captionEmphasized),
linkFont: .stripeFont(forTextStyle: .captionEmphasized),
textColor: .textSecondary,
alignCenter: true
)
if let didSelectEnterYourBankDetailsManually = didSelectEnterYourBankDetailsManually {
let pleaseTryAgainLaterString = STPLocalizedString("Please try again later or %@.", "Part of the subtitle of an error message that appears when a user searches for a bank, but there's an issue, or error. It instructs the user to try searching again later. '%@' will be replaced by 'enter your bank details manually' to form 'Please try again later or enter your bank details manually.'.")
let enterYourBankDetailsManuallyString = STPLocalizedString("enter your bank details manually", "Part of the subtitle of an error message that appears when a user searches for a bank, but there's an issue, or error. This 'part' will be placed into a full string that says 'Please try again later or enter your bank details manually.'")
subtitleLabel.setText(
String(format: pleaseTryAgainLaterString, "[\(enterYourBankDetailsManuallyString)](https://www.use-action-instead.com)"),
font: .stripeFont(forTextStyle: .caption),
linkFont: .stripeFont(forTextStyle: .captionEmphasized),
textColor: .textSecondary,
alignCenter: true,
action: { _ in
didSelectEnterYourBankDetailsManually()
}
)
} else {
subtitleLabel.setText(
STPLocalizedString("Please try again later.", "The subtitle of an error message that appears when a user searches for a bank, but there's an issue, or error. It instructs the user to try searching again later."),
font: .stripeFont(forTextStyle: .caption),
linkFont: .stripeFont(forTextStyle: .captionEmphasized),
textColor: .textSecondary,
alignCenter: true
STPLocalizedString("Please try again later.", "The subtitle of an error message that appears when a user searches for a bank, but there's an issue, or error. It instructs the user to try searching again later.")
)
}
return subtitleLabel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,24 +150,21 @@ private func CreateRowLabelView(
title: String,
customAction: (() -> Void)? = nil
) -> UIView {
let titleLabel = ClickableLabel()
let titleLabel = ClickableLabel(
font: .stripeFont(forTextStyle: .captionTightEmphasized),
boldFont: .stripeFont(forTextStyle: .captionTightEmphasized),
linkFont: .stripeFont(forTextStyle: .captionTightEmphasized),
textColor: .textPrimary
)
if let customAction = customAction {
titleLabel.setText(
title,
font: .stripeFont(forTextStyle: .captionTightEmphasized),
linkFont: .stripeFont(forTextStyle: .captionTightEmphasized),
textColor: .textPrimary,
action: { _ in
customAction()
}
)
} else {
titleLabel.setText(
title,
font: .stripeFont(forTextStyle: .captionTightEmphasized),
linkFont: .stripeFont(forTextStyle: .captionTightEmphasized),
textColor: .textPrimary
)
titleLabel.setText(title)
}
return titleLabel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,17 @@ private func CreatePartnerDisclosureView(
}

horizontalStackView.addArrangedSubview({
let partnerDisclosureLabel = ClickableLabel()
let partnerDisclosureLabel = ClickableLabel(
font: .stripeFont(forTextStyle: .captionTight),
boldFont: .stripeFont(forTextStyle: .captionTightEmphasized),
linkFont: .stripeFont(forTextStyle: .captionTightEmphasized),
textColor: .textSecondary
)
partnerDisclosureLabel.setText(
CreatePartnerDisclosureText(
partnerName: partner.name,
isStripeDirect: isStripeDirect
),
font: .stripeFont(forTextStyle: .captionTight),
linkFont: .stripeFont(forTextStyle: .captionTightEmphasized)
)
)
return partnerDisclosureLabel
}())
Expand Down
Loading

0 comments on commit aabbc75

Please sign in to comment.