From aa8fd9e69cbd921fea4cf8132952432db356c9e3 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 20 Feb 2019 17:35:46 -0500 Subject: [PATCH] Remove old registration views. --- Signal.xcodeproj/project.pbxproj | 18 - Signal/src/AppDelegate.m | 9 +- Signal/src/Signal-Bridging-Header.h | 1 - .../src/ViewControllers/DebugUI/DebugUIMisc.m | 3 +- .../HomeView/HomeViewController.m | 1 - .../OWS2FARegistrationViewController.h | 15 - .../OWS2FARegistrationViewController.m | 161 ----- .../CodeVerificationViewController.h | 15 - .../CodeVerificationViewController.m | 509 -------------- ...OnboardingVerificationViewController.swift | 28 + .../Registration/RegistrationController.swift | 107 ++- .../Registration/RegistrationViewController.h | 13 - .../Registration/RegistrationViewController.m | 646 ------------------ Signal/src/util/AppUpdateNag.swift | 4 +- Signal/src/util/RegistrationUtils.m | 17 +- .../SelectRecipientViewController.m | 2 - 16 files changed, 89 insertions(+), 1460 deletions(-) delete mode 100644 Signal/src/ViewControllers/OWS2FARegistrationViewController.h delete mode 100644 Signal/src/ViewControllers/OWS2FARegistrationViewController.m delete mode 100644 Signal/src/ViewControllers/Registration/CodeVerificationViewController.h delete mode 100644 Signal/src/ViewControllers/Registration/CodeVerificationViewController.m delete mode 100644 Signal/src/ViewControllers/Registration/RegistrationViewController.h delete mode 100644 Signal/src/ViewControllers/Registration/RegistrationViewController.m diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 683161dfc..bcd165bdf 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -12,8 +12,6 @@ 34074F61203D0CBE004596AE /* OWSSounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F5F203D0CBD004596AE /* OWSSounds.m */; }; 34074F62203D0CBE004596AE /* OWSSounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 34074F60203D0CBE004596AE /* OWSSounds.h */; settings = {ATTRIBUTES = (Public, ); }; }; 340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */; }; - 340FC8A7204DAC8D007AEB0F /* RegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC876204DAC8C007AEB0F /* RegistrationViewController.m */; }; - 340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */; }; 340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */; }; 340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */; }; 340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */; }; @@ -168,7 +166,6 @@ 349ED990221B0194008045B0 /* Onboarding2FAViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349ED98F221B0194008045B0 /* Onboarding2FAViewController.swift */; }; 34A4C61E221613D00042EF2E /* OnboardingVerificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */; }; 34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A4C61F22175C5C0042EF2E /* OnboardingProfileViewController.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 */; }; 34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */; }; @@ -639,10 +636,6 @@ 34074F60203D0CBE004596AE /* OWSSounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSounds.h; sourceTree = ""; }; 340B02B61F9FD31800F9CFEC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = translations/he.lproj/Localizable.strings; sourceTree = ""; }; 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationViewItemTest.m; sourceTree = ""; }; - 340FC876204DAC8C007AEB0F /* RegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegistrationViewController.m; sourceTree = ""; }; - 340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeVerificationViewController.m; sourceTree = ""; }; - 340FC878204DAC8C007AEB0F /* RegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegistrationViewController.h; sourceTree = ""; }; - 340FC879204DAC8C007AEB0F /* CodeVerificationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeVerificationViewController.h; sourceTree = ""; }; 340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsOptionsViewController.m; sourceTree = ""; }; 340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsViewController.m; sourceTree = ""; }; 340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DomainFrontingCountryViewController.m; sourceTree = ""; }; @@ -852,8 +845,6 @@ 349ED98F221B0194008045B0 /* Onboarding2FAViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Onboarding2FAViewController.swift; sourceTree = ""; }; 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingVerificationViewController.swift; sourceTree = ""; }; 34A4C61F22175C5C0042EF2E /* OnboardingProfileViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingProfileViewController.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 = ""; }; 34A8B3502190A40E00218A25 /* MediaAlbumCellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaAlbumCellView.swift; sourceTree = ""; }; 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSResaveCollectionDBMigration.m; sourceTree = ""; }; @@ -1471,8 +1462,6 @@ isa = PBXGroup; children = ( 3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */, - 340FC879204DAC8C007AEB0F /* CodeVerificationViewController.h */, - 340FC877204DAC8C007AEB0F /* CodeVerificationViewController.m */, 349ED98F221B0194008045B0 /* Onboarding2FAViewController.swift */, 3448E1612213585C004B052E /* OnboardingBaseViewController.swift */, 3448E1652215B313004B052E /* OnboardingCaptchaViewController.swift */, @@ -1483,8 +1472,6 @@ 3448E15F22134C88004B052E /* OnboardingSplashViewController.swift */, 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */, 346E9D5321B040B600562252 /* RegistrationController.swift */, - 340FC878204DAC8C007AEB0F /* RegistrationViewController.h */, - 340FC876204DAC8C007AEB0F /* RegistrationViewController.m */, ); path = Registration; sourceTree = ""; @@ -1871,8 +1858,6 @@ 34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */, 34B3F8541E8DF1700035BE1A /* NewGroupViewController.h */, 34B3F8551E8DF1700035BE1A /* NewGroupViewController.m */, - 34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */, - 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */, 45D2AC01204885170033C692 /* OWS2FAReminderViewController.swift */, 345BC30A2047030600257B7C /* OWS2FASettingsViewController.h */, 345BC30B2047030600257B7C /* OWS2FASettingsViewController.m */, @@ -3515,7 +3500,6 @@ 3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */, 4C2F454F214C00E1004871FF /* AvatarTableViewCell.swift in Sources */, 346E9D5421B040B700562252 /* RegistrationController.swift in Sources */, - 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */, 340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */, 340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */, 4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */, @@ -3607,7 +3591,6 @@ 45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */, 340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */, 45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */, - 340FC8A7204DAC8D007AEB0F /* RegistrationViewController.m in Sources */, 452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */, 34D2CCDA2062E7D000CB1A14 /* OWSScreenLockUI.m in Sources */, 45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */, @@ -3640,7 +3623,6 @@ 340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */, 3448E1662215B313004B052E /* OnboardingCaptchaViewController.swift in Sources */, 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */, - 340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */, 4521C3C01F59F3BA00B4C582 /* TextFieldHelper.swift in Sources */, 34D2CCDF206939B400CB1A14 /* DebugUIMessagesAction.m in Sources */, 340FC8AC204DAC8D007AEB0F /* PrivacySettingsTableViewController.m in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 1a6860b7b..fc580a824 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -3,7 +3,6 @@ // #import "AppDelegate.h" -#import "CodeVerificationViewController.h" #import "DebugLogger.h" #import "HomeViewController.h" #import "MainAppContext.h" @@ -12,7 +11,6 @@ #import "OWSOrphanDataCleaner.h" #import "OWSScreenLockUI.h" #import "Pastelog.h" -#import "RegistrationViewController.h" #import "Signal-Swift.h" #import "SignalApp.h" #import "SignalsNavigationController.h" @@ -632,10 +630,11 @@ static NSTimeInterval launchStartedAt; if ([signupController isKindOfClass:[OWSNavigationController class]]) { OWSNavigationController *navController = (OWSNavigationController *)signupController; UIViewController *controller = [navController.childViewControllers lastObject]; - if ([controller isKindOfClass:[CodeVerificationViewController class]]) { - CodeVerificationViewController *cvvc = (CodeVerificationViewController *)controller; + if ([controller isKindOfClass:[OnboardingVerificationViewController class]]) { + OnboardingVerificationViewController *verificationView + = (OnboardingVerificationViewController *)controller; NSString *verificationCode = [url.path substringFromIndex:1]; - [cvvc setVerificationCodeAndTryToVerify:verificationCode]; + [verificationView setVerificationCodeAndTryToVerify:verificationCode]; return YES; } else { OWSLogWarn(@"Not the verification view controller we expected. Got %@ instead", diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index 12e45a336..fd0a20bb9 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -41,7 +41,6 @@ #import "PinEntryView.h" #import "PrivacySettingsTableViewController.h" #import "ProfileViewController.h" -#import "RegistrationViewController.h" #import "RemoteVideoView.h" #import "SignalApp.h" #import "UIViewController+Permissions.h" diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m index 844a074c8..c14efff16 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m @@ -7,7 +7,6 @@ #import "OWSBackup.h" #import "OWSCountryMetadata.h" #import "OWSTableViewController.h" -#import "RegistrationViewController.h" #import "Signal-Swift.h" #import "ThreadUtil.h" #import @@ -168,7 +167,7 @@ NS_ASSUME_NONNULL_BEGIN [Environment.shared.preferences unsetRecordedAPNSTokens]; - RegistrationViewController *viewController = [RegistrationViewController new]; + UIViewController *viewController = [[OnboardingController new] initialViewController]; OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:viewController]; navigationController.navigationBarHidden = YES; diff --git a/Signal/src/ViewControllers/HomeView/HomeViewController.m b/Signal/src/ViewControllers/HomeView/HomeViewController.m index 2b34e195b..c21f0968c 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewController.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewController.m @@ -7,7 +7,6 @@ #import "AppSettingsViewController.h" #import "HomeViewCell.h" #import "NewContactThreadViewController.h" -#import "OWS2FARegistrationViewController.h" #import "OWSNavigationController.h" #import "OWSPrimaryStorage.h" #import "ProfileViewController.h" diff --git a/Signal/src/ViewControllers/OWS2FARegistrationViewController.h b/Signal/src/ViewControllers/OWS2FARegistrationViewController.h deleted file mode 100644 index 2b6bcd050..000000000 --- a/Signal/src/ViewControllers/OWS2FARegistrationViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface OWS2FARegistrationViewController : OWSViewController - -@property (nonatomic) NSString *verificationCode; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/OWS2FARegistrationViewController.m b/Signal/src/ViewControllers/OWS2FARegistrationViewController.m deleted file mode 100644 index 8b285eb31..000000000 --- a/Signal/src/ViewControllers/OWS2FARegistrationViewController.m +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "OWS2FARegistrationViewController.h" -#import "PinEntryView.h" -#import "ProfileViewController.h" -#import "Signal-Swift.h" -#import -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface OWS2FARegistrationViewController () - -@property (nonatomic) PinEntryView *entryView; - -@end - -#pragma mark - - -@implementation OWS2FARegistrationViewController - -#pragma mark - Dependencies - -- (AccountManager *)accountManager -{ - return AppEnvironment.shared.accountManager; -} - -#pragma mark - View Lifecycle - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - // The navigation bar is hidden in the registration workflow. - if (self.navigationController.navigationBarHidden) { - [self.navigationController setNavigationBarHidden:NO animated:YES]; - } - self.navigationItem.hidesBackButton = YES; - - self.title = NSLocalizedString(@"REGISTRATION_ENTER_LOCK_PIN_NAV_TITLE", - @"Navigation title shown when user is re-registering after having enabled registration lock"); - - self.view.backgroundColor = [Theme backgroundColor]; - - PinEntryView *entryView = [PinEntryView new]; - self.entryView = entryView; - entryView.delegate = self; - [self.view addSubview:entryView]; - - entryView.instructionsText = NSLocalizedString( - @"REGISTER_2FA_INSTRUCTIONS", @"Instructions to enter the 'two-factor auth pin' in the 2FA registration view."); - - // Layout - [entryView autoPinToTopLayoutGuideOfViewController:self withInset:0]; - [entryView autoPinEdgeToSuperviewMargin:ALEdgeLeft]; - [entryView autoPinEdgeToSuperviewMargin:ALEdgeRight]; - [entryView autoPinToBottomLayoutGuideOfViewController:self withInset:0]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - - [self.entryView makePinTextFieldFirstResponder]; -} - -#pragma mark - PinEntryViewDelegate - -- (void)pinEntryView:(PinEntryView *)entryView submittedPinCode:(NSString *)pinCode -{ - OWSAssertDebug(self.entryView.hasValidPin); - - [self tryToRegisterWithPinCode:pinCode]; -} - -- (void)pinEntryViewForgotPinLinkTapped:(PinEntryView *)entryView -{ - NSString *alertBody = NSLocalizedString(@"REGISTER_2FA_FORGOT_PIN_ALERT_MESSAGE", - @"Alert message explaining what happens if you forget your 'two-factor auth pin'."); - [OWSAlerts showAlertWithTitle:nil message:alertBody]; -} - -#pragma mark - Registration - -- (void)tryToRegisterWithPinCode:(NSString *)pinCode -{ - OWSAssertDebug(self.entryView.hasValidPin); - OWSAssertDebug(self.verificationCode.length > 0); - OWSAssertDebug(pinCode.length > 0); - - OWSLogInfo(@""); - - __weak OWS2FARegistrationViewController *weakSelf = self; - - [ModalActivityIndicatorViewController - presentFromViewController:self - canCancel:NO - backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { - OWSProdInfo([OWSAnalyticsEvents registrationRegisteringCode]); - [[self.accountManager registerObjcWithVerificationCode:self.verificationCode pin:pinCode] - .then(^{ - OWSAssertIsOnMainThread(); - OWSProdInfo([OWSAnalyticsEvents registrationRegisteringSubmittedCode]); - [[OWS2FAManager sharedManager] mark2FAAsEnabledWithPin:pinCode]; - - OWSLogInfo(@"Successfully registered Signal account."); - dispatch_async(dispatch_get_main_queue(), ^{ - [modalActivityIndicator dismissWithCompletion:^{ - OWSAssertIsOnMainThread(); - - [weakSelf verificationWasCompleted]; - }]; - }); - }) - .catch(^(NSError *error) { - OWSAssertIsOnMainThread(); - OWSProdInfo([OWSAnalyticsEvents registrationRegistrationFailed]); - OWSLogError(@"error verifying challenge: %@", error); - dispatch_async(dispatch_get_main_queue(), ^{ - [modalActivityIndicator dismissWithCompletion:^{ - OWSAssertIsOnMainThread(); - - [OWSAlerts - showAlertWithTitle:NSLocalizedString( - @"REGISTER_2FA_REGISTRATION_FAILED_ALERT_TITLE", - @"Title for alert indicating that attempt to " - @"register with 'two-factor auth' failed.") - message:error.localizedDescription]; - - [weakSelf.entryView makePinTextFieldFirstResponder]; - }]; - }); - }) retainUntilComplete]; - }]; -} - -- (void)verificationWasCompleted -{ - [RegistrationController verificationWasCompletedFromView:self]; -} - -#pragma mark - Orientation - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - return UIInterfaceOrientationMaskPortrait; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/Registration/CodeVerificationViewController.h b/Signal/src/ViewControllers/Registration/CodeVerificationViewController.h deleted file mode 100644 index 492aaa68b..000000000 --- a/Signal/src/ViewControllers/Registration/CodeVerificationViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface CodeVerificationViewController : OWSViewController - -- (void)setVerificationCodeAndTryToVerify:(NSString *)verificationCode; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m b/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m deleted file mode 100644 index 923955f0b..000000000 --- a/Signal/src/ViewControllers/Registration/CodeVerificationViewController.m +++ /dev/null @@ -1,509 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "CodeVerificationViewController.h" -#import "OWS2FARegistrationViewController.h" -#import "ProfileViewController.h" -#import "Signal-Swift.h" -#import -#import -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface CodeVerificationViewController () - -// Where the user enters the verification code they wish to document -@property (nonatomic) UITextField *challengeTextField; - -@property (nonatomic) UILabel *phoneNumberLabel; - -//// User action buttons -@property (nonatomic) OWSFlatButton *submitButton; -@property (nonatomic) UIButton *sendCodeViaSMSAgainButton; -@property (nonatomic) UIButton *sendCodeViaVoiceButton; - -@property (nonatomic) UIActivityIndicatorView *submitCodeSpinner; -@property (nonatomic) UIActivityIndicatorView *requestCodeAgainSpinner; -@property (nonatomic) UIActivityIndicatorView *requestCallSpinner; - -@end - -#pragma mark - - -@implementation CodeVerificationViewController - -#pragma mark - Dependencies - -- (TSAccountManager *)tsAccountManager -{ - OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); - - return SSKEnvironment.shared.tsAccountManager; -} - -- (AccountManager *)accountManager -{ - return AppEnvironment.shared.accountManager; -} - -#pragma mark - View Lifecycle - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.shouldUseTheme = NO; - - [self createViews]; - - [self initializeKeyboardHandlers]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - [self enableServerActions:YES]; - [self updatePhoneNumberLabel]; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - [_challengeTextField becomeFirstResponder]; -} - -#pragma mark - - -- (void)createViews -{ - self.view.backgroundColor = [UIColor whiteColor]; - self.view.opaque = YES; - - UIColor *signalBlueColor = [UIColor ows_signalBrandBlueColor]; - - UIView *header = [UIView new]; - header.backgroundColor = signalBlueColor; - [self.view addSubview:header]; - [header autoPinWidthToSuperview]; - [header autoPinEdgeToSuperviewEdge:ALEdgeTop]; - // The header will grow to accomodate the titleLabel's height. - - UILabel *titleLabel = [UILabel new]; - titleLabel.textColor = [UIColor whiteColor]; - titleLabel.text = [self phoneNumberText]; - titleLabel.font = [UIFont ows_mediumFontWithSize:20.f]; - [header addSubview:titleLabel]; - [titleLabel autoPinToTopLayoutGuideOfViewController:self withInset:0]; - [titleLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom]; - [titleLabel autoSetDimension:ALDimensionHeight toSize:40]; - [titleLabel autoHCenterInSuperview]; - - // This view is used in more than one context. - // - // * Usually, it is pushed atop RegistrationViewController in which - // case we want a "back" button. - // * It can also be used to re-register from the app's "de-registration" - // views, in which case RegistrationViewController is not used and we - // do _not_ want a "back" button. - if (self.navigationController.viewControllers.count > 1) { - UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [backButton - setTitle:NSLocalizedString(@"VERIFICATION_BACK_BUTTON", @"button text for back button on verification view") - forState:UIControlStateNormal]; - [backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - backButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f]; - [header addSubview:backButton]; - [backButton autoPinLeadingToSuperviewMarginWithInset:10.f]; - [backButton autoAlignAxis:ALAxisHorizontal toSameAxisOfView:titleLabel]; - [backButton addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; - } - - _phoneNumberLabel = [UILabel new]; - _phoneNumberLabel.textColor = [UIColor ows_darkGrayColor]; - _phoneNumberLabel.font = [UIFont ows_regularFontWithSize:20.f]; - _phoneNumberLabel.numberOfLines = 2; - _phoneNumberLabel.adjustsFontSizeToFitWidth = YES; - _phoneNumberLabel.textAlignment = NSTextAlignmentCenter; - [self.view addSubview:_phoneNumberLabel]; - [_phoneNumberLabel autoPinWidthToSuperviewWithMargin:ScaleFromIPhone5(32)]; - [_phoneNumberLabel autoPinEdge:ALEdgeTop - toEdge:ALEdgeBottom - ofView:header - withOffset:ScaleFromIPhone5To7Plus(30, 100)]; - - const CGFloat kHMargin = 36; - - if (UIDevice.currentDevice.isShorterThanIPhone5) { - _challengeTextField = [DismissableTextField new]; - } else { - _challengeTextField = [OWSTextField new]; - } - - _challengeTextField.textColor = [UIColor blackColor]; - _challengeTextField.placeholder = NSLocalizedString(@"VERIFICATION_CHALLENGE_DEFAULT_TEXT", - @"Text field placeholder for SMS verification code during registration"); - _challengeTextField.font = [UIFont ows_lightFontWithSize:21.f]; - _challengeTextField.textAlignment = NSTextAlignmentCenter; - _challengeTextField.keyboardType = UIKeyboardTypeNumberPad; - _challengeTextField.delegate = self; - [self.view addSubview:_challengeTextField]; - [_challengeTextField autoPinWidthToSuperviewWithMargin:kHMargin]; - [_challengeTextField autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_phoneNumberLabel withOffset:25]; - - UIView *underscoreView = [UIView new]; - underscoreView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1.f]; - [self.view addSubview:underscoreView]; - [underscoreView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_challengeTextField withOffset:3]; - [underscoreView autoPinWidthToSuperviewWithMargin:kHMargin]; - [underscoreView autoSetDimension:ALDimensionHeight toSize:1.f]; - - const CGFloat kSubmitButtonHeight = 47.f; - // NOTE: We use ows_signalBrandBlueColor instead of ows_materialBlueColor - // throughout the onboarding flow to be consistent with the headers. - OWSFlatButton *submitButton = - [OWSFlatButton buttonWithTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SUBMIT_CODE", - @"button text during registration to submit your SMS verification code.") - font:[OWSFlatButton fontForHeight:kSubmitButtonHeight] - titleColor:[UIColor whiteColor] - backgroundColor:[UIColor ows_signalBrandBlueColor] - target:self - selector:@selector(submitVerificationCode)]; - self.submitButton = submitButton; - [self.view addSubview:_submitButton]; - [_submitButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:underscoreView withOffset:15]; - [_submitButton autoPinWidthToSuperviewWithMargin:kHMargin]; - [_submitButton autoSetDimension:ALDimensionHeight toSize:kSubmitButtonHeight]; - - const CGFloat kSpinnerSize = 20; - const CGFloat kSpinnerSpacing = ScaleFromIPhone5To7Plus(5, 15); - - _submitCodeSpinner = - [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - [_submitButton addSubview:_submitCodeSpinner]; - [_submitCodeSpinner autoSetDimension:ALDimensionWidth toSize:kSpinnerSize]; - [_submitCodeSpinner autoSetDimension:ALDimensionHeight toSize:kSpinnerSize]; - [_submitCodeSpinner autoVCenterInSuperview]; - [_submitCodeSpinner autoPinTrailingToSuperviewMarginWithInset:kSpinnerSpacing]; - - _sendCodeViaSMSAgainButton = [UIButton buttonWithType:UIButtonTypeCustom]; - _sendCodeViaSMSAgainButton.backgroundColor = [UIColor whiteColor]; - [_sendCodeViaSMSAgainButton setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SUBMIT_AGAIN", - @"button text during registration to request another SMS code be sent") - forState:UIControlStateNormal]; - [_sendCodeViaSMSAgainButton setTitleColor:signalBlueColor forState:UIControlStateNormal]; - _sendCodeViaSMSAgainButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f]; - [_sendCodeViaSMSAgainButton addTarget:self - action:@selector(sendCodeViaSMSAction:) - forControlEvents:UIControlEventTouchUpInside]; - [self.view addSubview:_sendCodeViaSMSAgainButton]; - [_sendCodeViaSMSAgainButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_submitButton withOffset:10]; - [_sendCodeViaSMSAgainButton autoPinWidthToSuperviewWithMargin:kHMargin]; - [_sendCodeViaSMSAgainButton autoSetDimension:ALDimensionHeight toSize:35]; - - _requestCodeAgainSpinner = - [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [_sendCodeViaSMSAgainButton addSubview:_requestCodeAgainSpinner]; - [_requestCodeAgainSpinner autoSetDimension:ALDimensionWidth toSize:kSpinnerSize]; - [_requestCodeAgainSpinner autoSetDimension:ALDimensionHeight toSize:kSpinnerSize]; - [_requestCodeAgainSpinner autoVCenterInSuperview]; - [_requestCodeAgainSpinner autoPinTrailingToSuperviewMarginWithInset:kSpinnerSpacing]; - - _sendCodeViaVoiceButton = [UIButton buttonWithType:UIButtonTypeCustom]; - _sendCodeViaVoiceButton.backgroundColor = [UIColor whiteColor]; - [_sendCodeViaVoiceButton - setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SEND_VIA_VOICE", - @"button text during registration to request phone number verification be done via phone call") - forState:UIControlStateNormal]; - [_sendCodeViaVoiceButton setTitleColor:signalBlueColor forState:UIControlStateNormal]; - _sendCodeViaVoiceButton.titleLabel.font = [UIFont ows_mediumFontWithSize:14.f]; - [_sendCodeViaVoiceButton addTarget:self - action:@selector(sendCodeViaVoiceAction:) - forControlEvents:UIControlEventTouchUpInside]; - [self.view addSubview:_sendCodeViaVoiceButton]; - [_sendCodeViaVoiceButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_sendCodeViaSMSAgainButton]; - [_sendCodeViaVoiceButton autoPinWidthToSuperviewWithMargin:kHMargin]; - [_sendCodeViaVoiceButton autoSetDimension:ALDimensionHeight toSize:35]; - - _requestCallSpinner = - [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [_sendCodeViaVoiceButton addSubview:_requestCallSpinner]; - [_requestCallSpinner autoSetDimension:ALDimensionWidth toSize:kSpinnerSize]; - [_requestCallSpinner autoSetDimension:ALDimensionHeight toSize:kSpinnerSize]; - [_requestCallSpinner autoVCenterInSuperview]; - [_requestCallSpinner autoPinTrailingToSuperviewMarginWithInset:kSpinnerSpacing]; -} - -- (NSString *)phoneNumberText -{ - OWSAssertDebug([TSAccountManager localNumber] != nil); - return [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:[TSAccountManager localNumber]]; -} - -- (void)updatePhoneNumberLabel -{ - _phoneNumberLabel.text = - [NSString stringWithFormat:NSLocalizedString(@"VERIFICATION_PHONE_NUMBER_FORMAT", - @"Label indicating the phone number currently being verified."), - [self phoneNumberText]]; -} - -- (void)startActivityIndicator -{ - [self.submitCodeSpinner startAnimating]; - [self enableServerActions:NO]; - [self.challengeTextField resignFirstResponder]; -} - -- (void)stopActivityIndicator -{ - [self enableServerActions:YES]; - [self.submitCodeSpinner stopAnimating]; -} - -- (void)submitVerificationCode -{ - [self startActivityIndicator]; - OWSProdInfo([OWSAnalyticsEvents registrationRegisteringCode]); - __weak CodeVerificationViewController *weakSelf = self; - [[self.accountManager registerObjcWithVerificationCode:[self validationCodeFromTextField] pin:nil] - .then(^{ - OWSProdInfo([OWSAnalyticsEvents registrationRegisteringSubmittedCode]); - - OWSLogInfo(@"Successfully registered Signal account."); - dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf stopActivityIndicator]; - [weakSelf verificationWasCompleted]; - }); - }) - .catch(^(NSError *error) { - OWSLogError(@"error: %@, %@, %zd", [error class], error.domain, error.code); - OWSProdInfo([OWSAnalyticsEvents registrationRegistrationFailed]); - OWSLogError(@"error verifying challenge: %@", error); - dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf stopActivityIndicator]; - - if ([error.domain isEqualToString:OWSSignalServiceKitErrorDomain] - && error.code == OWSErrorCodeRegistrationMissing2FAPIN) { - CodeVerificationViewController *strongSelf = weakSelf; - if (!strongSelf) { - return; - } - OWSLogInfo(@"Showing 2FA registration view."); - OWS2FARegistrationViewController *viewController = [OWS2FARegistrationViewController new]; - viewController.verificationCode = strongSelf.validationCodeFromTextField; - [strongSelf.navigationController pushViewController:viewController animated:YES]; - } else { - [weakSelf presentAlertWithVerificationError:error]; - [weakSelf.challengeTextField becomeFirstResponder]; - } - }); - }) retainUntilComplete]; -} - -- (void)verificationWasCompleted -{ - [RegistrationController verificationWasCompletedFromView:self]; -} - -- (void)presentAlertWithVerificationError:(NSError *)error -{ - UIAlertController *alert; - alert = [UIAlertController - alertControllerWithTitle:NSLocalizedString(@"REGISTRATION_VERIFICATION_FAILED_TITLE", @"Alert view title") - message:error.localizedDescription - preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:CommonStrings.dismissButton - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action) { - [self.challengeTextField becomeFirstResponder]; - }]]; - - [self presentViewController:alert animated:YES completion:nil]; -} - -- (NSString *)validationCodeFromTextField -{ - return [self.challengeTextField.text stringByReplacingOccurrencesOfString:@"-" withString:@""]; -} - -#pragma mark - Actions - -- (void)sendCodeViaSMSAction:(id)sender -{ - OWSProdInfo([OWSAnalyticsEvents registrationRegisteringRequestedNewCodeBySms]); - - [self enableServerActions:NO]; - - [_requestCodeAgainSpinner startAnimating]; - __weak CodeVerificationViewController *weakSelf = self; - [self.tsAccountManager rerequestSMSWithCaptchaToken:nil - success:^{ - OWSLogInfo(@"Successfully requested SMS code"); - [weakSelf enableServerActions:YES]; - [weakSelf.requestCodeAgainSpinner stopAnimating]; - } - failure:^(NSError *error) { - OWSLogError(@"Failed to request SMS code with error: %@", error); - [weakSelf showRegistrationErrorMessage:error]; - [weakSelf enableServerActions:YES]; - [weakSelf.requestCodeAgainSpinner stopAnimating]; - [weakSelf.challengeTextField becomeFirstResponder]; - }]; -} - -- (void)sendCodeViaVoiceAction:(id)sender -{ - OWSProdInfo([OWSAnalyticsEvents registrationRegisteringRequestedNewCodeByVoice]); - - [self enableServerActions:NO]; - - [_requestCallSpinner startAnimating]; - __weak CodeVerificationViewController *weakSelf = self; - [self.tsAccountManager rerequestVoiceWithCaptchaToken:nil - success:^{ - OWSLogInfo(@"Successfully requested voice code"); - - [weakSelf enableServerActions:YES]; - [weakSelf.requestCallSpinner stopAnimating]; - } - failure:^(NSError *error) { - OWSLogError(@"Failed to request voice code with error: %@", error); - [weakSelf showRegistrationErrorMessage:error]; - [weakSelf enableServerActions:YES]; - [weakSelf.requestCallSpinner stopAnimating]; - [weakSelf.challengeTextField becomeFirstResponder]; - }]; -} - -- (void)showRegistrationErrorMessage:(NSError *)registrationError -{ - [OWSAlerts showAlertWithTitle:registrationError.localizedDescription - message:registrationError.localizedRecoverySuggestion]; -} - -- (void)enableServerActions:(BOOL)enabled -{ - [_submitButton setEnabled:enabled]; - [_sendCodeViaSMSAgainButton setEnabled:enabled]; - [_sendCodeViaVoiceButton setEnabled:enabled]; -} - -- (void)backButtonPressed:(id)sender -{ - OWSProdInfo([OWSAnalyticsEvents registrationVerificationBack]); - - [self.navigationController popViewControllerAnimated:YES]; -} - -#pragma mark - Keyboard notifications - -- (void)initializeKeyboardHandlers -{ - UITapGestureRecognizer *outsideTabRecognizer = - [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)]; - [self.view addGestureRecognizer:outsideTabRecognizer]; - self.view.userInteractionEnabled = YES; -} - -- (void)dismissKeyboardFromAppropriateSubView -{ - [self.view endEditing:NO]; -} - -- (BOOL)textField:(UITextField *)textField - shouldChangeCharactersInRange:(NSRange)range - replacementString:(NSString *)insertionText -{ - - // Verification codes take this form: "123-456". - // - // * We only want to let the user "6 decimal digits + 1 hyphen = 7". - // * The user shouldn't have to enter the hyphen - it should be added automatically. - // * The user should be able to copy and paste freely. - // * Invalid input (including extraneous hyphens) should be simply ignored. - // - // We accomplish this by being permissive and trying to "take as much of the user - // input as possible". - // - // * Always accept deletes. - // * Ignore invalid input. - // * Take partial input if possible. - - NSString *oldText = textField.text; - // Construct the new contents of the text field by: - // 1. Determining the "left" substring: the contents of the old text _before_ the deletion range. - // Filtering will remove non-decimal digit characters like hyphen "-". - NSString *left = [oldText substringToIndex:range.location].digitsOnly; - // 2. Determining the "right" substring: the contents of the old text _after_ the deletion range. - NSString *right = [oldText substringFromIndex:range.location + range.length].digitsOnly; - // 3. Determining the "center" substring: the contents of the new insertion text. - NSString *center = insertionText.digitsOnly; - // 3a. Trim the tail of the "center" substring to ensure that we don't end up - // with more than 6 decimal digits. - while (center.length > 0 && left.length + center.length + right.length > 6) { - center = [center substringToIndex:center.length - 1]; - } - // 4. Construct the "raw" new text by concatenating left, center and right. - NSString *rawNewText = [[left stringByAppendingString:center] stringByAppendingString:right]; - // 5. Construct the "formatted" new text by inserting a hyphen if necessary. - NSString *formattedNewText - = (rawNewText.length <= 3 ? rawNewText - : [[[rawNewText substringToIndex:3] stringByAppendingString:@"-"] - stringByAppendingString:[rawNewText substringFromIndex:3]]); - textField.text = formattedNewText; - - // Move the cursor after the newly inserted text. - NSUInteger newInsertionPoint = left.length + center.length; - if (newInsertionPoint > 3) { - // Nudge the cursor to the right to reflect the hyphen - // if necessary. - newInsertionPoint++; - } - UITextPosition *newPosition = - [textField positionFromPosition:textField.beginningOfDocument offset:(NSInteger)newInsertionPoint]; - textField.selectedTextRange = [textField textRangeFromPosition:newPosition toPosition:newPosition]; - - return NO; -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField -{ - [self submitVerificationCode]; - [textField resignFirstResponder]; - return NO; -} - -- (void)setVerificationCodeAndTryToVerify:(NSString *)verificationCode -{ - NSString *rawNewText = verificationCode.digitsOnly; - NSString *formattedNewText - = (rawNewText.length <= 3 ? rawNewText - : [[[rawNewText substringToIndex:3] stringByAppendingString:@"-"] - stringByAppendingString:[rawNewText substringFromIndex:3]]); - self.challengeTextField.text = formattedNewText; - // Move the cursor after the newly inserted text. - UITextPosition *newPosition = [self.challengeTextField endOfDocument]; - self.challengeTextField.selectedTextRange = - [self.challengeTextField textRangeFromPosition:newPosition toPosition:newPosition]; - [self submitVerificationCode]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return UIStatusBarStyleLightContent; -} - -#pragma mark - Orientation - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - return UIInterfaceOrientationMaskPortrait; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift b/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift index 3d21e96d6..e43d9f2e3 100644 --- a/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift +++ b/Signal/src/ViewControllers/Registration/OnboardingVerificationViewController.swift @@ -187,6 +187,14 @@ private class OnboardingCodeView: UIView { digitStroke.backgroundColor = backgroundColor } } + + fileprivate func set(verificationCode: String) { + digitText = verificationCode + + updateViewState() + + self.delegate?.codeViewDidChange() + } } // MARK: - @@ -251,10 +259,16 @@ public class OnboardingVerificationViewController: OnboardingBaseViewController private var codeState = CodeState.sent private var titleLabel: UILabel? + private var backLink: UIView? private let onboardingCodeView = OnboardingCodeView() private var codeStateLink: OWSFlatButton? private let errorLabel = UILabel() + @objc + public func hideBackLink() { + backLink?.isHidden = true + } + override public func loadView() { super.loadView() @@ -267,6 +281,7 @@ public class OnboardingVerificationViewController: OnboardingBaseViewController let backLink = self.linkButton(title: NSLocalizedString("ONBOARDING_VERIFICATION_BACK_LINK", comment: "Label for the link that lets users change their phone number in the onboarding views."), selector: #selector(backLinkTapped)) + self.backLink = backLink onboardingCodeView.delegate = self @@ -495,6 +510,19 @@ public class OnboardingVerificationViewController: OnboardingBaseViewController onboardingCodeView.setHasError(value) errorLabel.isHidden = !value } + + @objc + public func setVerificationCodeAndTryToVerify(_ verificationCode: String) { + AssertIsOnMainThread() + + let filteredCode = verificationCode.digitsOnly + guard filteredCode.count > 0 else { + owsFailDebug("Invalid code: \(verificationCode)") + return + } + + onboardingCodeView.set(verificationCode: filteredCode) + } } // MARK: - diff --git a/Signal/src/ViewControllers/Registration/RegistrationController.swift b/Signal/src/ViewControllers/Registration/RegistrationController.swift index 58ce9b616..25e9c63cd 100644 --- a/Signal/src/ViewControllers/Registration/RegistrationController.swift +++ b/Signal/src/ViewControllers/Registration/RegistrationController.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import UIKit @@ -23,30 +23,6 @@ public class RegistrationController: NSObject { // MARK: - - @objc - public class func verificationWasCompleted(fromView view: UIViewController) { - AssertIsOnMainThread() - - if tsAccountManager.isReregistering() { - showProfileView(fromView: view) - } else { - checkCanImportBackup(fromView: view) - } - } - - private class func showProfileView(fromView view: UIViewController) { - AssertIsOnMainThread() - - Logger.info("") - - guard let navigationController = view.navigationController else { - owsFailDebug("Missing navigationController") - return - } - - ProfileViewController.present(forRegistration: navigationController) - } - private class func showBackupRestoreView(fromView view: UIViewController) { AssertIsOnMainThread() @@ -61,44 +37,45 @@ public class RegistrationController: NSObject { navigationController.setViewControllers([restoreView], animated: true) } - private class func checkCanImportBackup(fromView view: UIViewController) { - AssertIsOnMainThread() - - Logger.info("") - - self.backup.checkCanImport({ (canImport) in - Logger.info("canImport: \(canImport)") - - if (canImport) { - self.backup.setHasPendingRestoreDecision(true) - - self.showBackupRestoreView(fromView: view) - } else { - self.showProfileView(fromView: view) - } - }) { (_) in - self.showBackupCheckFailedAlert(fromView: view) - } - } - - private class func showBackupCheckFailedAlert(fromView view: UIViewController) { - AssertIsOnMainThread() - - Logger.info("") - - let alert = UIAlertController(title: NSLocalizedString("CHECK_FOR_BACKUP_FAILED_TITLE", - comment: "Title for alert shown when the app failed to check for an existing backup."), - message: NSLocalizedString("CHECK_FOR_BACKUP_FAILED_MESSAGE", - comment: "Message for alert shown when the app failed to check for an existing backup."), - preferredStyle: .alert) - alert.addAction(UIAlertAction(title: NSLocalizedString("REGISTER_FAILED_TRY_AGAIN", comment: ""), - style: .default) { (_) in - self.checkCanImportBackup(fromView: view) - }) - alert.addAction(UIAlertAction(title: NSLocalizedString("CHECK_FOR_BACKUP_DO_NOT_RESTORE", comment: "The label for the 'do not restore backup' button."), - style: .destructive) { (_) in - self.showProfileView(fromView: view) - }) - view.present(alert, animated: true) - } + // TODO: OnboardingController will eventually need to do something like this. +// private class func checkCanImportBackup(fromView view: UIViewController) { +// AssertIsOnMainThread() +// +// Logger.info("") +// +// self.backup.checkCanImport({ (canImport) in +// Logger.info("canImport: \(canImport)") +// +// if (canImport) { +// self.backup.setHasPendingRestoreDecision(true) +// +// self.showBackupRestoreView(fromView: view) +// } else { +// self.showProfileView(fromView: view) +// } +// }) { (_) in +// self.showBackupCheckFailedAlert(fromView: view) +// } +// } +// +// private class func showBackupCheckFailedAlert(fromView view: UIViewController) { +// AssertIsOnMainThread() +// +// Logger.info("") +// +// let alert = UIAlertController(title: NSLocalizedString("CHECK_FOR_BACKUP_FAILED_TITLE", +// comment: "Title for alert shown when the app failed to check for an existing backup."), +// message: NSLocalizedString("CHECK_FOR_BACKUP_FAILED_MESSAGE", +// comment: "Message for alert shown when the app failed to check for an existing backup."), +// preferredStyle: .alert) +// alert.addAction(UIAlertAction(title: NSLocalizedString("REGISTER_FAILED_TRY_AGAIN", comment: ""), +// style: .default) { (_) in +// self.checkCanImportBackup(fromView: view) +// }) +// alert.addAction(UIAlertAction(title: NSLocalizedString("CHECK_FOR_BACKUP_DO_NOT_RESTORE", comment: "The label for the 'do not restore backup' button."), +// style: .destructive) { (_) in +// self.showProfileView(fromView: view) +// }) +// view.present(alert, animated: true) +// } } diff --git a/Signal/src/ViewControllers/Registration/RegistrationViewController.h b/Signal/src/ViewControllers/Registration/RegistrationViewController.h deleted file mode 100644 index 32cbe803c..000000000 --- a/Signal/src/ViewControllers/Registration/RegistrationViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface RegistrationViewController : OWSViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/Registration/RegistrationViewController.m b/Signal/src/ViewControllers/Registration/RegistrationViewController.m deleted file mode 100644 index 1f9de366e..000000000 --- a/Signal/src/ViewControllers/Registration/RegistrationViewController.m +++ /dev/null @@ -1,646 +0,0 @@ -// -// Copyright (c) 2019 Open Whisper Systems. All rights reserved. -// - -#import "RegistrationViewController.h" -#import "CodeVerificationViewController.h" -#import "CountryCodeViewController.h" -#import "PhoneNumber.h" -#import "PhoneNumberUtil.h" -#import "Signal-Swift.h" -#import "TSAccountManager.h" -#import "UIView+OWS.h" -#import "ViewControllerUtils.h" -#import -#import -#import -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -#ifdef DEBUG - -NSString *const kKeychainService_LastRegistered = @"kKeychainService_LastRegistered"; -NSString *const kKeychainKey_LastRegisteredCountryCode = @"kKeychainKey_LastRegisteredCountryCode"; -NSString *const kKeychainKey_LastRegisteredPhoneNumber = @"kKeychainKey_LastRegisteredPhoneNumber"; - -#endif - -@interface RegistrationViewController () - -@property (nonatomic) NSString *countryCode; -@property (nonatomic) NSString *callingCode; - -@property (nonatomic) UILabel *countryCodeLabel; -@property (nonatomic) UITextField *phoneNumberTextField; -@property (nonatomic) UILabel *examplePhoneNumberLabel; -@property (nonatomic) OWSFlatButton *activateButton; -@property (nonatomic) UIActivityIndicatorView *spinnerView; - -@end - -#pragma mark - - -@implementation RegistrationViewController - -#pragma mark - Dependencies - -- (TSAccountManager *)tsAccountManager -{ - OWSAssertDebug(SSKEnvironment.shared.tsAccountManager); - - return SSKEnvironment.shared.tsAccountManager; -} - -#pragma mark - - -- (void)loadView -{ - [super loadView]; - - self.shouldUseTheme = NO; - - [self createViews]; - - // Do any additional setup after loading the view. - [self populateDefaultCountryNameAndCode]; - OWSAssertDebug([self.navigationController isKindOfClass:[OWSNavigationController class]]); - [SignalApp.sharedApp setSignUpFlowNavigationController:(OWSNavigationController *)self.navigationController]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - OWSProdInfo([OWSAnalyticsEvents registrationBegan]); -} - -- (void)createViews -{ - self.view.backgroundColor = [UIColor whiteColor]; - self.view.userInteractionEnabled = YES; - [self.view - addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTapped:)]]; - self.view.accessibilityIdentifier = SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, @"root_view"); - - UIView *headerWrapper = [UIView containerView]; - [self.view addSubview:headerWrapper]; - headerWrapper.backgroundColor = UIColor.ows_signalBrandBlueColor; - [headerWrapper autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero excludingEdge:ALEdgeBottom]; - - UILabel *headerLabel = [UILabel new]; - headerLabel.text = NSLocalizedString(@"REGISTRATION_TITLE_LABEL", @""); - headerLabel.textColor = [UIColor whiteColor]; - headerLabel.font = [UIFont ows_mediumFontWithSize:ScaleFromIPhone5To7Plus(20.f, 24.f)]; - - NSString *legalTopMatterFormat = NSLocalizedString(@"REGISTRATION_LEGAL_TOP_MATTER_FORMAT", - @"legal disclaimer, embeds a tappable {{link title}} which is styled as a hyperlink"); - NSString *legalTopMatterLinkWord = NSLocalizedString( - @"REGISTRATION_LEGAL_TOP_MATTER_LINK_TITLE", @"embedded in legal topmatter, styled as a link"); - NSString *legalTopMatter = [NSString stringWithFormat:legalTopMatterFormat, legalTopMatterLinkWord]; - NSMutableAttributedString *attributedLegalTopMatter = - [[NSMutableAttributedString alloc] initWithString:legalTopMatter]; - NSRange linkRange = [legalTopMatter rangeOfString:legalTopMatterLinkWord]; - NSDictionary *linkStyleAttributes = @{ - NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid), - }; - [attributedLegalTopMatter setAttributes:linkStyleAttributes range:linkRange]; - - UILabel *legalTopMatterLabel = [UILabel new]; - legalTopMatterLabel.textColor = UIColor.whiteColor; - legalTopMatterLabel.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(13.f, 15.f)]; - legalTopMatterLabel.numberOfLines = 0; - legalTopMatterLabel.textAlignment = NSTextAlignmentCenter; - legalTopMatterLabel.attributedText = attributedLegalTopMatter; - legalTopMatterLabel.userInteractionEnabled = YES; - SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, legalTopMatterLabel); - - UITapGestureRecognizer *tapGesture = - [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapLegalTerms:)]; - [legalTopMatterLabel addGestureRecognizer:tapGesture]; - - UIStackView *headerContent = [[UIStackView alloc] initWithArrangedSubviews:@[ headerLabel ]]; - [headerContent addArrangedSubview:legalTopMatterLabel]; - headerContent.axis = UILayoutConstraintAxisVertical; - headerContent.alignment = UIStackViewAlignmentCenter; - headerContent.spacing = ScaleFromIPhone5To7Plus(8, 16); - headerContent.layoutMarginsRelativeArrangement = YES; - - { - CGFloat topMargin = ScaleFromIPhone5To7Plus(4, 16); - CGFloat bottomMargin = ScaleFromIPhone5To7Plus(8, 16); - headerContent.layoutMargins = UIEdgeInsetsMake(topMargin, 40, bottomMargin, 40); - } - - [headerWrapper addSubview:headerContent]; - [headerContent autoPinToTopLayoutGuideOfViewController:self withInset:0]; - [headerContent autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeTop]; - - const CGFloat kRowHeight = 60.f; - const CGFloat kRowHMargin = 20.f; - const CGFloat kSeparatorHeight = 1.f; - const CGFloat kExamplePhoneNumberVSpacing = 8.f; - const CGFloat fontSizePoints = ScaleFromIPhone5To7Plus(16.f, 20.f); - - UIView *contentView = [UIView containerView]; - [contentView setHLayoutMargins:kRowHMargin]; - contentView.backgroundColor = [UIColor whiteColor]; - [self.view addSubview:contentView]; - [contentView autoPinToBottomLayoutGuideOfViewController:self withInset:0]; - [contentView autoPinWidthToSuperview]; - [contentView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:headerContent]; - - // Country - UIView *countryRow = [UIView containerView]; - [contentView addSubview:countryRow]; - [countryRow autoPinLeadingAndTrailingToSuperviewMargin]; - [countryRow autoPinEdgeToSuperviewEdge:ALEdgeTop]; - [countryRow autoSetDimension:ALDimensionHeight toSize:kRowHeight]; - [countryRow - addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(countryCodeRowWasTapped:)]]; - SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, countryRow); - - UILabel *countryNameLabel = [UILabel new]; - countryNameLabel.text - = NSLocalizedString(@"REGISTRATION_DEFAULT_COUNTRY_NAME", @"Label for the country code field"); - countryNameLabel.textColor = [UIColor blackColor]; - countryNameLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints]; - [countryRow addSubview:countryNameLabel]; - [countryNameLabel autoVCenterInSuperview]; - [countryNameLabel autoPinLeadingToSuperviewMargin]; - - UILabel *countryCodeLabel = [UILabel new]; - self.countryCodeLabel = countryCodeLabel; - countryCodeLabel.textColor = [UIColor ows_materialBlueColor]; - countryCodeLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints + 2.f]; - [countryRow addSubview:countryCodeLabel]; - [countryCodeLabel autoVCenterInSuperview]; - [countryCodeLabel autoPinTrailingToSuperviewMargin]; - - UIView *separatorView1 = [UIView new]; - separatorView1.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.f]; - [contentView addSubview:separatorView1]; - [separatorView1 autoPinWidthToSuperview]; - [separatorView1 autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:countryRow]; - [separatorView1 autoSetDimension:ALDimensionHeight toSize:kSeparatorHeight]; - - // Phone Number - UIView *phoneNumberRow = [UIView containerView]; - [contentView addSubview:phoneNumberRow]; - [phoneNumberRow autoPinLeadingAndTrailingToSuperviewMargin]; - [phoneNumberRow autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:separatorView1]; - [phoneNumberRow autoSetDimension:ALDimensionHeight toSize:kRowHeight]; - - UILabel *phoneNumberLabel = [UILabel new]; - phoneNumberLabel.text - = NSLocalizedString(@"REGISTRATION_PHONENUMBER_BUTTON", @"Label for the phone number textfield"); - phoneNumberLabel.textColor = [UIColor blackColor]; - phoneNumberLabel.font = [UIFont ows_mediumFontWithSize:fontSizePoints]; - [phoneNumberRow addSubview:phoneNumberLabel]; - [phoneNumberLabel autoVCenterInSuperview]; - [phoneNumberLabel autoPinLeadingToSuperviewMargin]; - - UITextField *phoneNumberTextField; - if (UIDevice.currentDevice.isShorterThanIPhone5) { - phoneNumberTextField = [DismissableTextField new]; - } else { - phoneNumberTextField = [OWSTextField new]; - } - - phoneNumberTextField.textAlignment = NSTextAlignmentRight; - phoneNumberTextField.delegate = self; - phoneNumberTextField.keyboardType = UIKeyboardTypeNumberPad; - phoneNumberTextField.placeholder = NSLocalizedString( - @"REGISTRATION_ENTERNUMBER_DEFAULT_TEXT", @"Placeholder text for the phone number textfield"); - self.phoneNumberTextField = phoneNumberTextField; - phoneNumberTextField.textColor = [UIColor ows_materialBlueColor]; - phoneNumberTextField.font = [UIFont ows_mediumFontWithSize:fontSizePoints + 2]; - [phoneNumberRow addSubview:phoneNumberTextField]; - [phoneNumberTextField autoVCenterInSuperview]; - [phoneNumberTextField autoPinTrailingToSuperviewMargin]; - SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, phoneNumberTextField); - - UILabel *examplePhoneNumberLabel = [UILabel new]; - self.examplePhoneNumberLabel = examplePhoneNumberLabel; - examplePhoneNumberLabel.font = [UIFont ows_regularFontWithSize:fontSizePoints - 2.f]; - examplePhoneNumberLabel.textColor = Theme.middleGrayColor; - [contentView addSubview:examplePhoneNumberLabel]; - [examplePhoneNumberLabel autoPinTrailingToSuperviewMargin]; - [examplePhoneNumberLabel autoPinEdge:ALEdgeTop - toEdge:ALEdgeBottom - ofView:phoneNumberTextField - withOffset:kExamplePhoneNumberVSpacing]; - - UIView *separatorView2 = [UIView new]; - separatorView2.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.f]; - [contentView addSubview:separatorView2]; - [separatorView2 autoPinWidthToSuperview]; - [separatorView2 autoPinEdge:ALEdgeTop - toEdge:ALEdgeBottom - ofView:phoneNumberRow - withOffset:examplePhoneNumberLabel.font.lineHeight]; - [separatorView2 autoSetDimension:ALDimensionHeight toSize:kSeparatorHeight]; - - // Activate Button - const CGFloat kActivateButtonHeight = 47.f; - // NOTE: We use ows_signalBrandBlueColor instead of ows_materialBlueColor - // throughout the onboarding flow to be consistent with the headers. - OWSFlatButton *activateButton = [OWSFlatButton buttonWithTitle:NSLocalizedString(@"REGISTRATION_VERIFY_DEVICE", @"") - font:[OWSFlatButton fontForHeight:kActivateButtonHeight] - titleColor:[UIColor whiteColor] - backgroundColor:[UIColor ows_signalBrandBlueColor] - target:self - selector:@selector(didTapRegisterButton)]; - self.activateButton = activateButton; - [contentView addSubview:activateButton]; - [activateButton autoPinLeadingAndTrailingToSuperviewMargin]; - [activateButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:separatorView2 withOffset:15]; - [activateButton autoSetDimension:ALDimensionHeight toSize:kActivateButtonHeight]; - SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, activateButton); - - UIActivityIndicatorView *spinnerView = - [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - self.spinnerView = spinnerView; - [activateButton addSubview:spinnerView]; - [spinnerView autoVCenterInSuperview]; - [spinnerView autoSetDimension:ALDimensionWidth toSize:20.f]; - [spinnerView autoSetDimension:ALDimensionHeight toSize:20.f]; - [spinnerView autoPinTrailingToSuperviewMarginWithInset:20.f]; - [spinnerView stopAnimating]; - - NSString *bottomTermsLinkText = NSLocalizedString(@"REGISTRATION_LEGAL_TERMS_LINK", - @"one line label below submit button on registration screen, which links to an external webpage."); - UIButton *bottomLegalLinkButton = [UIButton new]; - bottomLegalLinkButton.titleLabel.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(13.f, 15.f)]; - [bottomLegalLinkButton setTitleColor:UIColor.ows_materialBlueColor forState:UIControlStateNormal]; - [bottomLegalLinkButton setTitle:bottomTermsLinkText forState:UIControlStateNormal]; - [contentView addSubview:bottomLegalLinkButton]; - [bottomLegalLinkButton addTarget:self - action:@selector(didTapLegalTerms:) - forControlEvents:UIControlEventTouchUpInside]; - - [bottomLegalLinkButton autoPinLeadingAndTrailingToSuperviewMargin]; - [bottomLegalLinkButton autoPinEdge:ALEdgeTop - toEdge:ALEdgeBottom - ofView:activateButton - withOffset:ScaleFromIPhone5To7Plus(8, 12)]; - [bottomLegalLinkButton setCompressionResistanceHigh]; - [bottomLegalLinkButton setContentHuggingHigh]; - - SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, bottomLegalLinkButton); -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - - [self.activateButton setEnabled:YES]; - [self.spinnerView stopAnimating]; - [self.phoneNumberTextField becomeFirstResponder]; - - if (self.tsAccountManager.isReregistering) { - // If re-registering, pre-populate the country (country code, calling code, country name) - // and phone number state. - NSString *_Nullable phoneNumberE164 = self.tsAccountManager.reregisterationPhoneNumber; - if (!phoneNumberE164) { - OWSFailDebug(@"Could not resume re-registration; missing phone number."); - } else if ([self tryToApplyPhoneNumberE164:phoneNumberE164]) { - // Don't let user edit their phone number while re-registering. - self.phoneNumberTextField.enabled = NO; - } - } -} - -- (BOOL)tryToApplyPhoneNumberE164:(NSString *)phoneNumberE164 -{ - OWSAssertDebug(phoneNumberE164); - - if (phoneNumberE164.length < 1) { - OWSFailDebug(@"Could not resume re-registration; invalid phoneNumberE164."); - return NO; - } - PhoneNumber *_Nullable parsedPhoneNumber = [PhoneNumber phoneNumberFromE164:phoneNumberE164]; - if (!parsedPhoneNumber) { - OWSFailDebug(@"Could not resume re-registration; couldn't parse phoneNumberE164."); - return NO; - } - NSNumber *_Nullable callingCode = parsedPhoneNumber.getCountryCode; - if (!callingCode) { - OWSFailDebug(@"Could not resume re-registration; missing callingCode."); - return NO; - } - NSString *callingCodeText = [NSString stringWithFormat:@"+%d", callingCode.intValue]; - NSArray *_Nullable countryCodes = - [PhoneNumberUtil.sharedThreadLocal countryCodesFromCallingCode:callingCodeText]; - if (countryCodes.count < 1) { - OWSFailDebug(@"Could not resume re-registration; unknown countryCode."); - return NO; - } - NSString *countryCode = countryCodes.firstObject; - NSString *_Nullable countryName = [PhoneNumberUtil countryNameFromCountryCode:countryCode]; - if (!countryName) { - OWSFailDebug(@"Could not resume re-registration; unknown countryName."); - return NO; - } - if (![phoneNumberE164 hasPrefix:callingCodeText]) { - OWSFailDebug(@"Could not resume re-registration; non-matching calling code."); - return NO; - } - NSString *phoneNumberWithoutCallingCode = [phoneNumberE164 substringFromIndex:callingCodeText.length]; - - [self updateCountryWithName:countryName callingCode:callingCodeText countryCode:countryCode]; - self.phoneNumberTextField.text = phoneNumberWithoutCallingCode; - - return YES; -} - -#pragma mark - Country - -- (void)populateDefaultCountryNameAndCode -{ - NSString *countryCode = [PhoneNumber defaultCountryCode]; - -#ifdef DEBUG - if ([self lastRegisteredCountryCode].length > 0) { - countryCode = [self lastRegisteredCountryCode]; - } - self.phoneNumberTextField.text = [self lastRegisteredPhoneNumber]; -#endif - - NSNumber *callingCode = [[PhoneNumberUtil sharedThreadLocal].nbPhoneNumberUtil getCountryCodeForRegion:countryCode]; - NSString *countryName = [PhoneNumberUtil countryNameFromCountryCode:countryCode]; - [self updateCountryWithName:countryName - callingCode:[NSString stringWithFormat:@"%@%@", COUNTRY_CODE_PREFIX, callingCode] - countryCode:countryCode]; -} - -- (void)updateCountryWithName:(NSString *)countryName - callingCode:(NSString *)callingCode - countryCode:(NSString *)countryCode -{ - OWSAssertIsOnMainThread(); - OWSAssertDebug(countryName.length > 0); - OWSAssertDebug(callingCode.length > 0); - OWSAssertDebug(countryCode.length > 0); - - _countryCode = countryCode; - _callingCode = callingCode; - - NSString *title = [NSString stringWithFormat:@"%@ (%@)", callingCode, countryCode.localizedUppercaseString]; - self.countryCodeLabel.text = title; - [self.countryCodeLabel setNeedsLayout]; - - self.examplePhoneNumberLabel.text = - [ViewControllerUtils examplePhoneNumberForCountryCode:countryCode callingCode:callingCode]; - [self.examplePhoneNumberLabel setNeedsLayout]; -} - -#pragma mark - Actions - -- (void)didTapRegisterButton -{ - NSString *phoneNumberText = [_phoneNumberTextField.text ows_stripped]; - if (phoneNumberText.length < 1) { - [OWSAlerts - showAlertWithTitle:NSLocalizedString(@"REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE", - @"Title of alert indicating that users needs to enter a phone number to register.") - message: - NSLocalizedString(@"REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_MESSAGE", - @"Message of alert indicating that users needs to enter a phone number to register.")]; - return; - } - - NSString *countryCode = self.countryCode; - NSString *phoneNumber = [NSString stringWithFormat:@"%@%@", _callingCode, phoneNumberText]; - PhoneNumber *localNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber]; - NSString *parsedPhoneNumber = localNumber.toE164; - if (parsedPhoneNumber.length < 1 - || ![[PhoneNumberValidator new] isValidForRegistrationWithPhoneNumber:localNumber]) { - [OWSAlerts showAlertWithTitle: - NSLocalizedString(@"REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_TITLE", - @"Title of alert indicating that users needs to enter a valid phone number to register.") - message:NSLocalizedString(@"REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_MESSAGE", - @"Message of alert indicating that users needs to enter a valid phone number " - @"to register.")]; - return; - } - - if (UIDevice.currentDevice.isIPad) { - [OWSAlerts showConfirmationAlertWithTitle:NSLocalizedString(@"REGISTRATION_IPAD_CONFIRM_TITLE", - @"alert title when registering an iPad") - message:NSLocalizedString(@"REGISTRATION_IPAD_CONFIRM_BODY", - @"alert body when registering an iPad") - proceedTitle:NSLocalizedString(@"REGISTRATION_IPAD_CONFIRM_BUTTON", - @"button text to proceed with registration when on an iPad") - proceedAction:^(UIAlertAction *_Nonnull action) { - [self sendCodeActionWithParsedPhoneNumber:parsedPhoneNumber - phoneNumberText:phoneNumberText - countryCode:countryCode]; - }]; - } else { - [self sendCodeActionWithParsedPhoneNumber:parsedPhoneNumber - phoneNumberText:phoneNumberText - countryCode:countryCode]; - } -} - -- (void)sendCodeActionWithParsedPhoneNumber:(NSString *)parsedPhoneNumber - phoneNumberText:(NSString *)phoneNumberText - countryCode:(NSString *)countryCode -{ - [self.activateButton setEnabled:NO]; - [self.spinnerView startAnimating]; - [self.phoneNumberTextField resignFirstResponder]; - - __weak RegistrationViewController *weakSelf = self; - [self.tsAccountManager registerWithPhoneNumber:parsedPhoneNumber - captchaToken:nil - success:^{ - OWSProdInfo([OWSAnalyticsEvents registrationRegisteredPhoneNumber]); - - [weakSelf.spinnerView stopAnimating]; - - CodeVerificationViewController *vc = [CodeVerificationViewController new]; - [weakSelf.navigationController pushViewController:vc animated:YES]; - -#ifdef DEBUG - [weakSelf setLastRegisteredCountryCode:countryCode]; - [weakSelf setLastRegisteredPhoneNumber:phoneNumberText]; -#endif - } - failure:^(NSError *error) { - if (error.code == 400) { - [OWSAlerts showAlertWithTitle:NSLocalizedString(@"REGISTRATION_ERROR", nil) - message:NSLocalizedString(@"REGISTRATION_NON_VALID_NUMBER", nil)]; - } else { - [OWSAlerts showAlertWithTitle:error.localizedDescription message:error.localizedRecoverySuggestion]; - } - - [weakSelf.activateButton setEnabled:YES]; - [weakSelf.spinnerView stopAnimating]; - [weakSelf.phoneNumberTextField becomeFirstResponder]; - } - smsVerification:YES]; -} - -- (void)countryCodeRowWasTapped:(UIGestureRecognizer *)sender -{ - if (self.tsAccountManager.isReregistering) { - // Don't let user edit their phone number while re-registering. - return; - } - - if (sender.state == UIGestureRecognizerStateRecognized) { - [self changeCountryCodeTapped]; - } -} - -- (void)didTapLegalTerms:(UIButton *)sender -{ - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:kLegalTermsUrlString]]; -} - -- (void)changeCountryCodeTapped -{ - CountryCodeViewController *countryCodeController = [CountryCodeViewController new]; - countryCodeController.countryCodeDelegate = self; - countryCodeController.interfaceOrientationMask = UIInterfaceOrientationMaskPortrait; - OWSNavigationController *navigationController = - [[OWSNavigationController alloc] initWithRootViewController:countryCodeController]; - [self presentViewController:navigationController animated:YES completion:nil]; -} - -- (void)backgroundTapped:(UIGestureRecognizer *)sender -{ - if (sender.state == UIGestureRecognizerStateRecognized) { - [self.phoneNumberTextField becomeFirstResponder]; - } -} - -#pragma mark - CountryCodeViewControllerDelegate - -- (void)countryCodeViewController:(CountryCodeViewController *)vc - didSelectCountryCode:(NSString *)countryCode - countryName:(NSString *)countryName - callingCode:(NSString *)callingCode -{ - OWSAssertDebug(countryCode.length > 0); - OWSAssertDebug(countryName.length > 0); - OWSAssertDebug(callingCode.length > 0); - - [self updateCountryWithName:countryName callingCode:callingCode countryCode:countryCode]; - - // Trigger the formatting logic with a no-op edit. - [self textField:self.phoneNumberTextField shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""]; -} - -#pragma mark - Keyboard notifications - -- (void)initializeKeyboardHandlers -{ - UITapGestureRecognizer *outsideTabRecognizer = - [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboardFromAppropriateSubView)]; - [self.view addGestureRecognizer:outsideTabRecognizer]; -} - -- (void)dismissKeyboardFromAppropriateSubView -{ - [self.view endEditing:NO]; -} - -#pragma mark - UITextFieldDelegate - -- (BOOL)textField:(UITextField *)textField - shouldChangeCharactersInRange:(NSRange)range - replacementString:(NSString *)insertionText -{ - - [ViewControllerUtils phoneNumberTextField:textField - shouldChangeCharactersInRange:range - replacementString:insertionText - callingCode:_callingCode]; - - return NO; // inform our caller that we took care of performing the change -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField -{ - [self didTapRegisterButton]; - [textField resignFirstResponder]; - return NO; -} - -#pragma mark - Debug - -#ifdef DEBUG - -- (NSString *_Nullable)debugValueForKey:(NSString *)key -{ - OWSCAssertDebug([NSThread isMainThread]); - OWSCAssertDebug(key.length > 0); - - NSError *error; - NSString *_Nullable value = - [CurrentAppContext().keychainStorage stringForService:kKeychainService_LastRegistered key:key error:&error]; - if (error || !value) { - OWSLogWarn(@"Could not retrieve 'last registered' value from keychain: %@.", error); - return nil; - } - return value; -} - -- (void)setDebugValue:(NSString *)value forKey:(NSString *)key -{ - OWSCAssertDebug([NSThread isMainThread]); - OWSCAssertDebug(key.length > 0); - OWSCAssertDebug(value.length > 0); - - NSError *error; - BOOL success = [CurrentAppContext().keychainStorage setString:value - service:kKeychainService_LastRegistered - key:key - error:&error]; - if (!success || error) { - OWSLogError(@"Error persisting 'last registered' value in keychain: %@", error); - } -} - -- (NSString *_Nullable)lastRegisteredCountryCode -{ - return [self debugValueForKey:kKeychainKey_LastRegisteredCountryCode]; -} - -- (void)setLastRegisteredCountryCode:(NSString *)value -{ - [self setDebugValue:value forKey:kKeychainKey_LastRegisteredCountryCode]; -} - -- (NSString *_Nullable)lastRegisteredPhoneNumber -{ - return [self debugValueForKey:kKeychainKey_LastRegisteredPhoneNumber]; -} - -- (void)setLastRegisteredPhoneNumber:(NSString *)value -{ - [self setDebugValue:value forKey:kKeychainKey_LastRegisteredPhoneNumber]; -} - -#endif - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return UIStatusBarStyleLightContent; -} - -#pragma mark - Orientation - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - return UIInterfaceOrientationMaskPortrait; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Signal/src/util/AppUpdateNag.swift b/Signal/src/util/AppUpdateNag.swift index f183b283d..4f5c9e47f 100644 --- a/Signal/src/util/AppUpdateNag.swift +++ b/Signal/src/util/AppUpdateNag.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -115,7 +115,7 @@ class AppUpdateNag: NSObject { } switch frontmostViewController { - case is HomeViewController, is RegistrationViewController: + case is HomeViewController, is OnboardingSplashViewController: self.setLastNagDate(Date()) self.clearFirstHeardOfNewVersionDate() presentUpgradeNag(appStoreRecord: appStoreRecord) diff --git a/Signal/src/util/RegistrationUtils.m b/Signal/src/util/RegistrationUtils.m index 9a245cff5..bc1b479ed 100644 --- a/Signal/src/util/RegistrationUtils.m +++ b/Signal/src/util/RegistrationUtils.m @@ -3,8 +3,8 @@ // #import "RegistrationUtils.h" -#import "CodeVerificationViewController.h" #import "OWSNavigationController.h" +#import "Signal-Swift.h" #import #import #import @@ -59,16 +59,23 @@ NS_ASSUME_NONNULL_BEGIN presentFromViewController:fromViewController canCancel:NO backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { - [self.tsAccountManager registerWithPhoneNumber:self.tsAccountManager.reregisterationPhoneNumber + NSString *phoneNumber = self.tsAccountManager.reregisterationPhoneNumber; + [self.tsAccountManager registerWithPhoneNumber:phoneNumber captchaToken:nil success:^{ OWSLogInfo(@"re-registering: send verification code succeeded."); dispatch_async(dispatch_get_main_queue(), ^{ [modalActivityIndicator dismissWithCompletion:^{ - CodeVerificationViewController *viewController = - [CodeVerificationViewController new]; - + OnboardingController *onboardingController = [OnboardingController new]; + OnboardingPhoneNumber *onboardingPhoneNumber = + [[OnboardingPhoneNumber alloc] initWithE164:phoneNumber + userInput:phoneNumber]; + [onboardingController updateWithPhoneNumber:onboardingPhoneNumber]; + OnboardingVerificationViewController *viewController = + [[OnboardingVerificationViewController alloc] + initWithOnboardingController:onboardingController]; + [viewController hideBackLink]; OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:viewController]; navigationController.navigationBarHidden = YES; diff --git a/SignalMessaging/ViewControllers/SelectRecipientViewController.m b/SignalMessaging/ViewControllers/SelectRecipientViewController.m index 006bd0c9c..4319895d8 100644 --- a/SignalMessaging/ViewControllers/SelectRecipientViewController.m +++ b/SignalMessaging/ViewControllers/SelectRecipientViewController.m @@ -414,8 +414,6 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien #pragma mark - UITextFieldDelegate -// TODO: This logic resides in both RegistrationViewController and here. -// We should refactor it out into a utility function. - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)insertionText