Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(GiniHealthSDK): Present all payment providers IPC-231 #476

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ extension String {
func toColor() -> UIColor? {
return UIColor(hex: String.rgbaHexFrom(rgbHex: self))
}

func canOpenURLString() -> Bool {
if let url = URL(string: self) {
if UIApplication.shared.canOpenURL(url) {
return true
}
}
return false
}
}

public extension String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,15 @@ class BankSelectionTableViewCell: UITableViewCell {
selectedBorderColor: cellViewModel.selectedBankBorderColor,
notSelectedBorderColor: cellViewModel.notSelectedBankBorderColor)

appStoreImageView.isHidden = !cellViewModel.shouldShowAppStoreIcon
selectionIndicatorImageView.image = cellViewModel.selectionIndicatorImage
selectionIndicatorImageView.isHidden = !cellViewModel.shouldShowSelectionIcon

appStoreBankNameSpacingConstraint.priority = !cellViewModel.shouldShowAppStoreIcon ? .required - 1 : .required
selectionIndicatorBankNameSpacingConstraint.priority = !cellViewModel.shouldShowSelectionIcon ? .required - 1 : .required
}
}

@IBOutlet private weak var cellView: UIView!
@IBOutlet private weak var bankImageView: UIImageView!
@IBOutlet private weak var bankNameLabel: UILabel!
@IBOutlet private weak var appStoreImageView: UIImageView!
@IBOutlet private weak var selectionIndicatorImageView: UIImageView!
@IBOutlet private weak var appStoreBankNameSpacingConstraint: NSLayoutConstraint!
@IBOutlet private weak var selectionIndicatorBankNameSpacingConstraint: NSLayoutConstraint!

override func awakeFromNib() {
super.awakeFromNib()
Expand All @@ -58,12 +51,6 @@ class BankSelectionTableViewCell: UITableViewCell {
cellView.layer.borderWidth = Constants.notSelectedBorderWidth
}
}

override func prepareForReuse() {
super.prepareForReuse()
appStoreBankNameSpacingConstraint.priority = .required - 1
selectionIndicatorBankNameSpacingConstraint.priority = .required - 1
}
}

extension BankSelectionTableViewCell {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,9 @@ import GiniHealthAPILibrary
final class BankSelectionTableViewCellModel {

private var isSelected: Bool = false
private var isPaymentProviderInstalled = false

var shouldShowAppStoreIcon: Bool {
!isPaymentProviderInstalled
}
var shouldShowSelectionIcon: Bool {
isPaymentProviderInstalled && isSelected
isSelected
}

let backgroundColor: UIColor = GiniColor(lightModeColor: UIColor.GiniHealthColors.dark7,
Expand Down Expand Up @@ -47,7 +43,6 @@ final class BankSelectionTableViewCellModel {

init(paymentProvider: PaymentProviderAdditionalInfo) {
self.isSelected = paymentProvider.isSelected
self.isPaymentProviderInstalled = paymentProvider.isInstalled
self.bankImageIconData = paymentProvider.paymentProvider.iconData
self.bankName = paymentProvider.paymentProvider.name

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ class BanksBottomView: UIView {
setupViewHierarchy()
setupViewAttributes()
setupLayout()
setupListeners()
}

private func setupViewHierarchy() {
Expand Down Expand Up @@ -126,18 +125,6 @@ class BanksBottomView: UIView {
setupTableViewConstraints()
setupPoweredByGiniConstraints()
}

private func setupListeners() {
NotificationCenter.default.addObserver(self,
selector: #selector(willEnterForeground),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}

@objc private func willEnterForeground() {
viewModel.updatePaymentProvidersInstalledState()
paymentProvidersTableView.reloadData()
}

private func setupTopRectangleConstraints() {
NSLayoutConstraint.activate([
Expand Down Expand Up @@ -245,10 +232,6 @@ extension BanksBottomView: UITableViewDataSource, UITableViewDelegate {
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if viewModel.paymentProviders[indexPath.row].isInstalled {
viewModel.viewDelegate?.didSelectPaymentProvider(paymentProvider: viewModel.paymentProviders[indexPath.row].paymentProvider)
} else {
openPaymentProvidersAppStoreLink(urlString: viewModel.paymentProviders[indexPath.row].paymentProvider.appStoreUrlIOS)
}
viewModel.viewDelegate?.didSelectPaymentProvider(paymentProvider: viewModel.paymentProviders[indexPath.row].paymentProvider)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ final class BanksBottomViewModel {
let descriptionLabelAccentColor: UIColor = GiniColor(lightModeColor: UIColor.GiniHealthColors.dark3,
darkModeColor: UIColor.GiniHealthColors.light3).uiColor()
var descriptionLabelFont: UIFont

private var urlOpener: URLOpener

init(paymentProviders: PaymentProviders, selectedPaymentProvider: PaymentProvider?) {
init(paymentProviders: PaymentProviders, selectedPaymentProvider: PaymentProvider?, urlOpener: URLOpener = URLOpener(UIApplication.shared)) {
self.selectedPaymentProvider = selectedPaymentProvider
self.urlOpener = urlOpener

let defaultRegularFont: UIFont = UIFont.systemFont(ofSize: 14, weight: .regular)
let defaultBoldFont: UIFont = UIFont.systemFont(ofSize: 14, weight: .bold)
Expand All @@ -64,26 +67,13 @@ final class BanksBottomViewModel {
self.descriptionLabelFont = GiniHealthConfiguration.shared.textStyleFonts[.caption1] ?? defaultRegularFont

self.paymentProviders = paymentProviders
.filter({ $0.appStoreUrlIOS != nil || isPaymentProviderInstalled(paymentProvider: $0) })
.map({ PaymentProviderAdditionalInfo(isSelected: $0.id == selectedPaymentProvider?.id,
isInstalled: isPaymentProviderInstalled(paymentProvider: $0),
paymentProvider: $0)})

.sorted(by: { $0.isInstalled && !$1.isInstalled })
self.calculateHeights()
}

func updatePaymentProvidersInstalledState() {
for index in 0 ..< paymentProviders.count {
paymentProviders[index].isInstalled = isPaymentProviderInstalled(paymentProvider: paymentProviders[index].paymentProvider)
}
if selectedPaymentProvider == nil {
selectedPaymentProvider = paymentProviders.first(where: { $0.isInstalled == true })?.paymentProvider
if let indexSelected = paymentProviders.firstIndex(where: { $0.paymentProvider.id == selectedPaymentProvider?.id }) {
paymentProviders[indexSelected].isSelected = true
}
}
}

private func calculateHeights() {
let totalTableViewHeight = CGFloat(paymentProviders.count) * Constants.cellSizeHeight
let totalBottomViewHeight = Constants.blankBottomViewHeight + totalTableViewHeight
Expand All @@ -105,7 +95,10 @@ final class BanksBottomViewModel {
}

private func isPaymentProviderInstalled(paymentProvider: PaymentProvider) -> Bool {
paymentProvider.appSchemeIOS.canOpenURLString()
if let urlAppScheme = URL(string: paymentProvider.appSchemeIOS) {
return urlOpener.canOpenLink(url: urlAppScheme)
}
return false
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ final class PaymentComponentView: UIView {
button.customConfigure(labelText: viewModel.bankNameLabelText,
leftImageIcon: viewModel.bankImageIcon,
rightImageIcon: viewModel.chevronDownIconName,
rightImageTintColor: viewModel.chevronDownIconColor,
isPaymentProviderInstalled: viewModel.isPaymentProviderInstalled,
notInstalledTextColor: viewModel.notInstalledBankTextColor)
rightImageTintColor: viewModel.chevronDownIconColor)
return button
}()

Expand All @@ -113,8 +111,7 @@ final class PaymentComponentView: UIView {
button.translatesAutoresizingMaskIntoConstraints = false
button.frame = CGRect(x: 0, y: 0, width: .greatestFiniteMagnitude, height: Constants.buttonViewHeight)
button.configure(with: viewModel.giniHealthConfiguration.primaryButtonConfiguration)
button.customConfigure(paymentProviderColors: viewModel.paymentProviderColors,
isPaymentProviderInstalled: viewModel.isPaymentProviderInstalled,
button.customConfigure(paymentProviderColors: viewModel.paymentProviderColors,
text: viewModel.payInvoiceLabelText)
return button
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ final class PaymentComponentViewModel {
private var bankName: String?
var bankNameLabelText: String {
if let bankName, !bankName.isEmpty {
return isPaymentProviderInstalled ? bankName : placeholderBankNameText
return bankName
}
return placeholderBankNameText
}
Expand All @@ -110,13 +110,6 @@ final class PaymentComponentViewModel {
let payInvoiceLabelText: String = NSLocalizedStringPreferredFormat("ginihealth.paymentcomponent.payInvoice.label",
comment: "Title label used for the pay invoice button")

// Payment provider installation status
var isPaymentProviderInstalled: Bool {
if let paymentProviderScheme, let url = URL(string: paymentProviderScheme), UIApplication.shared.canOpenURL(url) {
return true
}
return false
}
private var paymentProviderScheme: String?

weak var delegate: PaymentComponentViewProtocol?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public final class PaymentComponentsController: PaymentComponentsProtocol {

private var giniHealth: GiniHealth
private var paymentProviders: PaymentProviders = []
private var installedPaymentProviders: PaymentProviders = []

/// storing the current selected payment provider
public var selectedPaymentProvider: PaymentProvider?
Expand Down Expand Up @@ -83,7 +82,7 @@ public final class PaymentComponentsController: PaymentComponentsProtocol {
- Returns: a Payment Provider object.
*/
private func defaultInstalledPaymentProvider() -> PaymentProvider? {
savedPaymentProvider() ?? installedPaymentProviders.first
savedPaymentProvider() ?? paymentProviders.first
}

/**
Expand All @@ -97,7 +96,6 @@ public final class PaymentComponentsController: PaymentComponentsProtocol {
switch result {
case let .success(paymentProviders):
self?.paymentProviders = paymentProviders
self?.checkInstalledPaymentProviders()
self?.selectedPaymentProvider = self?.defaultInstalledPaymentProvider()
self?.delegate?.didFetchedPaymentProviders()
case let .failure(error):
Expand All @@ -115,15 +113,6 @@ public final class PaymentComponentsController: PaymentComponentsProtocol {
}
}

private func checkInstalledPaymentProviders() {
installedPaymentProviders = []
for paymentProvider in paymentProviders {
if checkPaymentProviderIsInstalled(paymentProvider: paymentProvider) {
self.installedPaymentProviders.append(paymentProvider)
}
}
}

private func storeDefaultPaymentProvider(paymentProvider: PaymentProvider) {
do {
let encoder = JSONEncoder()
Expand All @@ -139,7 +128,7 @@ public final class PaymentComponentsController: PaymentComponentsProtocol {
do {
let decoder = JSONDecoder()
let paymentProvider = try decoder.decode(PaymentProvider.self, from: data)
if self.installedPaymentProviders.contains(where: { $0.id == paymentProvider.id }) {
if self.paymentProviders.contains(where: { $0.id == paymentProvider.id }) {
return paymentProvider
}
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ final class PaymentInfoViewModel {

init(paymentProviders: PaymentProviders) {
self.paymentProviders = paymentProviders
.filter({ $0.appStoreUrlIOS != nil || $0.appStoreUrlIOS?.canOpenURLString() ?? false })

let giniHealthConfiguration = GiniHealthConfiguration.shared

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ extension PaymentPrimaryButton {
}
}

func customConfigure(paymentProviderColors: ProviderColors?, isPaymentProviderInstalled: Bool, text: String, leftImageData: Data? = nil) {
if let backgroundHexColor = paymentProviderColors?.background.toColor(), isPaymentProviderInstalled {
func customConfigure(paymentProviderColors: ProviderColors?, text: String, leftImageData: Data? = nil) {
if let backgroundHexColor = paymentProviderColors?.background.toColor() {
contentView.backgroundColor = backgroundHexColor
}
contentView.isUserInteractionEnabled = isPaymentProviderInstalled
contentView.isUserInteractionEnabled = true

titleLabel.text = text
if let textHexColor = paymentProviderColors?.text.toColor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,15 @@ final class PaymentSecondaryButton: UIView {
])
}

private func activateBankImageViewConstraints(isPaymentProviderInstalled: Bool) {
if isPaymentProviderInstalled {
leftImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.contentLeadingPadding).isActive = true
leftImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
leftImageView.widthAnchor.constraint(equalToConstant: leftImageView.frame.width).isActive = true
leftImageView.heightAnchor.constraint(equalToConstant: leftImageView.frame.height).isActive = true
let bankNameBankViewConstraint = titleLabel.leadingAnchor.constraint(equalTo: leftImageView.trailingAnchor, constant: Constants.contentLeadingPadding)
bankNameBankViewConstraint.priority = .required - 1 // fix needed because of embeded views in cells issue. We need this to silent the "Unable to simultaneously satisfy constraints" warning
bankNameBankViewConstraint.isActive = true
leftImageView.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor).isActive = true
} else {
let bankNameLeadingSuperviewConstraint = titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.contentLeadingPadding)
bankNameLeadingSuperviewConstraint.priority = .required - 1
bankNameLeadingSuperviewConstraint.isActive = true
contentView.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor).isActive = true
}
private func activateBankImageViewConstraints() {
leftImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Constants.contentLeadingPadding).isActive = true
leftImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
leftImageView.widthAnchor.constraint(equalToConstant: leftImageView.frame.width).isActive = true
leftImageView.heightAnchor.constraint(equalToConstant: leftImageView.frame.height).isActive = true
let bankNameBankViewConstraint = titleLabel.leadingAnchor.constraint(equalTo: leftImageView.trailingAnchor, constant: Constants.contentLeadingPadding)
bankNameBankViewConstraint.priority = .required - 1 // fix needed because of embeded views in cells issue. We need this to silent the "Unable to simultaneously satisfy constraints" warning
bankNameBankViewConstraint.isActive = true
leftImageView.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor).isActive = true
}

@objc
Expand All @@ -110,8 +103,8 @@ extension PaymentSecondaryButton {
}
}

func customConfigure(labelText: String, leftImageIcon: UIImage?, rightImageIcon: String?, rightImageTintColor: UIColor, isPaymentProviderInstalled: Bool, notInstalledTextColor: UIColor) {
if let leftImageIcon, isPaymentProviderInstalled {
func customConfigure(labelText: String, leftImageIcon: UIImage?, rightImageIcon: String?, rightImageTintColor: UIColor) {
if let leftImageIcon {
leftImageView.image = leftImageIcon
leftImageView.isHidden = false
} else {
Expand All @@ -125,10 +118,7 @@ extension PaymentSecondaryButton {
rightImageView.isHidden = true
}
titleLabel.text = labelText
if !isPaymentProviderInstalled {
titleLabel.textColor = notInstalledTextColor
}
activateBankImageViewConstraints(isPaymentProviderInstalled: isPaymentProviderInstalled)
activateBankImageViewConstraints()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ public final class PaymentReviewViewController: UIViewController, UIGestureRecog
guard let model else { return }
payInvoiceButton.configure(with: giniHealthConfiguration.primaryButtonConfiguration)
payInvoiceButton.customConfigure(paymentProviderColors: selectedPaymentProvider?.colors,
isPaymentProviderInstalled: true,
text: model.payInvoiceLabelText,
leftImageData: selectedPaymentProvider?.iconData)
disablePayButtonIfNeeded()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public struct URLOpener {
completion?(false)
}
}

func canOpenLink(url: URL) -> Bool {
application.canOpenURL(url)
}
}

public protocol URLOpenerProtocol {
Expand Down
Loading
Loading