-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
💲[Native Checkout] Rewards Collection View Plumbing #664
Merged
ifbarrera
merged 12 commits into
feature-native-checkout
from
rewards-collection-view-plumbing
May 6, 2019
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
9406300
New files
ifbarrera b0aa974
removing scroll view stuff for now
ifbarrera 85db760
Tests
ifbarrera 48a3e1f
Cleaning up insets
ifbarrera 5fcf780
More cleanup
ifbarrera 21216ac
Swiftlint
ifbarrera 2e4ddc2
Adding “deprecated” to more file names
ifbarrera 8b7f848
Removing duplicated file
ifbarrera a405611
Increasing hit area of close button
ifbarrera 940fe9e
PR comments
ifbarrera 6ddc89b
Merge branch 'feature-native-checkout' of https://github.com/kickstar…
ifbarrera aa5a37e
PR comments
ifbarrera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
20 changes: 20 additions & 0 deletions
20
Kickstarter-iOS/DataSources/RewardsCollectionViewDataSource.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,20 @@ | ||
import Foundation | ||
import KsApi | ||
import Library | ||
|
||
final class RewardsCollectionViewDataSource: ValueCellDataSource { | ||
func load(rewards: [Reward]) { | ||
self.set(values: rewards, | ||
cellClass: RewardCell.self, | ||
inSection: 0) | ||
} | ||
|
||
override func configureCell(collectionCell cell: UICollectionViewCell, withValue value: Any) { | ||
switch (cell, value) { | ||
case let (cell as RewardCell, value as Reward): | ||
cell.configureWith(value: value) | ||
default: | ||
assertionFailure("Unrecognized (cell, value) combo.") | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
Kickstarter-iOS/DataSources/RewardsCollectionViewDataSourceTests.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,18 @@ | ||
import XCTest | ||
@testable import Kickstarter_Framework | ||
@testable import KsApi | ||
|
||
final class RewardsCollectionViewDataSourceTests: XCTestCase { | ||
private let dataSource = RewardsCollectionViewDataSource() | ||
private let collectionView = UICollectionView(frame: .zero, | ||
collectionViewLayout: UICollectionViewFlowLayout()) | ||
|
||
func testLoadRewards() { | ||
let rewards = [Reward.template, Reward.template] | ||
|
||
self.dataSource.load(rewards: rewards) | ||
|
||
XCTAssertEqual(1, self.dataSource.numberOfSections(in: self.collectionView)) | ||
XCTAssertEqual(2, self.dataSource.collectionView(self.collectionView, numberOfItemsInSection: 0)) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
import KsApi | ||
import Library | ||
import Prelude | ||
|
||
internal protocol RewardCellDelegate: class { | ||
/// Called when the reward cell needs to perform an expansion animation. | ||
func rewardCellWantsExpansion(_ cell: DeprecatedRewardCell) | ||
} | ||
|
||
internal final class DeprecatedRewardCell: UITableViewCell, ValueCell { | ||
internal var delegate: RewardCellDelegate? | ||
fileprivate let viewModel: RewardCellViewModelType = DeprecatedRewardCellViewModel() | ||
|
||
@IBOutlet fileprivate weak var allGoneContainerView: UIView! | ||
@IBOutlet fileprivate weak var allGoneLabel: UILabel! | ||
@IBOutlet fileprivate weak var cardView: UIView! | ||
@IBOutlet fileprivate weak var checkmarkImageView: UIImageView! | ||
@IBOutlet fileprivate weak var conversionLabel: UILabel! | ||
@IBOutlet fileprivate weak var descriptionLabel: UILabel! | ||
@IBOutlet fileprivate weak var estimatedDeliveryDateLabel: UILabel! | ||
@IBOutlet fileprivate weak var estimatedDeliveryLabel: UILabel! | ||
@IBOutlet fileprivate weak var estimatedDeliveryDateStackView: UIStackView! | ||
@IBOutlet fileprivate weak var footerLabel: UILabel! | ||
@IBOutlet fileprivate weak var footerStackView: UIStackView! | ||
@IBOutlet fileprivate weak var includesTitleLabel: UILabel! | ||
@IBOutlet fileprivate weak var itemsContainerStackView: UIStackView! | ||
@IBOutlet fileprivate weak var itemsHeaderStackView: UIStackView! | ||
@IBOutlet fileprivate weak var itemsStackView: UIStackView! | ||
@IBOutlet fileprivate weak var manageRewardButton: UIButton! | ||
@IBOutlet fileprivate weak var minimumLabel: UILabel! | ||
@IBOutlet fileprivate weak var minimumStackView: UIStackView! | ||
@IBOutlet fileprivate weak var rewardTitleLabel: UILabel! | ||
@IBOutlet fileprivate weak var rootStackView: UIStackView! | ||
@IBOutlet fileprivate weak var selectRewardButton: UIButton! | ||
@IBOutlet fileprivate weak var shippingLocationsLabel: UILabel! | ||
@IBOutlet fileprivate weak var shippingLocationsStackView: UIStackView! | ||
@IBOutlet fileprivate weak var shippingLocationsSummaryLabel: UILabel! | ||
@IBOutlet fileprivate var separatorViews: [UIView]! | ||
@IBOutlet fileprivate weak var titleDescriptionStackView: UIStackView! | ||
@IBOutlet fileprivate weak var viewYourPledgeButton: UIButton! | ||
@IBOutlet fileprivate weak var youreABackerCheckmarkImageView: UIImageView! | ||
@IBOutlet fileprivate weak var youreABackerContainerView: UIView! | ||
@IBOutlet fileprivate weak var youreABackerLabel: UILabel! | ||
@IBOutlet fileprivate weak var youreABackerStackView: UIStackView! | ||
|
||
internal override func awakeFromNib() { | ||
super.awakeFromNib() | ||
|
||
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped)) | ||
tapRecognizer.cancelsTouchesInView = false | ||
tapRecognizer.delaysTouchesBegan = false | ||
tapRecognizer.delaysTouchesEnded = false | ||
self.addGestureRecognizer(tapRecognizer) | ||
} | ||
|
||
@objc fileprivate func tapped() { | ||
self.viewModel.inputs.tapped() | ||
} | ||
|
||
internal func configureWith(value: (Project, Either<Reward, Backing>)) { | ||
self.viewModel.inputs.configureWith(project: value.0, rewardOrBacking: value.1) | ||
} | ||
|
||
internal override func bindStyles() { | ||
super.bindStyles() | ||
|
||
_ = self | ||
|> baseTableViewCellStyle() | ||
|> DeprecatedRewardCell.lens.accessibilityTraits .~ UIAccessibilityTraits.button.rawValue | ||
|> (DeprecatedRewardCell.lens.contentView..UIView.lens.layoutMargins) %~~ { _, cell in | ||
cell.traitCollection.isRegularRegular | ||
? .init(top: Styles.grid(2), left: Styles.grid(16), bottom: Styles.grid(4), right: Styles.grid(16)) | ||
: .init(top: Styles.grid(1), left: Styles.grid(2), bottom: Styles.grid(2), right: Styles.grid(2)) | ||
} | ||
|> DeprecatedRewardCell.lens.contentView..UIView.lens.backgroundColor .~ projectCellBackgroundColor() | ||
|> UIView.lens.contentMode .~ .top | ||
|
||
_ = self.rootStackView | ||
|> UIStackView.lens.spacing .~ Styles.grid(4) | ||
|> UIStackView.lens.layoutMargins | ||
.~ .init(top: Styles.grid(3), left: Styles.grid(2), bottom: Styles.grid(2), right: Styles.grid(2)) | ||
|> UIStackView.lens.isLayoutMarginsRelativeArrangement .~ true | ||
|
||
_ = self.minimumStackView | ||
|> UIStackView.lens.spacing .~ Styles.grid(1) | ||
|
||
_ = self.titleDescriptionStackView | ||
|> UIStackView.lens.spacing .~ Styles.grid(2) | ||
|
||
_ = self.footerStackView | ||
|> UIStackView.lens.spacing .~ Styles.grid(2) | ||
|
||
_ = [self.estimatedDeliveryDateStackView, self.shippingLocationsStackView] | ||
||> UIStackView.lens.spacing .~ Styles.gridHalf(1) | ||
|
||
_ = [self.itemsContainerStackView, self.itemsHeaderStackView, self.itemsStackView] | ||
||> UIStackView.lens.spacing .~ Styles.grid(2) | ||
|
||
_ = [self.minimumStackView, self.titleDescriptionStackView, | ||
self.itemsContainerStackView, self.footerStackView] | ||
||> UIStackView.lens.layoutMargins .~ .init(topBottom: 0, leftRight: Styles.grid(2)) | ||
||> UIStackView.lens.isLayoutMarginsRelativeArrangement .~ true | ||
|
||
_ = self.allGoneContainerView | ||
|> roundedStyle(cornerRadius: 2) | ||
|> UIView.lens.backgroundColor .~ UIColor.ksr_soft_black | ||
|> UIView.lens.layoutMargins .~ .init(topBottom: Styles.gridHalf(1), leftRight: Styles.grid(1)) | ||
|
||
_ = self.allGoneLabel | ||
|> UILabel.lens.textColor .~ .white | ||
|> UILabel.lens.font .~ .ksr_headline(size: 12) | ||
|> UILabel.lens.text %~ { _ in Strings.All_gone() } | ||
|
||
_ = self.cardView | ||
|> darkCardStyle(cornerRadius: 0) | ||
|> UIView.lens.backgroundColor .~ .white | ||
|
||
_ = self.minimumLabel | ||
|> UILabel.lens.font .~ .ksr_title2(size: 24) | ||
|
||
_ = self.conversionLabel | ||
|> UILabel.lens.font .~ UIFont.ksr_caption1().italicized | ||
|
||
_ = self.rewardTitleLabel | ||
|> UILabel.lens.font .~ .ksr_body(size: 18) | ||
|> UILabel.lens.numberOfLines .~ 0 | ||
|
||
_ = self.descriptionLabel | ||
|> UILabel.lens.font .~ .ksr_body(size: 16) | ||
|> UILabel.lens.textColor .~ .ksr_text_dark_grey_400 | ||
|> UILabel.lens.numberOfLines .~ 0 | ||
|
||
_ = self.estimatedDeliveryLabel | ||
|> UILabel.lens.text %~ { _ in Strings.Estimated_delivery().uppercased() } | ||
|> UILabel.lens.font .~ .ksr_caption1(size: 12) | ||
|> UILabel.lens.textColor .~ .ksr_text_dark_grey_400 | ||
|
||
_ = self.estimatedDeliveryDateLabel | ||
|> UILabel.lens.font .~ .ksr_caption1(size: 13) | ||
|> UILabel.lens.textColor .~ .ksr_soft_black | ||
|
||
_ = self.includesTitleLabel | ||
|> UILabel.lens.font .~ .ksr_headline(size: 13) | ||
|> UILabel.lens.textColor .~ .ksr_text_dark_grey_500 | ||
|> UILabel.lens.text %~ { _ in Strings.rewards_info_includes() } | ||
|
||
_ = self.shippingLocationsLabel | ||
|> UILabel.lens.text %~ { _ in Strings.Ships_to().uppercased() } | ||
|> UILabel.lens.font .~ .ksr_caption1(size: 12) | ||
|> UILabel.lens.textColor .~ .ksr_text_dark_grey_400 | ||
|
||
_ = self.shippingLocationsSummaryLabel | ||
|> UILabel.lens.font .~ .ksr_caption1(size: 13) | ||
|> UILabel.lens.textColor .~ .ksr_soft_black | ||
|
||
_ = self.youreABackerCheckmarkImageView | ||
|> UIImageView.lens.tintColor .~ .ksr_text_dark_grey_500 | ||
|> UIImageView.lens.image %~ { _ in | ||
UIImage(named: "checkmark-icon", in: .framework, compatibleWith: nil) | ||
} | ||
|
||
_ = self.youreABackerContainerView | ||
|> roundedStyle(cornerRadius: 2) | ||
|> UIView.lens.backgroundColor .~ UIColor.ksr_green_500 | ||
|> UIView.lens.layoutMargins .~ .init(topBottom: Styles.grid(1), leftRight: Styles.gridHalf(3)) | ||
|
||
_ = self.youreABackerLabel | ||
|> UILabel.lens.font .~ .ksr_headline(size: 12) | ||
|> UILabel.lens.textColor .~ .white | ||
|
||
_ = self.youreABackerStackView | ||
|> UIStackView.lens.spacing .~ Styles.gridHalf(1) | ||
|> UIStackView.lens.alignment .~ .center | ||
|
||
_ = self.checkmarkImageView | ||
|> UIImageView.lens.tintColor .~ .white | ||
|
||
_ = self.footerLabel | ||
|> UILabel.lens.font .~ .ksr_caption1(size: 13) | ||
|> UILabel.lens.textColor .~ .ksr_soft_black | ||
|
||
_ = self.separatorViews | ||
||> separatorStyle | ||
|
||
_ = self.selectRewardButton | ||
|> greenButtonStyle | ||
|> UIButton.lens.layer.cornerRadius .~ 0 | ||
|> UIButton.lens.isUserInteractionEnabled .~ false | ||
|> UIButton.lens.isAccessibilityElement .~ false | ||
|
||
_ = self.manageRewardButton | ||
|> greenBorderButtonStyle | ||
|> UIButton.lens.isUserInteractionEnabled .~ false | ||
|> UIButton.lens.title(for: .normal) %~ { _ in Strings.Manage_your_pledge() } | ||
|> UIButton.lens.isAccessibilityElement .~ false | ||
|
||
_ = self.viewYourPledgeButton | ||
|> borderButtonStyle | ||
|> UIButton.lens.isUserInteractionEnabled .~ false | ||
|> UIButton.lens.title(for: .normal) %~ { _ in Strings.View_your_pledge() } | ||
|> UIButton.lens.isAccessibilityElement .~ false | ||
|
||
self.viewModel.inputs.boundStyles() | ||
} | ||
|
||
internal override func bindViewModel() { | ||
super.bindViewModel() | ||
|
||
self.allGoneContainerView.rac.hidden = self.viewModel.outputs.allGoneHidden | ||
self.conversionLabel.rac.hidden = self.viewModel.outputs.conversionLabelHidden | ||
self.conversionLabel.rac.text = self.viewModel.outputs.conversionLabelText | ||
self.conversionLabel.rac.textColor = self.viewModel.outputs.minimumAndConversionLabelsColor | ||
self.descriptionLabel.rac.hidden = self.viewModel.outputs.descriptionLabelHidden | ||
self.descriptionLabel.rac.text = self.viewModel.outputs.descriptionLabelText | ||
self.estimatedDeliveryDateLabel.rac.text = self.viewModel.outputs.estimatedDeliveryDateLabelText | ||
self.footerStackView.rac.hidden = self.viewModel.outputs.footerStackViewHidden | ||
self.footerLabel.rac.text = self.viewModel.outputs.footerLabelText | ||
self.itemsContainerStackView.rac.hidden = self.viewModel.outputs.itemsContainerHidden | ||
self.manageRewardButton.rac.hidden = self.viewModel.outputs.manageButtonHidden | ||
self.minimumLabel.rac.text = self.viewModel.outputs.minimumLabelText | ||
self.minimumLabel.rac.textColor = self.viewModel.outputs.minimumAndConversionLabelsColor | ||
self.rewardTitleLabel.rac.hidden = self.viewModel.outputs.titleLabelHidden | ||
self.rewardTitleLabel.rac.text = self.viewModel.outputs.titleLabelText | ||
self.rewardTitleLabel.rac.textColor = self.viewModel.outputs.titleLabelTextColor | ||
self.selectRewardButton.rac.hidden = self.viewModel.outputs.pledgeButtonHidden | ||
self.selectRewardButton.rac.title = self.viewModel.outputs.pledgeButtonTitleText | ||
self.shippingLocationsStackView.rac.hidden = self.viewModel.outputs.shippingLocationsStackViewHidden | ||
self.shippingLocationsSummaryLabel.rac.text = self.viewModel.outputs.shippingLocationsSummaryLabelText | ||
self.viewYourPledgeButton.rac.hidden = self.viewModel.outputs.viewPledgeButtonHidden | ||
self.youreABackerContainerView.rac.hidden = self.viewModel.outputs.youreABackerViewHidden | ||
self.youreABackerLabel.rac.text = self.viewModel.outputs.youreABackerLabelText | ||
|
||
self.viewModel.outputs.notifyDelegateRewardCellWantsExpansion | ||
.observeForUI() | ||
.observeValues { [weak self] in | ||
self.doIfSome { $0.delegate?.rewardCellWantsExpansion($0) } | ||
} | ||
|
||
self.viewModel.outputs.updateTopMarginsForIsBacking | ||
.observeForUI() | ||
.observeValues { [weak self] isBacking in | ||
self?.contentView.layoutMargins.top = Styles.grid(isBacking ? 3 : 1) | ||
} | ||
|
||
self.viewModel.outputs.items | ||
.observeForUI() | ||
.observeValues { [weak self] in self?.load(items: $0) } | ||
} | ||
|
||
fileprivate func load(items: [String]) { | ||
self.itemsStackView.arrangedSubviews.forEach { $0.removeFromSuperview() } | ||
|
||
for item in items { | ||
let label = UILabel() | ||
|> UILabel.lens.font .~ .ksr_body(size: 14) | ||
|> UILabel.lens.textColor .~ .ksr_text_dark_grey_500 | ||
|> UILabel.lens.text .~ item | ||
|> UILabel.lens.numberOfLines .~ 0 | ||
|
||
let separator = UIView() | ||
|> separatorStyle | ||
separator.heightAnchor.constraint(equalToConstant: 1).isActive = true | ||
|
||
self.itemsStackView.addArrangedSubview(label) | ||
self.itemsStackView.addArrangedSubview(separator) | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing in this file is actually new. This file was renamed from
RewardCell.swift
->DeprecatedRewardCell.swift