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

[NT-505] Project page creators header #930

Merged
merged 27 commits into from
Nov 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c92be4f
Created ProjectPamphletCreatorHeaderCell
Scollaco Nov 1, 2019
83dba29
Fixed top margin, added border
Scollaco Nov 1, 2019
e71d473
Added viewModel and logic to show the text according to project state
Scollaco Nov 1, 2019
5d6afe8
Added delegate
Scollaco Nov 1, 2019
9eb8a4e
Added tests
Scollaco Nov 4, 2019
283c0f3
Added viewcontroller test
Scollaco Nov 4, 2019
588bdfa
Merge remote-tracking branch 'oss/master' into project-page-creators-…
Scollaco Nov 4, 2019
8f2a20c
Strings
Scollaco Nov 4, 2019
51a74ca
Replaces hardcoded strings
Scollaco Nov 4, 2019
2032902
Added missing viewController test
Scollaco Nov 4, 2019
0f4bfc4
Merge remote-tracking branch 'oss/master' into project-page-creators-…
Scollaco Nov 4, 2019
fde2f35
Added DataSource tests and generated snapshots
Scollaco Nov 4, 2019
be5763f
Swiftformat
Scollaco Nov 4, 2019
88609a7
Fixed video container top margin
Scollaco Nov 4, 2019
2edc779
Snapshots
Scollaco Nov 4, 2019
34e0f07
Removed recordMode line
Scollaco Nov 4, 2019
ef91760
Removed print function
Scollaco Nov 4, 2019
920c913
Fixed margins and navBar height
Scollaco Nov 6, 2019
0317c0e
Updated snapshots
Scollaco Nov 6, 2019
20d7ca1
SwiftFormat
Scollaco Nov 6, 2019
bd1f320
Merge branch 'master' into project-page-creators-header
Scollaco Nov 6, 2019
7dad6ff
Pass timezone on date format function
Scollaco Nov 6, 2019
8678939
SwiftFormat
Scollaco Nov 6, 2019
6b266d5
Merge branch 'project-page-creators-header' of https://github.com/kic…
Scollaco Nov 6, 2019
88b3d41
Merge branch 'master' into project-page-creators-header
Scollaco Nov 6, 2019
6bb7351
Merge branch 'master' into project-page-creators-header
Scollaco Nov 7, 2019
832e145
Added spacing to stackView, fixed data used on tests
Scollaco Nov 7, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions Kickstarter-iOS/DataSources/ProjectPamphletContentDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Prelude

internal final class ProjectPamphletContentDataSource: ValueCellDataSource {
internal enum Section: Int {
case creatorHeader
case main
case subpages
case pledgeTitle
Expand Down Expand Up @@ -35,6 +36,14 @@ internal final class ProjectPamphletContentDataSource: ValueCellDataSource {
internal func load(project: Project, visible: Bool = false) {
self.clearValues()

if currentUserIsCreator(of: project) {
self.set(
values: [project],
cellClass: ProjectPamphletCreatorHeaderCell.self,
inSection: Section.creatorHeader.rawValue
)
}

self.set(values: [project], cellClass: ProjectPamphletMainCell.self, inSection: Section.main.rawValue)

let values: [ProjectPamphletSubpage] = [
Expand Down Expand Up @@ -139,6 +148,8 @@ internal final class ProjectPamphletContentDataSource: ValueCellDataSource {
switch (cell, value) {
case let (cell as DeprecatedRewardCell, value as (Project, Either<Reward, Backing>)):
cell.configureWith(value: value)
case let (cell as ProjectPamphletCreatorHeaderCell, value as Project):
cell.configureWith(value: value)
case let (cell as ProjectPamphletMainCell, value as Project):
cell.configureWith(value: value)
case let (cell as ProjectPamphletMinimalCell, value as Project):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,34 @@ final class ProjectPamphletContentDataSourceTests: TestCase {
XCTAssertTrue(self.dataSource.indexPathIsPledgeAnyAmountCell(.init(row: 0, section: section)))
}

func testViewProgressSectionRows_UserIsCreatorOfProject() {
let viewProgressSection = ProjectPamphletContentDataSource.Section.creatorHeader.rawValue

let user = User.template
let project = Project.template
|> Project.lens.creator .~ user

withEnvironment(currentUser: user) {
self.dataSource.load(project: project)

XCTAssertEqual(1, self.dataSource.tableView(self.tableView, numberOfRowsInSection: viewProgressSection))
}
}

func testViewProgressSectionRows_UserIsNotCreatorOfProject() {
let viewProgressSection = ProjectPamphletContentDataSource.Section.creatorHeader.rawValue

let user = User.template
|> \.id .~ 123
let project = Project.template

withEnvironment(currentUser: user) {
self.dataSource.load(project: project)

XCTAssertEqual(0, self.dataSource.tableView(self.tableView, numberOfRowsInSection: viewProgressSection))
}
}

func testAvailableRewardsSection_ShowsCorrectValues() {
let availableSection = ProjectPamphletContentDataSource.Section.availableRewards.rawValue
let unavailableSection = ProjectPamphletContentDataSource.Section.unavailableRewards.rawValue
Expand Down Expand Up @@ -61,7 +89,7 @@ final class ProjectPamphletContentDataSourceTests: TestCase {

dataSource.load(project: project)

XCTAssertEqual(2, self.dataSource.numberOfSections(in: self.tableView))
XCTAssertEqual(3, self.dataSource.numberOfSections(in: self.tableView))
}
}

Expand Down Expand Up @@ -107,7 +135,7 @@ final class ProjectPamphletContentDataSourceTests: TestCase {

dataSource.load(project: project)

XCTAssertEqual(7, self.dataSource.numberOfSections(in: self.tableView))
XCTAssertEqual(8, self.dataSource.numberOfSections(in: self.tableView))
XCTAssertEqual(1, self.dataSource.tableView(self.tableView, numberOfRowsInSection: availableSection))
XCTAssertEqual(1, self.dataSource.tableView(self.tableView, numberOfRowsInSection: unavailableSection))
}
Expand Down
3 changes: 3 additions & 0 deletions Kickstarter-iOS/Locales/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@
"Verification_email_sent" = "We've just sent you a verification email. Click the link in it and your address will be verified.";
"Video_disabled_until_the_internet_connection_improves" = "Video disabled until the internet connection improves";
"View" = "View";
"View_dashboard" = "View dashboard";
"View_progress" = "View progress";
"View_project" = "View project";
"View_rewards" = "View rewards";
"View_your_pledge" = "View your pledge";
Expand Down Expand Up @@ -563,6 +565,7 @@
"You_backed_this_project" = "You backed this project.";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "You can’t use this credit card to back a project from %{project_country}.";
"You_have_successfully_backed_project_html" = "You have successfully backed <b>%{project_name}</b>. This project is now one step closer to a reality, thanks to you. Spread the word!";
"You_launched_this_project_on_launch_date" = "You launched this project on %{launch_date}.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "You need to pledge at least %{reward_minimum} for this reward.";
"You_pledged_on_date" = "<b>You pledged</b> on %{pledge_date}";
"You_pledged_without_a_reward" = "You pledged without a reward";
Expand Down
3 changes: 3 additions & 0 deletions Kickstarter-iOS/Locales/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@
"Verification_email_sent" = "Wir haben dir gerade eine Bestätigungs-E-Mail geschickt. Bitte klicke auf den Link in der E-Mail, um deine Adresse zu bestätigen.";
"Video_disabled_until_the_internet_connection_improves" = "Video bis zur Wiederherstellung der Internetverbindung deaktiviert";
"View" = "Anzeigen";
"View_dashboard" = "View dashboard";
"View_progress" = "View progress";
"View_project" = "Projekt ansehen";
"View_rewards" = "Belohnungen ansehen";
"View_your_pledge" = "Deinen Finanzierungsbeitrag ansehen";
Expand Down Expand Up @@ -563,6 +565,7 @@
"You_backed_this_project" = "Du hast dieses Projekt unterstützt.";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "Diese Karte kann nicht verwendet werden, um ein Projekt aus dem folgenden Land zu unterstützen: %{project_country}.";
"You_have_successfully_backed_project_html" = "Dank deiner Unterstützung ist <b>%{project_name}</b> seiner Verwirklichung einen Schritt näher. Sag es weiter!";
"You_launched_this_project_on_launch_date" = "You launched this project on %{launch_date}.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "Diese Belohnung hat einen Mindestfinanzierungsbeitrag von %{reward_minimum}.";
"You_pledged_on_date" = "<b>Finanzierungsbeitrag geleistet</b> im %{pledge_date}";
"You_pledged_without_a_reward" = "Unterstützt ohne Belohnung";
Expand Down
3 changes: 3 additions & 0 deletions Kickstarter-iOS/Locales/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@
"Verification_email_sent" = "Te acabamos de enviar un correo electrónico de verificación. Haz clic en el enlace incluido y se verificará tu dirección.";
"Video_disabled_until_the_internet_connection_improves" = "Video desactivado hasta se reestablezca la conexión de internet";
"View" = "Ver";
"View_dashboard" = "View dashboard";
"View_progress" = "View progress";
"View_project" = "Ver proyecto";
"View_rewards" = "Ver recompensas";
"View_your_pledge" = "Revisa tu contribución";
Expand Down Expand Up @@ -563,6 +565,7 @@
"You_backed_this_project" = "Patrocinaste este proyecto.";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "No puedes usar esta tarjeta de crédito para patrocinar un proyecto de %{project_country}.";
"You_have_successfully_backed_project_html" = "Has patrocinado <b>%{project_name}</b> con éxito. Gracias a ti, este proyecto está ahora un paso más cerca de hacerse realidad. ¡Corre la voz!";
"You_launched_this_project_on_launch_date" = "You launched this project on %{launch_date}.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "Debes contribuir, al menos, %{reward_minimum} para obtener esta recompensa.";
"You_pledged_on_date" = "<b>Contribuiste</b> el %{pledge_date}";
"You_pledged_without_a_reward" = "Contribuiste sin recompensa";
Expand Down
3 changes: 3 additions & 0 deletions Kickstarter-iOS/Locales/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@
"Verification_email_sent" = "Nous venons de vous envoyer un e-mail de vérification. Cliquez sur le lien qu'il contient pour vérifier votre adresse.";
"Video_disabled_until_the_internet_connection_improves" = "Vidéo désactivée en attente d'une meilleure connexion Internet";
"View" = "Afficher";
"View_dashboard" = "View dashboard";
"View_progress" = "View progress";
"View_project" = "Afficher le projet";
"View_rewards" = "Afficher les récompenses";
"View_your_pledge" = "Afficher mon engagement";
Expand Down Expand Up @@ -563,6 +565,7 @@
"You_backed_this_project" = "Vous avez soutenu ce projet.";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "Impossible d'accepter cette carte pour soutenir un projet depuis le pays suivant : %{project_country}.";
"You_have_successfully_backed_project_html" = "Vous vous êtes engagé à soutenir le projet <b>%{project_name}</b>. Ce projet se rapproche tout doucement de son objectif grâce à vous. Parlez-en à votre entourage !";
"You_launched_this_project_on_launch_date" = "You launched this project on %{launch_date}.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "Vous devez vous engager à hauteur de %{reward_minimum} ou plus pour sélectionner cette récompense.";
"You_pledged_on_date" = "<b>Votre engagement</b> du %{pledge_date}";
"You_pledged_without_a_reward" = "Engagement sans récompense";
Expand Down
3 changes: 3 additions & 0 deletions Kickstarter-iOS/Locales/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@
"Verification_email_sent" = "認証メールを送信しました。メール内のリンクをクリックすればメールアドレスが認証済みとなります。";
"Video_disabled_until_the_internet_connection_improves" = "インターネット通信状態が向上するまでビデオはご利用いいただけません。";
"View" = "みる";
"View_dashboard" = "View dashboard";
"View_progress" = "View progress";
"View_project" = "プロジェクトを見る";
"View_rewards" = "リワードを見る";
"View_your_pledge" = "プレッジをみる";
Expand Down Expand Up @@ -564,6 +566,7 @@
"You_backed_this_project" = "バック済";
"You_cant_use_this_credit_card_to_back_a_project_from_project_country" = "%{project_country} のプロジェクトをバックするのにこのクレジットカードを利用することはできません。";
"You_have_successfully_backed_project_html" = "<b>%{project_name}</b>へのバックが完了しました。このプロジェクトは、成功に一歩近づきました!ありがとうございます。";
"You_launched_this_project_on_launch_date" = "You launched this project on %{launch_date}.";
"You_need_to_pledge_at_least_reward_minimum_for_this_reward" = "このリワードには、最低%{reward_minimum}のプレッジが必要です。";
"You_pledged_on_date" = "%{pledge_date} に<b>プレッジ</b>";
"You_pledged_without_a_reward" = "リワードなしでプレッジしました";
Expand Down
140 changes: 140 additions & 0 deletions Kickstarter-iOS/Views/Cells/ProjectPamphletCreatorHeaderCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import KsApi
import Library
import Prelude
import UIKit

private enum Layout {
enum Button {
static let height: CGFloat = 48
Copy link
Contributor

Choose a reason for hiding this comment

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

Where are these constants from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This comes from Abstract.

static let width: CGFloat = 152
}
}

protocol ProjectPamphletCreatorHeaderCellDelegate: class {
func projectPamphletCreatorHeaderCellDidTapButton(
_ cell: ProjectPamphletCreatorHeaderCell,
project: Project
)
}

final class ProjectPamphletCreatorHeaderCell: UITableViewCell, ValueCell {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Still not sure about this name 🤔 Would ProjectPamphletViewProgressCell be better?

// MARK: Properties

private let launchDateLabel: UILabel = { UILabel(frame: .zero) }()
private let rootStackView: UIStackView = { UIStackView(frame: .zero) }()
private let viewProgressButton: UIButton = { UIButton(frame: .zero) }()
private let viewModel: ProjectPamphletCreatorHeaderCellViewModelType =
ProjectPamphletCreatorHeaderCellViewModel()

internal weak var delegate: ProjectPamphletCreatorHeaderCellDelegate?

// MARK: Lifecycle

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.configureViews()
self.setupConstraints()
self.bindViewModel()
}

required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: Configuration

internal func configureWith(value project: Project) {
self.viewModel.inputs.configure(with: project)
}

private func configureViews() {
_ = ([self.launchDateLabel, self.viewProgressButton], self.rootStackView)
|> ksr_addArrangedSubviewsToStackView()

_ = (self.rootStackView, self.contentView)
|> ksr_addSubviewToParent()
|> ksr_constrainViewToMarginsInParent()

self.viewProgressButton.addTarget(
self, action: #selector(self.viewProgressButtonTapped), for: .touchUpInside
)
}

private func setupConstraints() {
NSLayoutConstraint.activate([
self.viewProgressButton.heightAnchor.constraint(equalToConstant: Layout.Button.height),
self.viewProgressButton.widthAnchor.constraint(equalToConstant: Layout.Button.width)
])
}

// MARK: - View model

override func bindViewModel() {
super.bindViewModel()
self.launchDateLabel.rac.attributedText = self.viewModel.outputs.launchDateLabelAttributedText
self.viewProgressButton.rac.title = self.viewModel.outputs.buttonTitle

self.viewModel.outputs.notifyDelegateViewProgressButtonTapped
.observeForUI()
.observeValues { [weak self] project in
guard let self = self else { return }

self.delegate?.projectPamphletCreatorHeaderCellDidTapButton(self, project: project)
}
}

// MARK: - Styles

override func bindStyles() {
super.bindStyles()

_ = self.contentView
|> contentViewStyle

_ = self.launchDateLabel
|> projectCreationInfoLabelStyle

_ = self.rootStackView
|> checkoutAdaptableStackViewStyle(
self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory
)
|> rootStackViewStyle

_ = self.viewProgressButton
|> viewProgressButtonStyle
}

// MARK: - Actions

@objc private func viewProgressButtonTapped() {
self.viewModel.inputs.viewProgressButtonTapped()
}
}

// MARK: Styles

private let contentViewStyle: ViewStyle = { view in
view
|> \.layer.borderWidth .~ 2.0
|> \.backgroundColor .~ UIColor.ksr_grey_100
|> \.layer.borderColor .~ UIColor.ksr_grey_500.cgColor
|> \.layoutMargins %~~ { _, _ in
.init(topBottom: Styles.grid(3), leftRight: 0)
}
}

private let projectCreationInfoLabelStyle: LabelStyle = { label in
label
|> \.adjustsFontForContentSizeCategory .~ true
|> \.numberOfLines .~ 0
}

private let rootStackViewStyle: StackViewStyle = { stackView in
stackView
|> \.spacing .~ Styles.grid(1)
}

private let viewProgressButtonStyle: ButtonStyle = { button in
button
|> greyButtonStyle
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public final class ProjectPamphletContentViewController: UITableViewController {
action: #selector(ProjectPamphletContentViewController.scrollViewPanGestureRecognizerDidChange(_:))
)

self.tableView.registerCellClass(ProjectPamphletCreatorHeaderCell.self)
self.tableView.register(nib: .DeprecatedRewardCell)

self.viewModel.inputs.viewDidLoad()
Expand Down Expand Up @@ -109,6 +110,8 @@ public final class ProjectPamphletContentViewController: UITableViewController {
cell.delegate = self
} else if let cell = cell as? DeprecatedRewardCell {
cell.delegate = self
} else if let cell = cell as? ProjectPamphletCreatorHeaderCell {
cell.delegate = self
}
}

Expand Down Expand Up @@ -243,3 +246,12 @@ extension ProjectPamphletContentViewController: DeprecatedRewardCellDelegate {
self.tableView.endUpdates()
}
}

extension ProjectPamphletContentViewController: ProjectPamphletCreatorHeaderCellDelegate {
internal func projectPamphletCreatorHeaderCellDidTapButton(
_: ProjectPamphletCreatorHeaderCell,
project _: Project
) {
// TODO:
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,42 @@ internal final class ProjectPamphletContentViewControllerTests: TestCase {
FBSnapshotVerifyView(vc.view, tolerance: 0.0001)
}

func testCreator_LiveProject() {
let user = User.template
let project = self.cosmicSurgery
|> Project.lens.state .~ .live
|> Project.lens.creator .~ user

combos(Language.allLanguages, [Device.phone4_7inch, Device.phone5_8inch, Device.pad]).forEach {
language, device in
withEnvironment(currentUser: user, language: language, locale: .init(identifier: language.rawValue)) {
let vc = ProjectPamphletViewController.configuredWith(projectOrParam: .left(project), refTag: nil)
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 2_300 : 2_200

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
}
}
}

func testCreator_NonLiveProject() {
let user = User.template
let project = self.cosmicSurgery
|> Project.lens.state .~ .successful
|> Project.lens.creator .~ user

combos(Language.allLanguages, [Device.phone4_7inch, Device.phone5_8inch, Device.pad]).forEach {
language, device in
withEnvironment(currentUser: user, language: language, locale: .init(identifier: language.rawValue)) {
let vc = ProjectPamphletViewController.configuredWith(projectOrParam: .left(project), refTag: nil)
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 2_300 : 2_200

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
}
}
}

func testFailedProject() {
let project = self.cosmicSurgery
|> Project.lens.stats.pledged .~ (self.cosmicSurgery.stats.goal * 3 / 4)
Expand Down
Loading