Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Nexd/Nexd/Resources/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"error_message_unknown" = "Unbekannter Fehler";
"error_message_user_detail_field_missing" = "Bitte ausfüllen";
"error_title" = "Fehler";
"error_message_user_terms_of_use_consent_missing" = "Bitte den Nutzungsbedingungen zustimmen";
"helper_call_overview_screen_title" = "Offene Anrufe:";
"helper_request_detail_button_accept" = "Mach ich!";
"helper_request_detail_button_accepted" = "Anfrage bereits angenommen";
Expand Down
1 change: 1 addition & 0 deletions Nexd/Nexd/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"error_message_registration_validation_failed" = "User registration failed. Please make sure you input valid data.";
"error_message_unknown" = "Unknown error";
"error_message_user_detail_field_missing" = "Please fill in";
"error_message_user_terms_of_use_consent_missing" = "You need to agree to the terms of use";
"error_title" = "Error";
"helper_call_overview_screen_title" = "Open calls:";
"helper_request_detail_button_accept" = "Will do!";
Expand Down
77 changes: 72 additions & 5 deletions Nexd/Nexd/ui/onboarding/RegistrationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class RegistrationViewController: ViewController<RegistrationViewController.View
private var keyboardObserver: KeyboardObserver?
private var keyboardDismisser: KeyboardDismisser?
lazy var logo = UIImageView()

private let caShapeLayer = CAShapeLayer()
private var didAgreeTermsOfUse: Bool = false

lazy var scrollView = UIScrollView()

lazy var email = ValidatingTextField.make(tag: 0,
Expand Down Expand Up @@ -56,17 +58,21 @@ class RegistrationViewController: ViewController<RegistrationViewController.View
private lazy var passwordImageView = UIImageView()

private lazy var confirmPasswordImageView = UIImageView()

lazy var privacyPolicy = UITextView()

lazy var confirmTermsOfUseButton = UIButton()

lazy var registerButton = UIButton()

override func viewDidLoad() {
super.viewDidLoad()
keyboardDismisser = KeyboardDismisser(rootView: view)

didAgreeTermsOfUse = false
view.backgroundColor = .white
title = R.string.localizable.registration_screen_title()
setupImageViews()

confirmTermsOfUseButton.addTarget(self, action: #selector(confirmTermsOfUseButtonPressed), for: .touchUpInside)
setupLayoutConstraints()
}

Expand All @@ -79,6 +85,10 @@ class RegistrationViewController: ViewController<RegistrationViewController.View
super.viewDidDisappear(animated)
keyboardObserver = nil
}

override func viewDidLayoutSubviews() {
drawCircle(on: confirmTermsOfUseButton)
}

override func bind(viewModel: RegistrationViewController.ViewModel, disposeBag: DisposeBag) {

Expand Down Expand Up @@ -109,7 +119,7 @@ class RegistrationViewController: ViewController<RegistrationViewController.View
email.snp.makeConstraints { make -> Void in
make.leftMargin.equalTo(8)
make.rightMargin.equalTo(-8)
make.top.equalTo(logo.snp.bottom).offset(134)
make.top.equalTo(logo.snp.bottom).offset(80)
}

contentView.addSubview(emailImageView)
Expand Down Expand Up @@ -179,15 +189,36 @@ class RegistrationViewController: ViewController<RegistrationViewController.View
make.width.equalTo(24)
make.right.equalToSuperview().offset(-41)
}
contentView.addSubview(privacyPolicy)
privacyPolicy.backgroundColor = .clear
privacyPolicy.isScrollEnabled = false
privacyPolicy.textContainerInset = .zero

let term = R.string.localizable.registration_term_privacy_policy()
let formatted = R.string.localizable.registration_label_privacy_policy_agreement(term)
privacyPolicy.attributedText = formatted.asLink(range: formatted.range(of: term), target: "https://www.nexd.app/privacypage")
privacyPolicy.snp.makeConstraints { make -> Void in
make.height.equalTo(54)
make.rightMargin.equalTo(-8)
make.top.equalTo(confirmPassword.snp.bottom).offset(12)
}

contentView.addSubview(confirmTermsOfUseButton)
confirmTermsOfUseButton.snp.makeConstraints { make -> Void in
make.centerY.equalTo(privacyPolicy.snp_centerY).offset(-7.5)
make.left.equalToSuperview().offset(27)
make.right.equalTo(privacyPolicy.snp.left).offset(-9)
make.height.equalTo(26)
make.width.equalTo(26)
}
contentView.addSubview(registerButton)
registerButton.style(text: R.string.localizable.registration_button_title_continue())
registerButton.addTarget(self, action: #selector(registerButtonPressed(sender:)), for: .touchUpInside)
registerButton.snp.makeConstraints { make in
make.height.equalTo(Style.buttonHeight)
make.leftMargin.equalTo(8)
make.rightMargin.equalTo(-8)
make.top.equalTo(confirmPassword.snp.bottom).offset(50)
make.top.equalTo(confirmPassword.snp.bottom).offset(80)
make.bottom.equalToSuperview().offset(-20)
}
}
Expand All @@ -208,14 +239,50 @@ class RegistrationViewController: ViewController<RegistrationViewController.View
confirmPasswordImageView.image = R.image.lock1()
confirmPasswordImageView.contentMode = .scaleAspectFit
}
private func drawCircle(on button: UIButton) {
let buttonWidth = button.frame.size.width
let buttonHeight = button.frame.size.height

let centerCoordinates = CGPoint(x: buttonWidth / 2, y: buttonHeight / 2)

let smallestAspect = min(button.frame.width, button.frame.height)
let circleRadiusWithinButton = smallestAspect / 2

// prevents setting the layer when the constraints have not been set properly yet
if buttonWidth != 0, buttonHeight != 0, circleRadiusWithinButton != 0 {
let circularPath = UIBezierPath(arcCenter: centerCoordinates,
radius: circleRadiusWithinButton,
startAngle: 0,
endAngle: 2 * CGFloat.pi,
clockwise: true)
caShapeLayer.path = circularPath.cgPath
caShapeLayer.strokeColor = R.color.nexdGreen()?.cgColor
caShapeLayer.lineWidth = 3.0
caShapeLayer.fillColor = UIColor.clear.cgColor
button.layer.addSublayer(caShapeLayer)
}
}
}

extension RegistrationViewController {
@objc func confirmTermsOfUseButtonPressed() {
if caShapeLayer.fillColor == UIColor.clear.cgColor {
caShapeLayer.fillColor = R.color.nexdGreen()?.cgColor
} else {
caShapeLayer.fillColor = UIColor.clear.cgColor
}
didAgreeTermsOfUse = !didAgreeTermsOfUse
}
@objc func registerButtonPressed(sender: UIButton!) {
let hasInvalidInput = [email, firstName, lastName, password, confirmPassword]
.map { $0.validate() }
.contains(false)

guard didAgreeTermsOfUse else {
log.warning("Cannot update user, did not agree to privacy policy")
showError(title: R.string.localizable.error_title(), message: R.string.localizable.error_message_registration_failed())
return
}
guard !hasInvalidInput else {
log.warning("Cannot register user! Validation failed!")
showError(title: R.string.localizable.error_title(), message: R.string.localizable.error_message_registration_validation_failed())
Expand Down
42 changes: 5 additions & 37 deletions Nexd/Nexd/ui/onboarding/UserDetailsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ class UserDetailsViewController: ViewController<UserDetailsViewController.ViewMo
let firstName: String
let lastName: String
}

private let disposeBag = DisposeBag()
private var keyboardObserver: KeyboardObserver?
private var keyboardDismisser: KeyboardDismisser?

private let caShapeLayer = CAShapeLayer()

lazy var scrollView = UIScrollView()
Expand All @@ -46,18 +44,15 @@ class UserDetailsViewController: ViewController<UserDetailsViewController.ViewMo

lazy var registerButton = UIButton()

lazy var privacyPolicy = UITextView()

lazy var phoneNumberImageView = UIImageView()

lazy var postalCodeImageView = UIImageView()

lazy var confirmTermsOfUseButton = UIButton()

override func viewDidLoad() {
super.viewDidLoad()

setupImageViews()
confirmTermsOfUseButton.addTarget(self, action: #selector(confirmTermsOfUseButtonPressed), for: .touchUpInside)

keyboardDismisser = KeyboardDismisser(rootView: view)

Expand Down Expand Up @@ -114,28 +109,6 @@ class UserDetailsViewController: ViewController<UserDetailsViewController.ViewMo
make.right.equalToSuperview().offset(-41)
}

contentView.addSubview(privacyPolicy)
privacyPolicy.backgroundColor = .clear
privacyPolicy.isScrollEnabled = false
privacyPolicy.textContainerInset = .zero

let term = R.string.localizable.registration_term_privacy_policy()
let formatted = R.string.localizable.registration_label_privacy_policy_agreement(term)
privacyPolicy.attributedText = formatted.asLink(range: formatted.range(of: term), target: "https://www.nexd.app/privacypage")
privacyPolicy.snp.makeConstraints { make -> Void in
make.height.equalTo(54)
make.rightMargin.equalTo(-8)
make.top.equalTo(zipCode.snp.bottom).offset(50)
}

contentView.addSubview(confirmTermsOfUseButton)
confirmTermsOfUseButton.snp.makeConstraints { make -> Void in
make.centerY.equalTo(privacyPolicy.snp_centerY).offset(-7.5)
make.left.equalToSuperview().offset(27)
make.right.equalTo(privacyPolicy.snp.left).offset(-9)
make.height.equalTo(26)
make.width.equalTo(26)
}

contentView.addSubview(registerButton)
registerButton.style(text: R.string.localizable.registration_button_title_send())
Expand All @@ -144,7 +117,7 @@ class UserDetailsViewController: ViewController<UserDetailsViewController.ViewMo
make.height.equalTo(Style.buttonHeight)
make.leftMargin.equalTo(8)
make.rightMargin.equalTo(-8)
make.top.equalTo(privacyPolicy.snp_bottom).offset(150)
make.top.equalTo(zipCode.snp_bottom).offset(250)
make.bottom.equalToSuperview().offset(-20)
}
}
Expand All @@ -160,7 +133,7 @@ class UserDetailsViewController: ViewController<UserDetailsViewController.ViewMo
}

override func viewDidLayoutSubviews() {
drawCircle(on: confirmTermsOfUseButton)

}

override func bind(viewModel: UserDetailsViewController.ViewModel, disposeBag: DisposeBag) { }
Expand Down Expand Up @@ -199,19 +172,14 @@ class UserDetailsViewController: ViewController<UserDetailsViewController.ViewMo
}

extension UserDetailsViewController {
@objc func confirmTermsOfUseButtonPressed() {
if caShapeLayer.fillColor == UIColor.clear.cgColor {
caShapeLayer.fillColor = R.color.nexdGreen()?.cgColor
} else {
caShapeLayer.fillColor = UIColor.clear.cgColor
}
}


@objc func registerButtonPressed(sender: UIButton!) {
let hasInvalidInput = [phone, zipCode]
.map { $0.validate() }
.contains(false)


guard !hasInvalidInput else {
log.warning("Cannot update user, mandatory field is missing!")
showError(title: R.string.localizable.error_title(), message: R.string.localizable.error_message_registration_validation_failed())
Expand Down
2 changes: 1 addition & 1 deletion Nexd/Nexd/utilities/KeyboardObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class KeyboardObserver {

static func insetting(scrollView: UIScrollView) -> KeyboardObserver {
return KeyboardObserver(keyboardWillShow: { keyboardSize in
let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0)
let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height - 150, right: 0.0)
scrollView.contentInset = contentInsets
scrollView.scrollIndicatorInsets = contentInsets

Expand Down
21 changes: 20 additions & 1 deletion Nexd/R.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ struct R: Rswift.Validatable {

/// This `R.string` struct is generated, and contains static references to 1 localization tables.
struct string {
/// This `R.string.localizable` struct is generated, and contains static references to 130 localization keys.
/// This `R.string.localizable` struct is generated, and contains static references to 131 localization keys.
struct localizable {
/// en translation: %1$@ ago, %2$@
///
Expand Down Expand Up @@ -1172,6 +1172,10 @@ struct R: Rswift.Validatable {
///
/// Locales: en, de
static let seeker_overview_empty_label = Rswift.StringResource(key: "seeker_overview_empty_label", tableName: "Localizable", bundle: R.hostingBundle, locales: ["en", "de"], comment: nil)
/// en translation: You need to agree to the terms of use
///
/// Locales: en, de
static let error_message_user_terms_of_use_consent_missing = Rswift.StringResource(key: "error_message_user_terms_of_use_consent_missing", tableName: "Localizable", bundle: R.hostingBundle, locales: ["en", "de"], comment: nil)
/// en translation: Your request
///
/// Locales: en, de
Expand Down Expand Up @@ -3058,6 +3062,21 @@ struct R: Rswift.Validatable {
return NSLocalizedString("seeker_overview_empty_label", bundle: bundle, comment: "")
}

/// en translation: You need to agree to the terms of use
///
/// Locales: en, de
static func error_message_user_terms_of_use_consent_missing(preferredLanguages: [String]? = nil) -> String {
guard let preferredLanguages = preferredLanguages else {
return NSLocalizedString("error_message_user_terms_of_use_consent_missing", bundle: hostingBundle, comment: "")
}

guard let (_, bundle) = localeBundle(tableName: "Localizable", preferredLanguages: preferredLanguages) else {
return "error_message_user_terms_of_use_consent_missing"
}

return NSLocalizedString("error_message_user_terms_of_use_consent_missing", bundle: bundle, comment: "")
}

/// en translation: Your request
///
/// Locales: en, de
Expand Down