Allow switching to secondary device linking from new registration and vice versa

* add copy pasted RegistrationConfirmModeSwitchViewController

* enable switching registration and secondary device linking back and forth
This commit is contained in:
Harry 2023-03-24 13:51:05 -07:00 committed by GitHub
parent 4b3c75385d
commit b6e781fa24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 180 additions and 25 deletions

View File

@ -836,6 +836,7 @@
66586D3829005A1B00DDA9B9 /* story_viewer_onboarding_1.json in Resources */ = {isa = PBXBuildFile; fileRef = 66586D3529005A1B00DDA9B9 /* story_viewer_onboarding_1.json */; };
66586D3929005A1B00DDA9B9 /* story_viewer_onboarding_3.json in Resources */ = {isa = PBXBuildFile; fileRef = 66586D3629005A1B00DDA9B9 /* story_viewer_onboarding_3.json */; };
66586D4129009C0000DDA9B9 /* TextAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66586D4029009C0000DDA9B9 /* TextAttachment.swift */; };
6659CCB129CD4650000C24C0 /* RegistrationConfirmModeSwitchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6659CCB029CD4650000C24C0 /* RegistrationConfirmModeSwitchViewController.swift */; };
665EF86D290C385B00F490D2 /* OWSNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 665EF86C290C385B00F490D2 /* OWSNavigationController.swift */; };
6673FF702978C40300F96CFD /* KBSAuthCredentialStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6673FF6F2978C40300F96CFD /* KBSAuthCredentialStorage.swift */; };
6673FF722979B33800F96CFD /* KBSAuthCredentialStorageImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6673FF712979B33800F96CFD /* KBSAuthCredentialStorageImpl.swift */; };
@ -3302,6 +3303,7 @@
66586D3529005A1B00DDA9B9 /* story_viewer_onboarding_1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = story_viewer_onboarding_1.json; sourceTree = "<group>"; };
66586D3629005A1B00DDA9B9 /* story_viewer_onboarding_3.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = story_viewer_onboarding_3.json; sourceTree = "<group>"; };
66586D4029009C0000DDA9B9 /* TextAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextAttachment.swift; sourceTree = "<group>"; };
6659CCB029CD4650000C24C0 /* RegistrationConfirmModeSwitchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationConfirmModeSwitchViewController.swift; sourceTree = "<group>"; };
665EF86C290C385B00F490D2 /* OWSNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSNavigationController.swift; sourceTree = "<group>"; };
6673FF6F2978C40300F96CFD /* KBSAuthCredentialStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KBSAuthCredentialStorage.swift; sourceTree = "<group>"; };
6673FF712979B33800F96CFD /* KBSAuthCredentialStorageImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KBSAuthCredentialStorageImpl.swift; sourceTree = "<group>"; };
@ -5037,6 +5039,7 @@
66AAC2C329CB6F1100566AD6 /* RegistrationChangeNumberSplashViewController.swift */,
66AAC2C729CB9ED900566AD6 /* RegistrationChangePhoneNumberConfirmationViewController.swift */,
66AAC2C529CB942F00566AD6 /* RegistrationChangePhoneNumberViewController.swift */,
6659CCB029CD4650000C24C0 /* RegistrationConfirmModeSwitchViewController.swift */,
F92E4C73299E9A0100C6E6C7 /* RegistrationLoadingViewController.swift */,
F9D5C39E2993F9FF004891FC /* RegistrationPermissionsViewController.swift */,
F905DFEA29A534F200BAD034 /* RegistrationPhoneNumberDiscoverabilityViewController.swift */,
@ -11387,6 +11390,7 @@
66AAC2C429CB6F1100566AD6 /* RegistrationChangeNumberSplashViewController.swift in Sources */,
66AAC2C829CB9ED900566AD6 /* RegistrationChangePhoneNumberConfirmationViewController.swift in Sources */,
66AAC2C629CB942F00566AD6 /* RegistrationChangePhoneNumberViewController.swift in Sources */,
6659CCB129CD4650000C24C0 /* RegistrationConfirmModeSwitchViewController.swift in Sources */,
6600F39629919ECC00B1EDB7 /* RegistrationCoodinatorShims.swift in Sources */,
66E3C8F62994634E00BB38ED /* RegistrationCoordinator.swift in Sources */,
66F0F1DF29C12363008C0ECE /* RegistrationCoordinatorDependencies.swift in Sources */,

View File

@ -9,6 +9,12 @@ import Foundation
/// including re-registration and change number.
public protocol RegistrationCoordinator {
/// Prepare to switch to secondary device linking, if allowed.
/// If this returns true, state will have been appropriately cleared
/// in order to proceed to seconday device linking; if not the
/// user/device is not allowed and should stay in primary registration.
func switchToSecondaryDeviceLinking() -> Bool
/// Attempt to exit registration, returning true if allowed.
///
/// When allowed differs by `RegistrationMode`:

View File

@ -33,6 +33,21 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// MARK: - Public API
public func switchToSecondaryDeviceLinking() -> Bool {
switch mode {
case .registering:
if persistedState.hasShownSplash {
// Once we are past the splash, no going back.
return false
} else {
self.wipePersistedState()
return true
}
case .reRegistering, .changingNumber:
return false
}
}
public func exitRegistration() -> Bool {
guard canExitRegistrationFlow() else {
return false

View File

@ -326,6 +326,22 @@ extension RegistrationNavigationController: RegistrationSplashPresenter {
public func continueFromSplash() {
pushNextController(coordinator.continueFromSplash())
}
public func switchToDeviceLinkingMode() {
let controller = RegistrationConfirmModeSwitchViewController(presenter: self)
pushViewController(controller, animated: true, completion: nil)
}
}
extension RegistrationNavigationController: RegistrationConfimModeSwitchPresenter {
public func confirmSwitchToDeviceLinkingMode() {
guard coordinator.switchToSecondaryDeviceLinking() else {
owsFailBeta("Can't switch to secondary device linking")
return
}
SignalApp.shared().showDeprecatedOnboardingView(.init(context: .shared, onboardingMode: .provisioning))
}
}
extension RegistrationNavigationController: RegistrationChangeNumberSplashPresenter {}

View File

@ -33,6 +33,8 @@ public class Deprecated_OnboardingNavigationController: OWSNavigationController
// MARK: -
// TODO[Registration]: pull out the parts of this related to secondary device
// linking into simpler classes and delete the rest once once new registration rolls out.
@objc
public class Deprecated_OnboardingController: NSObject {
@ -218,6 +220,12 @@ public class Deprecated_OnboardingController: NSObject {
Logger.info("")
if FeatureFlags.useNewRegistrationFlow, onboardingMode == .provisioning {
let loader = RegistrationCoordinatorLoaderImpl(dependencies: .from(self))
signalApp.showRegistration(loader: loader, desiredMode: .registering)
return
}
switch Self.defaultOnboardingMode {
case .registering:
onboardingMode = .provisioning

View File

@ -21,7 +21,7 @@ class Deprecated_OnboardingModeSwitchConfirmationViewController: Deprecated_Onbo
let nextButtonText: String
let image: UIImage?
switch Deprecated_OnboardingController.defaultOnboardingMode {
switch onboardingController.onboardingMode {
case .registering:
titleText = NSLocalizedString("ONBOARDING_MODE_SWITCH_TITLE_REGISTERING",
comment: "header text indicating to the user they're switching from registering to linking flow")

View File

@ -94,10 +94,16 @@ public class Deprecated_OnboardingSplashViewController: Deprecated_OnboardingBas
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Whenever this view appears, we should switch back to the default
// registration mode. If the user wants to use the other one, they need to
// tap the link icon and confirm their selection.
onboardingController.onboardingMode = Deprecated_OnboardingController.defaultOnboardingMode
if !FeatureFlags.useNewRegistrationFlow {
// Whenever this view appears, we should switch back to the default
// registration mode. If the user wants to use the other one, they need to
// tap the link icon and confirm their selection.
onboardingController.onboardingMode = Deprecated_OnboardingController.defaultOnboardingMode
}
}
override func shouldShowBackButton() -> Bool {
return false
}
// MARK: - Events

View File

@ -0,0 +1,90 @@
//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import SignalMessaging
import SignalUI
protocol RegistrationConfimModeSwitchPresenter: AnyObject {
func confirmSwitchToDeviceLinkingMode()
}
class RegistrationConfirmModeSwitchViewController: OWSViewController {
var warningText: String?
weak var presenter: RegistrationConfimModeSwitchPresenter?
public init(presenter: RegistrationConfimModeSwitchPresenter) {
self.presenter = presenter
super.init()
}
override func loadView() {
view = UIView()
view.backgroundColor = Theme.backgroundColor
let titleText = NSLocalizedString("ONBOARDING_MODE_SWITCH_TITLE_REGISTERING",
comment: "header text indicating to the user they're switching from registering to linking flow")
let explanationText = NSLocalizedString("ONBOARDING_MODE_SWITCH_EXPLANATION_REGISTERING",
comment: "explanation to the user they're switching from registering to linking flow")
let nextButtonText = NSLocalizedString("ONBOARDING_MODE_SWITCH_BUTTON_REGISTERING",
comment: "button indicating that the user will link their phone")
warningText = NSLocalizedString("ONBOARDING_MODE_SWITCH_WARNING_REGISTERING",
comment: "warning to the user that linking a phone is not recommended")
let titleLabel = UILabel.titleLabelForRegistration(text: titleText)
let explanationLabel = UILabel.explanationLabelForRegistration(text: explanationText)
let nextButton = OWSFlatButton.primaryButtonForRegistration(
title: nextButtonText,
target: self,
selector: #selector(didPressNext)
)
nextButton.accessibilityIdentifier = "onboarding.modeSwitch.nextButton"
let primaryButtonView = Deprecated_OnboardingBaseViewController.horizontallyWrap(primaryButton: nextButton)
let topSpacer = UIView.vStretchingSpacer(minHeight: 12)
let bottomSpacer = UIView.vStretchingSpacer(minHeight: 12)
let stackView = UIStackView(arrangedSubviews: [
titleLabel,
UIView.spacer(withHeight: 12),
explanationLabel,
topSpacer,
bottomSpacer,
primaryButtonView
])
stackView.axis = .vertical
stackView.alignment = .fill
stackView.spacing = 12
view.addSubview(stackView)
topSpacer.autoMatch(.height, to: .height, of: bottomSpacer)
stackView.autoPinEdgesToSuperviewMargins()
}
@objc
func didPressNext() {
let actionSheet = ActionSheetController(message: warningText)
let continueAction = ActionSheetAction(
title: CommonStrings.continueButton,
accessibilityIdentifier: "onboarding.modeSwitch.continue",
handler: { [weak self] _ in
self?.presenter?.confirmSwitchToDeviceLinkingMode()
}
)
actionSheet.addAction(continueAction)
actionSheet.addAction(OWSActionSheets.cancelAction)
presentActionSheet(actionSheet)
}
}

View File

@ -50,7 +50,9 @@ class RegistrationLoadingViewController: OWSViewController {
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
spinnerView.startAnimating()
if spinnerView.isAnimating.negated {
spinnerView.startAnimating()
}
}
public override func themeDidChange() {

View File

@ -12,6 +12,8 @@ import SignalMessaging
public protocol RegistrationSplashPresenter: AnyObject {
func continueFromSplash()
func switchToDeviceLinkingMode()
}
// MARK: - RegistrationSplashViewController
@ -126,7 +128,8 @@ public class RegistrationSplashViewController: OWSViewController {
@objc
private func didTapModeSwitch() {
Logger.info("")
owsFail("TODO[Registration] Not implemented")
presenter?.switchToDeviceLinkingMode()
}
@objc

View File

@ -59,25 +59,20 @@ extension SignalApp {
let onboardingController = Deprecated_OnboardingController()
if FeatureFlags.useNewRegistrationFlow {
var desiredMode: RegistrationMode? = DependenciesBridge.shared.db.read {
if let lastMode = DependenciesBridge.shared.db.read(block: {
return registrationLoader.restoreLastMode(transaction: $0)
}
if desiredMode == nil {
// Check for legacy state.
// TODO[Registration]: use a db migration to move this state to reg coordinator.
if !onboardingController.isComplete {
desiredMode = .registering
}) {
showRegistration(loader: registrationLoader, desiredMode: lastMode)
AppReadiness.setUIIsReady()
// TODO[Registration]: use a db migration to move isComplete state to reg coordinator.
} else if !onboardingController.isComplete {
if UIDevice.current.isIPad {
showDeprecatedOnboardingView(onboardingController)
AppReadiness.setUIIsReady()
} else {
showRegistration(loader: registrationLoader, desiredMode: .registering)
AppReadiness.setUIIsReady()
}
}
if let desiredMode {
let coordinator = databaseStorage.write { tx in
return registrationLoader.coordinator(forDesiredMode: desiredMode, transaction: tx.asV2Write)
}
let navController = RegistrationNavigationController.withCoordinator(coordinator)
appDelegate.window??.rootViewController = navController
conversationSplitViewController = nil
} else {
onboardingController.markAsOnboarded()
showConversationSplitView()
@ -88,7 +83,6 @@ extension SignalApp {
showConversationSplitView()
} else {
showDeprecatedOnboardingView(onboardingController)
AppReadiness.setUIIsReady()
}
}
@ -104,6 +98,17 @@ extension SignalApp {
}
conversationSplitViewController.showAppSettingsWithMode(mode)
}
func showRegistration(loader: RegistrationCoordinatorLoader, desiredMode: RegistrationMode) {
let coordinator = databaseStorage.write { tx in
return loader.coordinator(forDesiredMode: desiredMode, transaction: tx.asV2Write)
}
let navController = RegistrationNavigationController.withCoordinator(coordinator)
UIApplication.shared.delegate?.window??.rootViewController = navController
conversationSplitViewController = nil
}
}
extension SignalApp {