-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MBL-1606] New Crowdfund Checkout UI (#2127)
* remove expandable header * replace summary section with pledge summary table * don't show pledge amount, total summary, and bonus amount sections * only show bonus amount in summary if it's greater than 0 * update pledge summary table cell UI * create new NoShippingPledgeRewardsSummaryTotalViewController * makes feature flagging easier * only add header labels to pledge summary table cells if feature flag is on * add new CTA container that includes the pledge amount * add title label * remove used outputs * fix tests * pledge rewards summary table test coverage * add snapshots
- Loading branch information
1 parent
0ff8bfe
commit 0986687
Showing
33 changed files
with
1,197 additions
and
544 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
195 changes: 195 additions & 0 deletions
195
...s/PledgePaymentMethods/Controller/NoShippingPledgeRewardsSummaryTotalViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
import Library | ||
import Prelude | ||
import UIKit | ||
|
||
final class NoShippingPledgeRewardsSummaryTotalViewController: UIViewController { | ||
// MARK: - Properties | ||
|
||
private let dataSource = NoShippingPledgeRewardsSummaryDataSource() | ||
|
||
private var tableViewContainerHeightConstraint: NSLayoutConstraint? | ||
|
||
private lazy var rootStackView: UIStackView = { | ||
UIStackView(frame: .zero) | ||
|> \.translatesAutoresizingMaskIntoConstraints .~ false | ||
}() | ||
|
||
private lazy var tableViewContainer: UIView = { | ||
UIView(frame: .zero) | ||
|> \.translatesAutoresizingMaskIntoConstraints .~ false | ||
|> \.clipsToBounds .~ true | ||
}() | ||
|
||
private lazy var tableView: UITableView = { | ||
ContentSizeTableView(frame: .zero, style: .plain) | ||
|> \.separatorInset .~ .zero | ||
|> \.contentInsetAdjustmentBehavior .~ .never | ||
|> \.isScrollEnabled .~ false | ||
|> \.dataSource .~ self.dataSource | ||
|> \.delegate .~ self | ||
|> \.rowHeight .~ UITableView.automaticDimension | ||
}() | ||
|
||
private lazy var separatorView: UIView = { UIView(frame: .zero) }() | ||
|
||
private lazy var pledgeTotalViewController = { | ||
PostCampaignPledgeRewardsSummaryTotalViewController.instantiate() | ||
}() | ||
|
||
private let viewModel: PostCampaignPledgeRewardsSummaryViewModelType = | ||
PostCampaignPledgeRewardsSummaryViewModel() | ||
|
||
// MARK: - Lifecycle | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
|
||
self.configureSubviews() | ||
self.setupConstraints() | ||
self.setEntireViewToIsHidden(true) | ||
|
||
self.viewModel.inputs.viewDidLoad() | ||
} | ||
|
||
private func configureSubviews() { | ||
_ = (self.rootStackView, self.view) | ||
|> ksr_addSubviewToParent() | ||
|> ksr_constrainViewToEdgesInParent() | ||
|
||
_ = ( | ||
[self.tableViewContainer, self.separatorView, self.pledgeTotalViewController.view], | ||
self.rootStackView | ||
) | ||
|> ksr_addArrangedSubviewsToStackView() | ||
|
||
_ = (self.tableView, self.tableViewContainer) | ||
|> ksr_addSubviewToParent() | ||
|
||
self.addChild(self.pledgeTotalViewController) | ||
self.pledgeTotalViewController.didMove(toParent: self) | ||
|
||
self.tableView.registerCellClass(PostCampaignPledgeRewardsSummaryHeaderCell.self) | ||
self.tableView.registerCellClass(PostCampaignPledgeRewardsSummaryCell.self) | ||
} | ||
|
||
override func viewWillLayoutSubviews() { | ||
super.viewWillLayoutSubviews() | ||
|
||
self.tableViewContainerHeightConstraint?.constant = self.tableView.intrinsicContentSize.height | ||
} | ||
|
||
private func setupConstraints() { | ||
let tableViewContainerHeightConstraint = self.tableViewContainer.heightAnchor | ||
.constraint(equalToConstant: 0) | ||
self.tableViewContainerHeightConstraint = tableViewContainerHeightConstraint | ||
|
||
NSLayoutConstraint.activate([ | ||
tableViewContainerHeightConstraint, | ||
self.tableView.leftAnchor.constraint(equalTo: self.tableViewContainer.leftAnchor), | ||
self.tableView.rightAnchor.constraint(equalTo: self.tableViewContainer.rightAnchor), | ||
self.tableView.topAnchor.constraint(equalTo: self.tableViewContainer.topAnchor), | ||
self.tableViewContainer.leftAnchor.constraint(equalTo: self.rootStackView.leftAnchor), | ||
self.tableViewContainer.rightAnchor.constraint(equalTo: self.rootStackView.rightAnchor), | ||
self.tableViewContainer.topAnchor.constraint(equalTo: self.rootStackView.topAnchor), | ||
self.separatorView.leftAnchor | ||
.constraint(equalTo: self.rootStackView.leftAnchor, constant: Styles.grid(4)), | ||
self.separatorView.rightAnchor | ||
.constraint(equalTo: self.rootStackView.rightAnchor, constant: -Styles.grid(4)), | ||
self.separatorView.heightAnchor.constraint(equalToConstant: 1), | ||
self.rootStackView.widthAnchor.constraint(equalTo: self.view.widthAnchor) | ||
]) | ||
} | ||
|
||
// MARK: - Bind Styles | ||
|
||
override func bindStyles() { | ||
super.bindStyles() | ||
|
||
_ = self.view | ||
|> \.clipsToBounds .~ true | ||
|> checkoutWhiteBackgroundStyle | ||
|
||
_ = self.rootStackView | ||
|> self.rootStackViewStyle | ||
|
||
_ = self.tableView | ||
|> checkoutWhiteBackgroundStyle | ||
|> \.translatesAutoresizingMaskIntoConstraints .~ false | ||
|
||
_ = self.separatorView | ||
|> self.separatorViewStyle | ||
|
||
self.tableViewContainerHeightConstraint?.constant = self.tableView.intrinsicContentSize.height | ||
} | ||
|
||
// MARK: - View model | ||
|
||
override func bindViewModel() { | ||
super.bindViewModel() | ||
|
||
self.viewModel.outputs.loadRewardsIntoDataSource | ||
.observeForUI() | ||
.observeValues { [weak self] data in | ||
guard let self else { return } | ||
|
||
self.dataSource.load(data) | ||
self.tableView.reloadData() | ||
self.tableView.setNeedsLayout() | ||
|
||
self.setEntireViewToIsHidden(false) | ||
self.tableViewContainerHeightConstraint?.constant = self.tableView.intrinsicContentSize.height | ||
} | ||
|
||
self.viewModel.outputs.configurePledgeTotalViewWithData | ||
.observeForUI() | ||
.observeValues { [weak self] data in | ||
guard let self else { return } | ||
|
||
self.pledgeTotalViewController.configure(with: data) | ||
} | ||
} | ||
|
||
// MARK: - Configuration | ||
|
||
func configureWith( | ||
rewardsData: PostCampaignRewardsSummaryViewData, | ||
bonusAmount: Double?, | ||
pledgeData: PledgeSummaryViewData | ||
) { | ||
self.viewModel.inputs | ||
.configureWith(rewardsData: rewardsData, bonusAmount: bonusAmount, pledgeData: pledgeData) | ||
|
||
self.view.setNeedsLayout() | ||
} | ||
|
||
// MARK: Styles | ||
|
||
private let rootStackViewStyle: StackViewStyle = { stackView in | ||
stackView | ||
|> \.axis .~ NSLayoutConstraint.Axis.vertical | ||
|> \.spacing .~ Styles.grid(1) | ||
|> \.isLayoutMarginsRelativeArrangement .~ true | ||
} | ||
|
||
private let separatorViewStyle: ViewStyle = { view in | ||
view | ||
|> \.backgroundColor .~ .ksr_support_200 | ||
|> \.translatesAutoresizingMaskIntoConstraints .~ false | ||
} | ||
|
||
// MARK: - Helpers | ||
|
||
private func setEntireViewToIsHidden(_ isHidden: Bool) { | ||
self.view.isHidden = isHidden | ||
self.pledgeTotalViewController.view.isHidden = isHidden | ||
self.separatorView.isHidden = isHidden | ||
} | ||
} | ||
|
||
// MARK: - UITableViewDelegate | ||
|
||
extension NoShippingPledgeRewardsSummaryTotalViewController: UITableViewDelegate { | ||
func tableView(_: UITableView, willSelectRowAt _: IndexPath) -> IndexPath? { | ||
return nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...S/Features/PledgePaymentMethods/Datasource/NoShippingPledgeRewardsSummaryDataSource.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import KsApi | ||
import Library | ||
import Prelude | ||
import UIKit | ||
|
||
internal final class NoShippingPledgeRewardsSummaryDataSource: ValueCellDataSource { | ||
internal enum Section: Int { | ||
case header | ||
case rewards | ||
} | ||
|
||
internal func load(_ items: [PostCampaignRewardsSummaryItem]) { | ||
self.clearValues() | ||
|
||
let headerItemData = items.compactMap { item -> PledgeExpandableHeaderRewardCellData? in | ||
guard case let .header(data) = item else { return nil } | ||
return data | ||
} | ||
|
||
let rewardItemData = items.compactMap { item -> PledgeExpandableHeaderRewardCellData? in | ||
guard case let .reward(data) = item else { return nil } | ||
return data | ||
} | ||
|
||
self.set( | ||
values: headerItemData, | ||
cellClass: PostCampaignPledgeRewardsSummaryHeaderCell.self, | ||
inSection: Section.header.rawValue | ||
) | ||
|
||
self.set( | ||
values: rewardItemData, | ||
cellClass: PostCampaignPledgeRewardsSummaryCell.self, | ||
inSection: Section.rewards.rawValue | ||
) | ||
} | ||
|
||
override func configureCell(tableCell cell: UITableViewCell, withValue value: Any) { | ||
switch (cell, value) { | ||
case let ( | ||
cell as PostCampaignPledgeRewardsSummaryHeaderCell, | ||
value as PledgeExpandableHeaderRewardCellData | ||
): | ||
cell.configureWith(value: value) | ||
case let (cell as PostCampaignPledgeRewardsSummaryCell, value as PledgeExpandableHeaderRewardCellData): | ||
cell.configureWith(value: value) | ||
default: | ||
assertionFailure("Unrecognized combo: \(cell), \(value)") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.