diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 1b04183ffe8e..1074eb461074 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -9,6 +9,7 @@ * [*] [internal] Editor: Only register core blocks when `onlyCoreBlocks` capability is enabled [https://github.com/wordpress-mobile/gutenberg-mobile/pull/5293] * [**] [internal] Disable StockPhoto and Tenor media sources when Jetpack features are removed [#19826] * [*] [Jetpack-only] Fixed a bug where analytics calls weren't synced to the user account. [#19926] +* [*] [Jetpack-only] Fixed a bug where the Login flow was restarting every time the app enters the foreground. [#19961] 21.4 ----- diff --git a/WordPress/Classes/System/WindowManager.swift b/WordPress/Classes/System/WindowManager.swift index 32611f2c51f0..721919743e9d 100644 --- a/WordPress/Classes/System/WindowManager.swift +++ b/WordPress/Classes/System/WindowManager.swift @@ -21,6 +21,12 @@ class WindowManager: NSObject { /// private(set) var isShowingFullscreenSignIn = false + /// The root view controller for the window. + /// + var rootViewController: UIViewController? { + return window.rootViewController + } + init(window: UIWindow) { self.window = window } diff --git a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift index 5cd83b9ce774..373218cf54b9 100644 --- a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift +++ b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift @@ -139,11 +139,41 @@ private extension JetpackWindowManager { !hasFailedExportAttempts, let schemeUrl = URL(string: "\(AppScheme.wordpressMigrationV1.rawValue)\(WordPressExportRoute().path.removingPrefix("/"))") else { - showSignInUI() + performSafeRootNavigation { [weak self] in + self?.showSignInUI() + } return } /// WordPress is a compatible version for migrations, but needs to be loaded to prepare the data - showLoadWordPressUI(schemeUrl: schemeUrl) + performSafeRootNavigation { [weak self] in + self?.showLoadWordPressUI(schemeUrl: schemeUrl) + } + } + + /// This method takes care of preventing screens being abruptly replaced. + /// + /// Since the import method is called whenever the app is foregrounded, we want to make sure that + /// any root view controller replacements only happen where it is "allowed": + /// + /// 1. When there's no root view controller yet, or + /// 2. When the Load WordPress screen is shown. + /// + /// Note: We should remove this method when the migration phase is concluded and we no longer need + /// to perfom the migration. + /// + /// - Parameter navigationClosure: The closure containing logic that eventually calls the `show` method. + func performSafeRootNavigation(with navigationClosure: @escaping () -> Void) { + switch rootViewController { + case .none: + // we can perform the navigation directly when there's no root view controller yet. + navigationClosure() + case .some(let viewController) where viewController is MigrationLoadWordPressViewController: + // allow the Load WordPress view to be replaced in case the migration process fails. + viewController.dismiss(animated: true, completion: navigationClosure) + default: + // do nothing when another root view controller is already displayed. + break + } } }