Skip to content

Commit

Permalink
Main into Release 5.6.0 (#1762)
Browse files Browse the repository at this point in the history
* [PAY-2055] Project Currency Country Code Display Error (#1754)

* added a project currency, oddly build is crashing when opening a project, but unrelated to any new code.

* removed extaneous currency field from top level project and used existing stats field.

* fixed incorrect parameter build issue

* fixed extra parameter in lenses

* removed unused line

* corrected display issues for rewards and reward addons.

* reverting spacing in ProjectLenses, unneeded change, cluttering pr

* more ProjectLenses updated

* bonus support currency fix on pledge page.

* updated a shared function of min max pledge amount to use the project's currency country instead of project country.

* updated Apple Pay request currency code to be from project currency first, then project country currency. Also updated the supported networks of apple pay to be based on project currency country instead of project country

* updated analytics to come from the project currency country not project country

* updated summary view, apple pay alert, and expandable rewards header (spacing) to use project currency country first then project country

* total values for pledge summary view using project currency country before project country

* handled logged currency display scenarios (manage pledge flow)

* formatting

* fixed currency issue when user logged in and about to manage pledge, fetch backing doesn't update the chosen currency in the project.

* added view model tests

* more view model tests

* project summary view model tests

* pledge view model and project page view model tests

* project page snapshot tests added, existing project lense hadn't accounted for extended project properties, now it does.

* pr comments.

* [WEB-666] - Require FB Only Users To Set A Password  (#1755)

* adds  bool to user model

* separate apple and facebook signals to gain more control over facebook flow in LoginToutViewController

* Push SetYourPasswordViewController if fb user needs a password

* Run make strings script to pull in latest string updates from server

* fetch user's email and set context label

* create new password on user account and handle success and error cases

* make strings

* change nav bar back button text

* update unit tests

* wrap in fb login depreciated feature flag

* update view model tests

* adds activity indicator

* update strings

* add tests

* format

* update failing snapshot tests

* needsPassword is not actually an optional

* use kickstarter conventions

* updates uses of now non nil needsPassword property

* move loading indicator from top level view to stackview and replace save button when loading indicator is showing

* update snapshot tests

* update comments

* update snapshot tests

* update saveButton isHidden/isEnabled

* Remove unused User+GraphUser.swift

* Update User+UserFragment.swift

* Removes User+UserGraph releated tests

* Update LoginToutViewModelTests

* Update SetYourPasswordViewModelTests

* formatting

* Refactor needsPassword static func

* put back User+GraphUser because more test files than expected use it

* Revert "Removes User+UserGraph releated tests"

This reverts commit 2026508.

* corrected the api and library tests, was able to remove unused User+GraphUser and tests. Snapshot tests still failing.

* updated snapshot tests, all kickstarter-ios tests recorded and passing on intel. Should pass CI checks.

* revoked a change just being used for testing.

* rerecorded tests due to translation changes

* more re-records on Intel because of translations

* updated set your view model tests

Co-authored-by: Mubarak Sadoon <msadoon@gmail.com>

* [Unticketed] user needs_password not returned in v1/discover/ creator (#1758)

* needs password needs to be optional.

* add a default property for encoding

* [PAY-2053] Add New Payment Button Padding FIx (#1759)

* added constraints to add new button and loading indicator view to constraint them to the edges of their stack view and center them. One is only shown at a time, so the spacing error should not occur anymore.

* slight adjustment in the add button and loading indicator positions.

* updates to pledge view controller screenshot tests.

* guard against index out of range issue and default selected tab to index 0 if this scenario arises (#1761)

Co-authored-by: Mubarak Sadoon <msadoon@gmail.com>
  • Loading branch information
scottkicks and msadoon committed Dec 6, 2022
1 parent 7de5317 commit fdaf39e
Show file tree
Hide file tree
Showing 179 changed files with 761 additions and 208 deletions.
Expand Up @@ -187,12 +187,29 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC
self?.pushSignupViewController()
}

self.viewModel.outputs.logIntoEnvironment
self.viewModel.outputs.logIntoEnvironmentWithApple
.observeValues { [weak self] accessTokenEnv in
AppEnvironment.login(accessTokenEnv)
self?.viewModel.inputs.environmentLoggedIn()
}

self.viewModel.outputs.logIntoEnvironmentWithFacebook
.observeValues { [weak self] accessTokenEnv in
guard let strongSelf = self else { return }

AppEnvironment.login(accessTokenEnv)

guard featureFacebookLoginDeprecationEnabled(),
let needsPassword = accessTokenEnv.user.needsPassword,
needsPassword else {
strongSelf.pushSetYourPasswordViewController()

return
}

strongSelf.viewModel.inputs.environmentLoggedIn()
}

self.viewModel.outputs.postNotification
.observeForUI()
.observeValues {
Expand Down Expand Up @@ -241,10 +258,10 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC
self.helpViewModel.outputs.showMailCompose
.observeForControllerAction()
.observeValues { [weak self] in
guard let _self = self else { return }
guard let strongSelf = self else { return }
let controller = MFMailComposeViewController.support()
controller.mailComposeDelegate = _self
_self.present(controller, animated: true, completion: nil)
controller.mailComposeDelegate = strongSelf
strongSelf.present(controller, animated: true, completion: nil)
}

self.helpViewModel.outputs.showNoEmailError
Expand Down Expand Up @@ -407,6 +424,14 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC
self.navigationItem.backBarButtonItem = UIBarButtonItem.back(nil, selector: nil)
}

private func pushSetYourPasswordViewController() {
let vc = SetYourPasswordViewController.instantiate()
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
self.navigationItem
.backBarButtonItem = UIBarButtonItem(title: "Log in", style: .plain, target: nil, action: nil)
}

fileprivate func showHelpSheet(helpTypes: [HelpType]) {
let helpSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

Expand Down Expand Up @@ -573,6 +598,14 @@ extension LoginToutViewController: ASAuthorizationControllerDelegate {
}
}

// MARK: SetYourPasswordViewControllerDelegate

extension LoginToutViewController: SetYourPasswordViewControllerDelegate {
func setPasswordCompleteAndLogUserIn() {
self.viewModel.inputs.environmentLoggedIn()
}
}

// MARK: - ASAuthorizationControllerPresentationContextProviding

@available(iOS 13.0, *)
Expand Down
Expand Up @@ -55,6 +55,14 @@ final class PledgePaymentMethodAddCell: UITableViewCell, ValueCell {
_ = ([self.activityIndicator, self.addButton], self.containerView)
|> ksr_addArrangedSubviewsToStackView()

_ = (self.addButton, self.containerView)
|> ksr_constrainViewToEdgesInParent()
|> ksr_constrainViewToCenterInParent()

_ = (self.activityIndicator, self.containerView)
|> ksr_constrainViewToEdgesInParent()
|> ksr_constrainViewToCenterInParent()

_ = (self.containerView, self.contentView)
|> ksr_constrainViewToEdgesInParent()
|> ksr_constrainViewToCenterInParent()
Expand Down
Expand Up @@ -4,6 +4,10 @@ import Prelude
import ReactiveSwift
import UIKit

protocol SetYourPasswordViewControllerDelegate: AnyObject {
func setPasswordCompleteAndLogUserIn()
}

public final class SetYourPasswordViewController: UIViewController {
// MARK: - Properties

Expand All @@ -13,6 +17,11 @@ public final class SetYourPasswordViewController: UIViewController {
private lazy var confirmPasswordLabel: UILabel = { UILabel(frame: .zero) }()
private lazy var confirmPasswordTextField: UITextField = { UITextField(frame: .zero) |> \.tag .~ 1 }()

private lazy var loadingIndicator: UIActivityIndicatorView = {
UIActivityIndicatorView()
|> \.translatesAutoresizingMaskIntoConstraints .~ false
}()

private lazy var rootStackView = { UIStackView() }()
private lazy var scrollView = {
UIScrollView(frame: .zero)
Expand All @@ -33,16 +42,7 @@ public final class SetYourPasswordViewController: UIViewController {
}()

private let viewModel: SetYourPasswordViewModelType = SetYourPasswordViewModel()

// MARK: - Configuration

public static func configuredWith(
userEmail: String
) -> SetYourPasswordViewController {
let vc = SetYourPasswordViewController.instantiate()
vc.viewModel.inputs.configureWith(userEmail)
return vc
}
weak var delegate: SetYourPasswordViewControllerDelegate?

// MARK: - Lifecycle

Expand All @@ -60,6 +60,12 @@ public final class SetYourPasswordViewController: UIViewController {
self.viewModel.inputs.viewDidLoad()
}

public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

self.viewModel.inputs.viewWillAppear()
}

// MARK: - Styles

public override func bindStyles() {
Expand Down Expand Up @@ -96,19 +102,39 @@ public final class SetYourPasswordViewController: UIViewController {
// MARK: - Bind View Model

public override func bindViewModel() {
super.bindViewModel()

self.loadingIndicator.rac.animating = self.viewModel.outputs.shouldShowActivityIndicator
self.contextLabel.rac.text = self.viewModel.outputs.contextLabelText
self.newPasswordLabel.rac.text = self.viewModel.outputs.newPasswordLabel
self.confirmPasswordLabel.rac.text = self.viewModel.outputs.confirmPasswordLabel
self.saveButton.rac.enabled = self.viewModel.outputs.saveButtonIsEnabled

self.viewModel.outputs.setPasswordFailure
.observeForControllerAction()
.observeValues { [weak self] errorMessage in
self?.present(UIAlertController.genericError(errorMessage), animated: true, completion: nil)
self?.enableTextFieldsAndSaveButton(true)
}

self.viewModel.outputs.setPasswordSuccess
.observeForControllerAction()
.observeValues { [weak self] in
self?.delegate?.setPasswordCompleteAndLogUserIn()
}

self.viewModel.outputs.textFieldsAndSaveButtonAreEnabled
.observeForUI()
.observeValues { [weak self] isEnabled in
self?.enableTextFieldsAndSaveButton(isEnabled)
}
}

// MARK: - Functions

private func configureViews() {
_ = self.view
|> \.autoresizingMask .~ .flexibleHeight
|> \.backgroundColor .~ .ksr_white
|> \.clipsToBounds .~ true

_ = (self.scrollView, self.view)
|> ksr_addSubviewToParent()
Expand All @@ -124,7 +150,8 @@ public final class SetYourPasswordViewController: UIViewController {
self.newPasswordTextField,
self.confirmPasswordLabel,
self.confirmPasswordTextField,
self.saveButton
self.saveButton,
self.loadingIndicator
], self.rootStackView)
|> ksr_addArrangedSubviewsToStackView()

Expand All @@ -135,8 +162,11 @@ public final class SetYourPasswordViewController: UIViewController {
private func setupConstraints() {
NSLayoutConstraint.activate([
self.rootStackView.widthAnchor.constraint(equalTo: self.view.widthAnchor),

self.newPasswordTextField.heightAnchor.constraint(greaterThanOrEqualToConstant: 44),

self.confirmPasswordTextField.heightAnchor.constraint(greaterThanOrEqualToConstant: 44),

self.saveButton.heightAnchor.constraint(greaterThanOrEqualToConstant: 48)
])
}
Expand All @@ -149,6 +179,13 @@ public final class SetYourPasswordViewController: UIViewController {
self.saveButton.addTarget(self, action: #selector(self.saveButtonPressed), for: .touchUpInside)
}

private func enableTextFieldsAndSaveButton(_ isEnabled: Bool) {
_ = [self.newPasswordTextField, self.confirmPasswordTextField, self.saveButton]
||> \.isUserInteractionEnabled .~ isEnabled

self.saveButton.isHidden = !isEnabled
}

// MARK: - Accessors

@objc private func dismissKeyboard() {
Expand Down
Expand Up @@ -7,16 +7,24 @@ import XCTest
final class SetYourPasswordViewControllerTests: TestCase {
override func setUp() {
super.setUp()

AppEnvironment.pushEnvironment(mainBundle: Bundle.framework)
UIView.setAnimationsEnabled(false)
}

func testView() {
combos([Language.en], [Device.phone4_7inch, Device.pad]).forEach {
override func tearDown() {
AppEnvironment.popEnvironment()
super.tearDown()
}

func testSetYourPasswordViewController_DisabledSave() {
let userTemplate = GraphUser.template |> \.isEmailVerified .~ true
let userEnvelope = UserEnvelope(me: userTemplate)
let service = MockService(fetchGraphUserResult: .success(userEnvelope))

combos(Language.allLanguages, [Device.phone4_7inch, Device.pad]).forEach {
language, device in
withEnvironment(language: language) {
let controller = SetYourPasswordViewController.configuredWith(userEmail: "abc******@gmail.com")
withEnvironment(apiService: service, apiDelayInterval: .seconds(0), language: language) {
let controller = SetYourPasswordViewController.instantiate()
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: controller)

self.scheduler.run()
Expand All @@ -25,10 +33,4 @@ final class SetYourPasswordViewControllerTests: TestCase {
}
}
}

override func tearDown() {
AppEnvironment.popEnvironment()
UIView.setAnimationsEnabled(true)
super.tearDown()
}
}
11 changes: 11 additions & 0 deletions Kickstarter-iOS/Locales/Base.lproj/Localizable.strings
Expand Up @@ -323,6 +323,7 @@
"Kickstarter_is_not_a_store_Its_a_way_to_bring_creative_projects_to_life" = "Kickstarter is not a store. It's a way to bring creative projects to life.";
"Kickstarter_is_not_a_store_Its_a_way_to_bring_creative_projects_to_life_Learn_more_about_accountability" = "Kickstarter is not a store. It's a way to bring creative projects to life.<br/><a href=\"%{trust_link}\">Learn more about accountability</a>";
"Kickstarter_on_Film" = "Kickstarter on Film";
"Kickstarters_community_guidelines" = "Kickstarter’s Community Guidelines.";
"Know_when_creators_and_backers_message_you" = "Know when creators and backers message you by enabling notifications.";
"Learn_about_accountability_on_Kickstarter" = "Learn about accountability on Kickstarter";
"Learn_more_about_accountability" = "Learn more about accountability";
Expand Down Expand Up @@ -499,6 +500,7 @@
"Request_my_personal_data" = "Request my personal data";
"Resend_email" = "Resend email";
"Resend_verification_email" = "Re-send verification email";
"Reset_your_password" = "Reset your password";
"Retry" = "Retry";
"Retry_or_select_another_method" = "Retry or select another method.";
"Reusability_and_recyclability" = "Reusability and recyclability";
Expand Down Expand Up @@ -555,6 +557,8 @@
"Selected_reward" = "Selected reward";
"Send" = "Send";
"Send_verfication_email" = "Send verification email";
"Set_new_password" = "Set new password";
"Set_your_password" = "Set your password";
"Share" = "Share";
"Share_an_update_about_your_project" = "Share an update about your project…";
"Share_this_live_stream" = "Share this live stream.";
Expand Down Expand Up @@ -633,6 +637,9 @@
"These_projects_could_use_your_support" = "These projects could use your support.";
"This_allows_you_to_see_project_goal_and_pledge_amounts_in_your_preferred_currency" = "This allows you to see project goal and pledge amounts in your preferred currency.";
"This_comment_has_been_removed_by_Kickstarter" = "This comment has been removed by Kickstarter.";
"This_comment_is_under_review" = "This comment is under review.";
"This_comment_is_under_review_for_potentially_violating" = "This comment is under review for potentially violating";
"This_comment_is_under_review_for_potentially_violating_kickstarters_community_guidelines" = "This comment is under review for potentially violating <a href=\"%{community_guidelines}\">Kickstarter’s Community Guidelines.</a>";
"This_facebook_account_is_already_linked_to_another_Kickstarter_user" = "This Facebook account is already linked to another Kickstarter user.";
"This_holiday_season_support_a_project_for_no_reward" = "This holiday season, support a project for no reward, just because it speaks to you.";
"This_person_canceled_their_pledge" = "This person has canceled their pledge.";
Expand Down Expand Up @@ -690,6 +697,7 @@
"Visit_our_Environmental_Resources_Center" = "Visit our Environmental Resources Center";
"Visit_our_Environmental_Resources_Center_Alternative" = "<a href=\"%{environment_link}\">Visit our Environmental Resources Center</a>";
"Watch_live" = "Watch live";
"We_can_no_longer_log_you_in_through_Facebook" = "We can no longer log you in through Facebook. Please log in with your Kickstarter password, or set a new password with your Facebook email.";
"We_cant_process_this_pledge_because_of_a_problem_with_the_backers_payment_method" = "We can’t process this pledge because of a problem with the backer’s payment method.";
"We_cant_process_your_pledge" = "We can't process your pledge.";
"We_cant_process_your_pledge_Please_update_your_payment_method" = "We can’t process your pledge. Please update your payment method.";
Expand All @@ -701,11 +709,13 @@
"We_dont_allow_cancelations_that_will_cause_a_project_to_fall_short_of_its_goal_within_the_last_24_hours" = "We don’t allow cancelations that will cause a project to fall short of its goal within the last 24 hours.";
"We_re_processing_this_pledge_pull_to_refresh" = "We're processing this pledge—pull to refresh.";
"We_re_processing_your_pledge_pull_to_refresh" = "We're processing your pledge—pull to refresh.";
"We_re_simplifying_our_login_process_To_log_in" = "We’re simplifying our login process. To access your Kickstarter account, enter the email associated to your Facebook account and we’ll send you a link to set a password";
"We_think_youll_like_these_too" = "We think you’ll like these, too";
"We_use_your_activity_internally_to_make_recommendations_for_you" = "We use your activity internally to make recommendations for you. Turn recommendations off to opt out of this.";
"We_ve_been_unable_to_send_email" = "We've been unable to send email to this address. Please make sure it is typed correctly.";
"We_were_unable_to_connect_to_the_live_stream_chat" = "We were unable to connect to the live stream chat.";
"We_were_unable_to_load_the_shipping_destinations" = "We were unable to load the shipping destinations.\nPlease try again later.";
"We_will_be_discontinuing_the_ability_to_log_in_via_Facebook" = "We will be discontinuing the ability to log in via Facebook. To log in to your account using the email %{email}, please set a password that's at least 6 characters long.";
"We_wont_share_this_with_the_creator" = "We won’t share this with the creator.";
"Websites" = "Websites";
"Welcome_to_our_library_Peruse_the_stacks_with_us" = "Welcome to our library. Peruse the stacks with us.";
Expand Down Expand Up @@ -1313,6 +1323,7 @@
"forgot_password.placeholder_email" = "Email address";
"forgot_password.title" = "Forgot your password?";
"forgot_password.we_sent_an_email_to_email_address_with_instructions_to_reset_your_password" = "We’ve sent an email to %{email} with instructions to reset your password.";
"forgot_password.we_sent_an_email_to_email_address_with_instructions_to_set_your_password" = "We’ve sent an email to %{email} with instructions to set your password.";
"general.accessibility.kickstarter" = "Kickstarter";
"general.alert.buttons.ok" = "OK";
"general.backer_count_backers.few" = "%{backer_count} backers";
Expand Down

0 comments on commit fdaf39e

Please sign in to comment.