Skip to content

Commit

Permalink
[NT-1366] Add-ons Selection Navigation (#1243)
Browse files Browse the repository at this point in the history
* Navigate to add-ons selection

* Actually stage all the files

* Put import back

* [NT-1366] Add header UI to add-ons selection view (#1244)

* Add basic header view with label

* Blend background color
  • Loading branch information
justinswart authored Jul 6, 2020
1 parent 49662f5 commit e0c901f
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Foundation
import Library
import Prelude
import UIKit

final class RewardAddOnSelectionViewController: UITableViewController {
// MARK: - Properties

public lazy var headerLabel: UILabel = UILabel(frame: .zero)
public lazy var headerView: UIView = UIView(frame: .zero)
public lazy var headerRootStackView: UIStackView = UIStackView(frame: .zero)

// MARK: - Lifecycle

override func viewDidLoad() {
super.viewDidLoad()

self.configureHeaderView()

self.navigationItem.title = localizedString(
key: "Edit_reward",
defaultValue: "Edit reward"
)

self.tableView.tableHeaderView = self.headerView
self.tableView.tableFooterView = UIView(frame: .zero)
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

self.tableView.ksr_sizeHeaderFooterViewsToFit()
}

// MARK: - Configuration

private func configureHeaderView() {
_ = (self.headerRootStackView, self.headerView)
|> ksr_addSubviewToParent()
|> ksr_constrainViewToEdgesInParent(priority: UILayoutPriority(rawValue: 999))

_ = ([self.headerLabel], self.headerRootStackView)
|> ksr_addArrangedSubviewsToStackView()
}

// MARK: - Styles

override func bindStyles() {
super.bindStyles()

_ = self.view
|> checkoutBackgroundStyle

_ = self.headerLabel
|> checkoutBackgroundStyle

_ = self.headerLabel
|> \.numberOfLines .~ 0
|> \.font .~ UIFont.ksr_title1().bolded
|> \.text .~ localizedString(
key: "Customize_your_reward_with_optional_addons",
defaultValue: "Customize your reward with optional add-ons."
)

_ = self.headerRootStackView
|> \.isLayoutMarginsRelativeArrangement .~ true
|> \.layoutMargins .~ .init(topBottom: Styles.grid(3), leftRight: Styles.grid(4))
|> \.axis .~ .vertical
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ final class RewardsCollectionViewController: UICollectionViewController {
self?.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
}

self.viewModel.outputs.goToAddOnSelection
.observeForControllerAction()
.observeValues { [weak self] data, context in
self?.goToAddOnSelection(
project: data.project,
reward: data.reward,
refTag: data.refTag,
context: context
)
}

self.viewModel.outputs.goToPledge
.observeForControllerAction()
.observeValues { [weak self] data, context in
Expand Down Expand Up @@ -227,6 +238,16 @@ final class RewardsCollectionViewController: UICollectionViewController {
?|> \.isActive .~ !isHidden
}

private func goToAddOnSelection(
project _: Project,
reward _: Reward,
refTag _: RefTag?,
context _: PledgeViewContext
) {
let vc = RewardAddOnSelectionViewController.instantiate()
self.navigationController?.pushViewController(vc, animated: true)
}

private func goToPledge(project: Project, reward: Reward, refTag: RefTag?, context: PledgeViewContext) {
let pledgeViewController = PledgeViewController.instantiate()
pledgeViewController.delegate = self.pledgeViewDelegate
Expand Down
4 changes: 4 additions & 0 deletions Kickstarter.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@
8AB3BDA6246DC8BE00D69624 /* DiscoveryEditorialViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77C25FBE2385FDA5006E2010 /* DiscoveryEditorialViewModelTests.swift */; };
8AB55D5023C3FAA6002F5E64 /* Qualtrics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AD7953123A286D800998C79 /* Qualtrics.framework */; };
8AB87DF3243FF22B006D7451 /* PledgePaymentMethodAddCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB87DF2243FF22B006D7451 /* PledgePaymentMethodAddCell.swift */; };
8ACB32A824ABC2DB00A03968 /* RewardAddOnSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ACB32A724ABC2DB00A03968 /* RewardAddOnSelectionViewController.swift */; };
8ACD29F7243E48260044BC17 /* PledgePaymentMethodsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ACD29F6243E48260044BC17 /* PledgePaymentMethodsDataSource.swift */; };
8ACF558723E8D444001654A2 /* Argo+ToPrimitive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ACF558623E8D444001654A2 /* Argo+ToPrimitive.swift */; };
8ACF558923E8D467001654A2 /* TryDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ACF558823E8D467001654A2 /* TryDecodable.swift */; };
Expand Down Expand Up @@ -1968,6 +1969,7 @@
8AB0E0112432B4C9008E975E /* ProjectSummaryCarouselCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectSummaryCarouselCell.swift; sourceTree = "<group>"; };
8AB0E0132432D03A008E975E /* ProjectSummaryCarouselViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectSummaryCarouselViewModel.swift; sourceTree = "<group>"; };
8AB87DF2243FF22B006D7451 /* PledgePaymentMethodAddCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PledgePaymentMethodAddCell.swift; sourceTree = "<group>"; };
8ACB32A724ABC2DB00A03968 /* RewardAddOnSelectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RewardAddOnSelectionViewController.swift; sourceTree = "<group>"; };
8ACD29F6243E48260044BC17 /* PledgePaymentMethodsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PledgePaymentMethodsDataSource.swift; sourceTree = "<group>"; };
8ACF558623E8D444001654A2 /* Argo+ToPrimitive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Argo+ToPrimitive.swift"; sourceTree = "<group>"; };
8ACF558823E8D467001654A2 /* TryDecodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TryDecodable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3396,6 +3398,7 @@
59392BEB1D7094B0001C99A4 /* ProjectUpdatesViewController.swift */,
019DDFEB1CB6FF4500BDC113 /* ResetPasswordViewController.swift */,
A7ED20291E8323E900BFFA01 /* ResetPasswordViewControllerTests.swift */,
8ACB32A724ABC2DB00A03968 /* RewardAddOnSelectionViewController.swift */,
8A8099F722E2156E00373E66 /* RewardPledgeNavigationController.swift */,
77EFBAA52268D32000DA5C3C /* RewardsCollectionViewController.swift */,
77EFBADE2268D33E00DA5C3C /* RewardsCollectionViewControllerTests.swift */,
Expand Down Expand Up @@ -5736,6 +5739,7 @@
3767EDAB22CFFED40088E8E4 /* ShippingRuleCell.swift in Sources */,
5955E64F1D21800300B4153D /* DashboardReferrersCell.swift in Sources */,
9D89B7E31D6B8B310021F6FF /* WebModalViewController.swift in Sources */,
8ACB32A824ABC2DB00A03968 /* RewardAddOnSelectionViewController.swift in Sources */,
D63BBCD0217E5460007E01F0 /* PaymentMethodsViewController.swift in Sources */,
9D14FF8D1D133351005F4ABB /* ProjectActivityBackingCell.swift in Sources */,
379CFFFC2242DAE800F6F0C2 /* Nib.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions KsApi/models/Reward+ManagePledgeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public extension Reward {
description: backingReward.description,
endsAt: backingReward.endsAt,
estimatedDeliveryOn: estimatedDeliveryOn,
hasAddOns: false, // This value is only sent via the v1 API to indicate that a base reward has add-ons
id: rewardId,
limit: backingReward.limit,
minimum: backingReward.amount.amount,
Expand Down
2 changes: 2 additions & 0 deletions KsApi/models/Reward.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public struct Reward {
public let description: String
public let endsAt: TimeInterval?
public let estimatedDeliveryOn: TimeInterval?
public let hasAddOns: Bool
public let id: Int
public let limit: Int?
public let minimum: Double
Expand Down Expand Up @@ -84,6 +85,7 @@ extension Reward: Argo.Decodable {
<*> json <|? "ends_at"
<*> json <|? "estimated_delivery_on"
let tmp2 = tmp1
<*> ((json <| "has_addons") <|> .success(false))
<*> json <| "id"
<*> json <|? "limit"
<*> json <| "minimum"
Expand Down
35 changes: 35 additions & 0 deletions KsApi/models/lenses/RewardLenses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -31,6 +32,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -51,6 +53,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -71,6 +74,7 @@ extension Reward {
description: $0,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -91,6 +95,7 @@ extension Reward {
description: $1.description,
endsAt: $0,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -111,6 +116,28 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $0,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
remaining: $1.remaining,
rewardsItems: $1.rewardsItems,
shipping: $1.shipping,
startsAt: $1.startsAt,
title: $1.title
) }
)

public static let hasAddOns = Lens<Reward, Bool>(
view: { $0.hasAddOns },
set: { Reward(
addOnData: $1.addOnData,
backersCount: $1.backersCount,
convertedMinimum: $1.convertedMinimum,
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $0,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -131,6 +158,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $0,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -151,6 +179,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $0,
minimum: $1.minimum,
Expand All @@ -171,6 +200,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $0,
Expand All @@ -191,6 +221,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -211,6 +242,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -231,6 +263,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -251,6 +284,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand All @@ -271,6 +305,7 @@ extension Reward {
description: $1.description,
endsAt: $1.endsAt,
estimatedDeliveryOn: $1.estimatedDeliveryOn,
hasAddOns: $1.hasAddOns,
id: $1.id,
limit: $1.limit,
minimum: $1.minimum,
Expand Down
3 changes: 3 additions & 0 deletions KsApi/models/templates/RewardTemplates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extension Reward {
estimatedDeliveryOn: Date(
timeIntervalSince1970: 1_475_361_315
).timeIntervalSince1970 + 60.0 * 60.0 * 24.0 * 365.0,
hasAddOns: false,
id: 1,
limit: 100,
minimum: 10.00,
Expand All @@ -33,6 +34,7 @@ extension Reward {
description: "",
endsAt: nil,
estimatedDeliveryOn: nil,
hasAddOns: false,
id: 0,
limit: nil,
minimum: 0,
Expand All @@ -56,6 +58,7 @@ extension Reward {
description: "",
endsAt: nil,
estimatedDeliveryOn: nil,
hasAddOns: false,
id: 9_999,
limit: nil,
minimum: 0,
Expand Down
9 changes: 7 additions & 2 deletions Library/ViewModels/RewardsCollectionViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public protocol RewardsCollectionViewModelInputs {
public protocol RewardsCollectionViewModelOutputs {
var configureRewardsCollectionViewFooterWithCount: Signal<Int, Never> { get }
var flashScrollIndicators: Signal<Void, Never> { get }
var goToAddOnSelection: Signal<(PledgeData, PledgeViewContext), Never> { get }
var goToPledge: Signal<(PledgeData, PledgeViewContext), Never> { get }
var navigationBarShadowImageHidden: Signal<Bool, Never> { get }
var reloadDataWithValues: Signal<[RewardCardViewData], Never> { get }
Expand Down Expand Up @@ -100,14 +101,17 @@ public final class RewardsCollectionViewModel: RewardsCollectionViewModelType,
PledgeData(project: project, reward: reward, refTag: refTag)
}

self.goToPledge = goToPledge
let goToData = goToPledge
.filter { project, reward, _ in
!userIsBacking(reward: reward, inProject: project)
}
.map { data in
.map { data -> (PledgeData, PledgeViewContext) in
(data, data.project.personalization.backing == nil ? .pledge : .updateReward)
}

self.goToAddOnSelection = goToData.filter { data, _ in data.reward.hasAddOns }
self.goToPledge = goToData.filter { data, _ in !data.reward.hasAddOns }

self.rewardsCollectionViewFooterIsHidden = self.traitCollectionChangedProperty.signal
.skipNil()
.map { isFalse($0.verticalSizeClass == .regular) }
Expand Down Expand Up @@ -177,6 +181,7 @@ public final class RewardsCollectionViewModel: RewardsCollectionViewModelType,

public let configureRewardsCollectionViewFooterWithCount: Signal<Int, Never>
public let flashScrollIndicators: Signal<Void, Never>
public let goToAddOnSelection: Signal<(PledgeData, PledgeViewContext), Never>
public let goToPledge: Signal<(PledgeData, PledgeViewContext), Never>
public let navigationBarShadowImageHidden: Signal<Bool, Never>
public let reloadDataWithValues: Signal<[RewardCardViewData], Never>
Expand Down
Loading

0 comments on commit e0c901f

Please sign in to comment.