Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Stripe/StripeiOSTests/ConfirmButtonTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ConfirmButtonTests: XCTestCase {
]

for (backgroundColor, expectedForeground) in testCases {
let button = ConfirmButton.BuyButton()
let button = ConfirmButton.BuyButton(callToAction: .pay(amount: 900, currency: "usd"))
button.tintColor = backgroundColor
button.update(
status: .enabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,10 @@ class ConfirmButton: UIView {
}
}

private(set) var status: Status = .enabled
private(set) var callToAction: CallToActionType
Comment on lines -71 to -72
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These properties are moved to the BuyButton


// MARK: Private Properties
private lazy var buyButton: BuyButton = {
let buyButton = BuyButton(showProcessingLabel: showProcessingLabel, appearance: appearance)
buyButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
return buyButton
}()
private let buyButton: BuyButton
private let didTap: () -> Void
private let didTapWhenDisabled: () -> Void
private let appearance: PaymentSheet.Appearance
private let showProcessingLabel: Bool

// MARK: Init

Expand All @@ -92,13 +83,11 @@ class ConfirmButton: UIView {
didTap: @escaping () -> Void,
didTapWhenDisabled: @escaping () -> Void = {}
) {
self.status = status
self.callToAction = callToAction
self.showProcessingLabel = showProcessingLabel
self.appearance = appearance
self.buyButton = BuyButton(status: status, callToAction: callToAction, showProcessingLabel: showProcessingLabel, appearance: appearance)
self.didTap = didTap
self.didTapWhenDisabled = didTapWhenDisabled
super.init(frame: .zero)
buyButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
addAndPinSubview(buyButton)

update()
Expand All @@ -117,12 +106,12 @@ class ConfirmButton: UIView {
#if !os(visionOS)
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
self.buyButton.update(status: status, callToAction: callToAction, animated: false)
self.buyButton.update(status: buyButton.status, callToAction: buyButton.callToAction, animated: false)
}
#endif

@objc private func didBecomeActive() {
self.buyButton.update(status: self.status, callToAction: self.callToAction, animated: false)
self.buyButton.update(status: self.buyButton.status, callToAction: self.buyButton.callToAction, animated: false)
}

deinit {
Expand All @@ -138,8 +127,8 @@ class ConfirmButton: UIView {
completion: (() -> Void)? = nil
) {
update(
status: status ?? self.status,
callToAction: callToAction ?? self.callToAction,
status: status ?? self.buyButton.status,
callToAction: callToAction ?? self.buyButton.callToAction,
animated: animated,
completion: completion)
}
Expand All @@ -150,37 +139,21 @@ class ConfirmButton: UIView {
animated: Bool = false,
completion: (() -> Void)? = nil
) {
self.status = status
self.callToAction = callToAction

// Enable/disable
isUserInteractionEnabled = (status == .enabled || status == .disabled)

// Update the buy button; it has its own presentation logic
self.buyButton.update(status: status, callToAction: callToAction, animated: animated)

if let completion = completion {
let delay: TimeInterval = {
guard animated else {
return 0
}

return status == .succeeded
? PaymentSheetUI.delayBetweenSuccessAndDismissal
: PaymentSheetUI.defaultAnimationDuration
}()

DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: completion)
}
Comment on lines -153 to -174
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function and the old BuyButton.update functions are unified into a single BuyButton.update function. For now the ConfirmButton.update functions are just wrappers that pass the data to the BuyButton to complete all logic

self.buyButton.update(
status: status,
callToAction: callToAction,
animated: animated,
completion: completion
)
}

// MARK: - Private Methods

@objc
private func handleTap() {
if case .enabled = status {
if case .enabled = buyButton.status {
didTap()
} else if case .disabled = status {
} else if case .disabled = buyButton.status {
// When the disabled button is tapped, trigger validation error display
didTapWhenDisabled()
// Resign first responder (as we would if the button was disabled)
Expand All @@ -202,7 +175,8 @@ class ConfirmButton: UIView {
return appearance.primaryButton.successBackgroundColor
}

private var status: Status = .enabled
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, the ConfirmButton and BuyButton each had their own status property that needed to be kept in sync. Now there's only one, which is the BuyButton's

private(set) var status: Status
private(set) var callToAction: CallToActionType
private let appearance: PaymentSheet.Appearance
private let showProcessingLabel: Bool

Expand Down Expand Up @@ -289,9 +263,13 @@ class ConfirmButton: UIView {
var overriddenForegroundColor: UIColor?

init(
status: Status = .enabled,
callToAction: CallToActionType,
showProcessingLabel: Bool = true,
appearance: PaymentSheet.Appearance = .default
) {
self.status = status
self.callToAction = callToAction
self.showProcessingLabel = showProcessingLabel
self.appearance = appearance
super.init(frame: .zero)
Expand Down Expand Up @@ -368,8 +346,12 @@ class ConfirmButton: UIView {
fatalError("init(coder:) has not been implemented")
}

func update(status: Status, callToAction: CallToActionType, animated: Bool) {
func update(status: Status, callToAction: CallToActionType, animated: Bool, completion: (() -> Void)? = nil) {
self.status = status
self.callToAction = callToAction

// Enable/disable
isUserInteractionEnabled = (status == .enabled || status == .disabled)
Comment on lines +351 to +354
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from the old ConfirmButton.update function


// Update the label with a crossfade UIView.transition; UIView.animate doesn't provide an animation for text changes
let text: String? = {
Expand Down Expand Up @@ -504,6 +486,20 @@ class ConfirmButton: UIView {
self.animateSuccess()
}
}

if let completion = completion {
let delay: TimeInterval = {
guard animated else {
return 0
}

return status == .succeeded
? PaymentSheetUI.delayBetweenSuccessAndDismissal
: PaymentSheetUI.defaultAnimationDuration
}()

DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: completion)
}
Comment on lines +489 to +502
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from the old ConfirmButton.update function

}

private func applyCornerRadius() {
Expand Down
Loading