From d193eec371f5e9a669976b83370eadfc9b277fe9 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 15 Feb 2019 10:21:19 -0500 Subject: [PATCH] Sketch out the 'onboarding code verification' view. --- Signal.xcodeproj/project.pbxproj | 4 + .../HomeView/HomeViewController.m | 13 + .../OnboardingBaseViewController.swift | 25 +- .../Registration/OnboardingController.swift | 4 +- ...OnboardingVerificationViewController.swift | 374 ++++++++++++++++++ .../translations/en.lproj/Localizable.strings | 18 + 6 files changed, 422 insertions(+), 16 deletions(-) create mode 100644 Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 40575582f..0b34e517f 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -165,6 +165,7 @@ 3496957321A301A100DCFE74 /* OWSBackupJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 3496956A21A301A100DCFE74 /* OWSBackupJob.m */; }; 3496957421A301A100DCFE74 /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496956B21A301A100DCFE74 /* OWSBackupAPI.swift */; }; 349EA07C2162AEA800F7B17F /* OWS111UDAttributesMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */; }; + 34A4C61E221613D00042EF2E /* OnboardingVerificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */; }; 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; }; 34A6C28021E503E700B5B12E /* OWSImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A6C27F21E503E600B5B12E /* OWSImagePickerController.swift */; }; 34A8B3512190A40E00218A25 /* MediaAlbumCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A8B3502190A40E00218A25 /* MediaAlbumCellView.swift */; }; @@ -846,6 +847,7 @@ 3496956C21A301A100DCFE74 /* OWSBackupImportJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupImportJob.h; sourceTree = ""; }; 3496956D21A301A100DCFE74 /* OWSBackupIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupIO.h; sourceTree = ""; }; 349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWS111UDAttributesMigration.swift; sourceTree = ""; }; + 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingVerificationViewController.swift; sourceTree = ""; }; 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FARegistrationViewController.m; sourceTree = ""; }; 34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = ""; }; 34A6C27F21E503E600B5B12E /* OWSImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSImagePickerController.swift; sourceTree = ""; }; @@ -1473,6 +1475,7 @@ 3448E15B22133274004B052E /* OnboardingPermissionsViewController.swift */, 3448E16322135FFA004B052E /* OnboardingPhoneNumberViewController.swift */, 3448E15F22134C88004B052E /* OnboardingSplashViewController.swift */, + 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */, 346E9D5321B040B600562252 /* RegistrationController.swift */, 340FC878204DAC8C007AEB0F /* RegistrationViewController.h */, 340FC876204DAC8C007AEB0F /* RegistrationViewController.m */, @@ -3537,6 +3540,7 @@ 34D1F0521F7E8EA30066283D /* GiphyDownloader.swift in Sources */, 340FC8BC204DAC8D007AEB0F /* FingerprintViewController.m in Sources */, 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */, + 34A4C61E221613D00042EF2E /* OnboardingVerificationViewController.swift in Sources */, 340FC8B2204DAC8D007AEB0F /* AdvancedSettingsTableViewController.m in Sources */, 452B999020A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift in Sources */, 346129991FD1E4DA00532771 /* SignalApp.m in Sources */, diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index 2e8ab8ba1..88eb9f6f0 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -482,6 +482,19 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations [self.searchResultsController viewDidAppear:animated]; self.hasEverAppeared = YES; + + dispatch_async(dispatch_get_main_queue(), ^{ + OnboardingController *onboardingController = [OnboardingController new]; + [onboardingController + updateWithPhoneNumber:[[OnboardingPhoneNumber alloc] initWithE164:@"+13213214321" userInput:@"3213214321"]]; + + // UIViewController *view = [onboardingController initialViewController]; + UIViewController *view = + [[OnboardingVerificationViewController alloc] initWithOnboardingController:onboardingController]; + OWSNavigationController *navigationController = + [[OWSNavigationController alloc] initWithRootViewController:view]; + [self presentViewController:navigationController animated:YES completion:nil]; + }); } - (void)viewDidDisappear:(BOOL)animated diff --git a/Signal/src/ViewControllers/Registration/OnboardingBaseViewController.swift b/Signal/src/ViewControllers/Registration/OnboardingBaseViewController.swift index bd76bdb98..ac9125a27 100644 --- a/Signal/src/ViewControllers/Registration/OnboardingBaseViewController.swift +++ b/Signal/src/ViewControllers/Registration/OnboardingBaseViewController.swift @@ -50,29 +50,26 @@ public class OnboardingBaseViewController: OWSViewController { } func button(title: String, selector: Selector) -> OWSFlatButton { - // TODO: Make sure this all fits if dynamic font sizes are maxed out. - let font = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight() - // Button height should be 48pt if the font is 17pt. - let buttonHeight = font.pointSize * 48 / 17 - let button = OWSFlatButton.button(title: title, - font: font, - titleColor: .white, - backgroundColor: .ows_materialBlue, - target: self, - selector: selector) - button.autoSetDimension(.height, toSize: buttonHeight) - return button + return button(title: title, selector: selector, titleColor: .white, backgroundColor: .ows_materialBlue) } func linkButton(title: String, selector: Selector) -> OWSFlatButton { + return button(title: title, selector: selector, titleColor: .ows_materialBlue, backgroundColor: .white) + } + + func disabledLinkButton(title: String, selector: Selector) -> OWSFlatButton { + return self.button(title: title, selector: selector, titleColor: Theme.secondaryColor, backgroundColor: .white) + } + + private func button(title: String, selector: Selector, titleColor: UIColor, backgroundColor: UIColor) -> OWSFlatButton { // TODO: Make sure this all fits if dynamic font sizes are maxed out. let font = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight() // Button height should be 48pt if the font is 17pt. let buttonHeight = font.pointSize * 48 / 17 let button = OWSFlatButton.button(title: title, font: font, - titleColor: .ows_materialBlue, - backgroundColor: .white, + titleColor: titleColor, + backgroundColor: backgroundColor, target: self, selector: selector) button.autoSetDimension(.height, toSize: buttonHeight) diff --git a/Signal/src/ViewControllers/Registration/OnboardingController.swift b/Signal/src/ViewControllers/Registration/OnboardingController.swift index 532cc975f..5909cd674 100644 --- a/Signal/src/ViewControllers/Registration/OnboardingController.swift +++ b/Signal/src/ViewControllers/Registration/OnboardingController.swift @@ -122,8 +122,8 @@ public class OnboardingController: NSObject { Logger.info("") - // CodeVerificationViewController *vc = [CodeVerificationViewController new]; - // [weakSelf.navigationController pushViewController:vc animated:YES]; + let view = OnboardingVerificationViewController(onboardingController: self) + viewController.navigationController?.pushViewController(view, animated: true) } public func onboardingDidRequireCaptcha(viewController: UIViewController) { diff --git a/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift b/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift new file mode 100644 index 000000000..bba81af9b --- /dev/null +++ b/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift @@ -0,0 +1,374 @@ +// +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. +// + +import UIKit +import PromiseKit + +private class OnboardingCodeView: UIView { +} + +@objc +public class OnboardingVerificationViewController: OnboardingBaseViewController { + +// // MARK: - Dependencies +// +// private var tsAccountManager: TSAccountManager { +// return TSAccountManager.sharedInstance() +// } + + // MARK: - + + private let phoneNumberTextField = UITextField() +// private var nextButton: OWSFlatButton? + private var resendCodeLabel: OWSFlatButton? + private var resendCodeLink: OWSFlatButton? + + override public func loadView() { + super.loadView() + +// populateDefaults() + + view.backgroundColor = Theme.backgroundColor + view.layoutMargins = .zero + + var e164PhoneNumber = "" + if let phoneNumber = onboardingController.phoneNumber { + e164PhoneNumber = phoneNumber.e164 + } + let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: e164PhoneNumber) + let titleText = String(format: NSLocalizedString("ONBOARDING_VERIFICATION_TITLE_FORMAT", + comment: "Format for the title of the 'onboarding verification' view. Embeds {{the user's phone number}}."), + formattedPhoneNumber) + let titleLabel = self.titleLabel(text: titleText) + + let backLink = self.linkButton(title: NSLocalizedString("ONBOARDING_VERIFICATION_BACK_LINK", + comment: "Label for the link that lets users change their phone number."), + selector: #selector(backLinkTapped)) + + let onboardingCodeView = OnboardingCodeView() + onboardingCodeView.addRedBorder() + +// resendCodeLabel.text = NSLocalizedString("ONBOARDING_VERIFICATION_BACK_LINK", +// comment: "Label for the link that lets users change their phone number."), +// resendCodeLabel.text = "TODO" +// resendCodeLabel.textColor = Theme.secondaryColor +// resendCodeLabel.font = UIFont.ows_dynamicTypeBodyClamped + + // TODO: Copy. + let resendCodeLabel = disabledLinkButton(title: NSLocalizedString("ONBOARDING_VERIFICATION_RESEND_CODE_LINK", + comment: "Label for the link that lets users request another verification code."), + selector: #selector(ignoreEvent)) + self.resendCodeLabel = resendCodeLabel + + let resendCodeLink = self.linkButton(title: NSLocalizedString("ONBOARDING_VERIFICATION_RESEND_CODE_LINK", + comment: "Label for the link that lets users request another verification code."), + selector: #selector(resendCodeLinkTapped)) + self.resendCodeLink = resendCodeLink + + let resentCodeWrapper = UIView.container() + resentCodeWrapper.addSubview(resendCodeLabel) + resentCodeWrapper.addSubview(resendCodeLink) + resendCodeLabel.autoPinEdgesToSuperviewEdges() + resendCodeLink.autoPinEdgesToSuperviewEdges() + + // TODO: Finalize copy. + +// let nextButton = self.button(title: NSLocalizedString("BUTTON_NEXT", +// comment: "Label for the 'next' button."), +// selector: #selector(nextPressed)) +// self.nextButton = nextButton + let topSpacer = UIView.vStretchingSpacer() + let bottomSpacer = UIView.vStretchingSpacer() + + let stackView = UIStackView(arrangedSubviews: [ + titleLabel, + UIView.spacer(withHeight: 21), + backLink, + topSpacer, + onboardingCodeView, +// countryRow, +// UIView.spacer(withHeight: 8), +// phoneNumberRow, + bottomSpacer, + resentCodeWrapper + ]) + stackView.axis = .vertical + stackView.alignment = .fill + stackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32) + stackView.isLayoutMarginsRelativeArrangement = true + view.addSubview(stackView) + stackView.autoPinWidthToSuperview() + stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0) + autoPinView(toBottomOfViewControllerOrKeyboard: stackView, avoidNotch: true) + + // Ensure whitespace is balanced, so inputs are vertically centered. + topSpacer.autoMatch(.height, to: .height, of: bottomSpacer) + } + +// private func addBottomStroke(_ view: UIView) { +// let strokeView = UIView() +// strokeView.backgroundColor = Theme.middleGrayColor +// view.addSubview(strokeView) +// strokeView.autoSetDimension(.height, toSize: CGHairlineWidth()) +// strokeView.autoPinWidthToSuperview() +// strokeView.autoPinEdge(toSuperviewEdge: .bottom) +// } +// +// public override func viewDidAppear(_ animated: Bool) { +// super.viewDidAppear(animated) +// +// phoneNumberTextField.becomeFirstResponder() +// +// if tsAccountManager.isReregistering() { +// // If re-registering, pre-populate the country (country code, calling code, country name) +// // and phone number state. +// guard let phoneNumberE164 = tsAccountManager.reregisterationPhoneNumber() else { +// owsFailDebug("Could not resume re-registration; missing phone number.") +// return +// } +// tryToReregister(phoneNumberE164: phoneNumberE164) +// } +// } +// +// private func tryToReregister(phoneNumberE164: String) { +// guard phoneNumberE164.count > 0 else { +// owsFailDebug("Could not resume re-registration; invalid phoneNumberE164.") +// return +// } +// guard let parsedPhoneNumber = PhoneNumber(fromE164: phoneNumberE164) else { +// owsFailDebug("Could not resume re-registration; couldn't parse phoneNumberE164.") +// return +// } +// guard let callingCodeNumeric = parsedPhoneNumber.getCountryCode() else { +// owsFailDebug("Could not resume re-registration; missing callingCode.") +// return +// } +// let callingCode = "\(COUNTRY_CODE_PREFIX)\(callingCodeNumeric)" +// let countryCodes: [String] = +// PhoneNumberUtil.sharedThreadLocal().countryCodes(fromCallingCode: callingCode) +// guard let countryCode = countryCodes.first else { +// owsFailDebug("Could not resume re-registration; unknown countryCode.") +// return +// } +// guard let countryName = PhoneNumberUtil.countryName(fromCountryCode: countryCode) else { +// owsFailDebug("Could not resume re-registration; unknown countryName.") +// return +// } +// if !phoneNumberE164.hasPrefix(callingCode) { +// owsFailDebug("Could not resume re-registration; non-matching calling code.") +// return +// } +// let phoneNumberWithoutCallingCode = phoneNumberE164.substring(from: callingCode.count) +// +// guard countryCode.count > 0 else { +// owsFailDebug("Invalid country code.") +// return +// } +// guard countryName.count > 0 else { +// owsFailDebug("Invalid country name.") +// return +// } +// guard callingCode.count > 0 else { +// owsFailDebug("Invalid calling code.") +// return +// } +// +// let countryState = OnboardingCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode) +// onboardingController.update(countryState: countryState) +// +// updateState() +// +// phoneNumberTextField.text = phoneNumberWithoutCallingCode +// // Don't let user edit their phone number while re-registering. +// phoneNumberTextField.isEnabled = false +// } +// +// // MARK: - +// +// private var countryName: String { +// get { +// return onboardingController.countryState.countryName +// } +// } +// private var callingCode: String { +// get { +// AssertIsOnMainThread() +// +// return onboardingController.countryState.callingCode +// } +// } +// private var countryCode: String { +// get { +// AssertIsOnMainThread() +// +// return onboardingController.countryState.countryCode +// } +// } +// +// private func populateDefaults() { +// if let lastRegisteredPhoneNumber = OnboardingController.lastRegisteredPhoneNumber(), +// lastRegisteredPhoneNumber.count > 0, +// lastRegisteredPhoneNumber.hasPrefix(callingCode) { +// phoneNumberTextField.text = lastRegisteredPhoneNumber.substring(from: callingCode.count) +// } else if let phoneNumber = onboardingController.phoneNumber { +// phoneNumberTextField.text = phoneNumber.userInput +// } +// +// updateState() +// } +// +// private func updateState() { +// AssertIsOnMainThread() +// +// countryNameLabel.text = countryName +// callingCodeLabel.text = callingCode +// +// self.phoneNumberTextField.placeholder = ViewControllerUtils.examplePhoneNumber(forCountryCode: countryCode, callingCode: callingCode) +// } +// +// // MARK: - Events +// +// @objc func countryRowTapped(sender: UIGestureRecognizer) { +// guard sender.state == .recognized else { +// return +// } +// showCountryPicker() +// } +// +// @objc func countryCodeTapped(sender: UIGestureRecognizer) { +// guard sender.state == .recognized else { +// return +// } +// showCountryPicker() +// } +// +// @objc func nextPressed() { +// Logger.info("") +// +// parseAndTryToRegister() +// } +// +// // MARK: - Country Picker +// +// private func showCountryPicker() { +// guard !tsAccountManager.isReregistering() else { +// return +// } +// +// let countryCodeController = CountryCodeViewController() +// countryCodeController.countryCodeDelegate = self +// countryCodeController.interfaceOrientationMask = .portrait +// let navigationController = OWSNavigationController(rootViewController: countryCodeController) +// self.present(navigationController, animated: true, completion: nil) +// } +// +// // MARK: - Register +// +// private func parseAndTryToRegister() { +// guard let phoneNumberText = phoneNumberTextField.text?.ows_stripped(), +// phoneNumberText.count > 0 else { +// OWSAlerts.showAlert(title: +// NSLocalizedString("REGISTRATION_VIEW_NO_VERIFICATION_ALERT_TITLE", +// comment: "Title of alert indicating that users needs to enter a phone number to register."), +// message: +// NSLocalizedString("REGISTRATION_VIEW_NO_VERIFICATION_ALERT_MESSAGE", +// comment: "Message of alert indicating that users needs to enter a phone number to register.")) +// return +// } +// +// let phoneNumber = "\(callingCode)\(phoneNumberText)" +// guard let localNumber = PhoneNumber.tryParsePhoneNumber(fromUserSpecifiedText: phoneNumber), +// localNumber.toE164().count > 0, +// PhoneNumberValidator().isValidForRegistration(phoneNumber: localNumber) else { +// OWSAlerts.showAlert(title: +// NSLocalizedString("REGISTRATION_VIEW_INVALID_VERIFICATION_ALERT_TITLE", +// comment: "Title of alert indicating that users needs to enter a valid phone number to register."), +// message: +// NSLocalizedString("REGISTRATION_VIEW_INVALID_VERIFICATION_ALERT_MESSAGE", +// comment: "Message of alert indicating that users needs to enter a valid phone number to register.")) +// return +// } +// let e164PhoneNumber = localNumber.toE164() +// +// onboardingController.update(phoneNumber: OnboardingPhoneNumber(e164: e164PhoneNumber, userInput: phoneNumberText)) +// +// if UIDevice.current.isIPad { +// OWSAlerts.showConfirmationAlert(title: NSLocalizedString("REGISTRATION_IPAD_CONFIRM_TITLE", +// comment: "alert title when registering an iPad"), +// message: NSLocalizedString("REGISTRATION_IPAD_CONFIRM_BODY", +// comment: "alert body when registering an iPad"), +// proceedTitle: NSLocalizedString("REGISTRATION_IPAD_CONFIRM_BUTTON", +// comment: "button text to proceed with registration when on an iPad"), +// proceedAction: { (_) in +// self.onboardingController.tryToRegister(fromViewController: self, smsVerification: false) +// }) +// } else { +// onboardingController.tryToRegister(fromViewController: self, smsVerification: false) +// } +// } + + // MARK: - Events + + @objc func backLinkTapped() { + Logger.info("") + + self.navigationController?.popViewController(animated: true) + } + + @objc func ignoreEvent() { + Logger.info("") + } + + @objc func resendCodeLinkTapped() { + Logger.info("") + + // TODO: +// self.navigationController?.popViewController(animated: true) + } +} + +//// MARK: - +// +//extension OnboardingVerificationViewController: UITextFieldDelegate { +// public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { +// // TODO: Fix auto-format of phone numbers. +// ViewControllerUtils.phoneNumber(textField, shouldChangeCharactersIn: range, replacementString: string, countryCode: countryCode) +// +// // Inform our caller that we took care of performing the change. +// return false +// } +// +// public func textFieldShouldReturn(_ textField: UITextField) -> Bool { +// parseAndTryToRegister() +// return false +// } +//} +// +//// MARK: - +// +//extension OnboardingVerificationViewController: CountryCodeViewControllerDelegate { +// public func countryCodeViewController(_ vc: CountryCodeViewController, didSelectCountryCode countryCode: String, countryName: String, callingCode: String) { +// guard countryCode.count > 0 else { +// owsFailDebug("Invalid country code.") +// return +// } +// guard countryName.count > 0 else { +// owsFailDebug("Invalid country name.") +// return +// } +// guard callingCode.count > 0 else { +// owsFailDebug("Invalid calling code.") +// return +// } +// +// let countryState = OnboardingCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode) +// +// onboardingController.update(countryState: countryState) +// +// updateState() +// +// // Trigger the formatting logic with a no-op edit. +// _ = textField(phoneNumberTextField, shouldChangeCharactersIn: NSRange(location: 0, length: 0), replacementString: "") +// } +//} diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 9c80faccb..eb6c9dbb8 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1535,6 +1535,12 @@ /* Title of the 'onboarding splash' view. */ "ONBOARDING_SPLASH_TITLE" = "Signal is the private messenger for everybody"; +/* Label for the link that lets users change their phone number. */ +"ONBOARDING_VERIFICATION_BACK_LINK" = "Wrong number?"; + +/* Format for the title of the 'onboarding verification' view. Embeds {{the user's phone number}}. */ +"ONBOARDING_VERIFICATION_TITLE_FORMAT" = "Enter the code we sent to %@"; + /* Button text which opens the settings app */ "OPEN_SETTINGS_BUTTON" = "Settings"; @@ -1835,12 +1841,24 @@ /* Title of alert indicating that users needs to enter a valid phone number to register. */ "REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_TITLE" = "Invalid Phone Number"; +/* Message of alert indicating that users needs to enter a valid phone number to register. */ +"REGISTRATION_VIEW_INVALID_VERIFICATION_ALERT_MESSAGE" = "REGISTRATION_VIEW_INVALID_VERIFICATION_ALERT_MESSAGE"; + +/* Title of alert indicating that users needs to enter a valid phone number to register. */ +"REGISTRATION_VIEW_INVALID_VERIFICATION_ALERT_TITLE" = "REGISTRATION_VIEW_INVALID_VERIFICATION_ALERT_TITLE"; + /* Message of alert indicating that users needs to enter a phone number to register. */ "REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_MESSAGE" = "Please enter a phone number to register."; /* Title of alert indicating that users needs to enter a phone number to register. */ "REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE" = "No Phone Number"; +/* Message of alert indicating that users needs to enter a phone number to register. */ +"REGISTRATION_VIEW_NO_VERIFICATION_ALERT_MESSAGE" = "REGISTRATION_VIEW_NO_VERIFICATION_ALERT_MESSAGE"; + +/* Title of alert indicating that users needs to enter a phone number to register. */ +"REGISTRATION_VIEW_NO_VERIFICATION_ALERT_TITLE" = "REGISTRATION_VIEW_NO_VERIFICATION_ALERT_TITLE"; + /* notification action */ "REJECT_CALL_BUTTON_TITLE" = "Reject";