From 9d3a0dfd992f7adc02daaa148476f15a51aeab59 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:01:53 -0600 Subject: [PATCH 01/35] Add MigrationDpendencyContainer, dependency injection container for wp-to-jp migration --- .../Common/MigrationDependencyContainer.swift | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift new file mode 100644 index 000000000000..43fb00f72575 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift @@ -0,0 +1,47 @@ +class MigrationDependencyContainer { + + let migrationCoordinator = MigrationFlowCoordinator() + + func makeInitialViewController() -> UIViewController { + MigrationNavigationController(coordinator: migrationCoordinator, + migrationStack: [.welcome: makeWelcomeViewController(), + .notifications: makeNotificationsViewController(), + .done: makeDoneViewController()]) + } + + private func makeAccount() -> WPAccount? { + + let context = ContextManager.shared.mainContext + do { + return try WPAccount.lookupDefaultWordPressComAccount(in: context) + } catch { + DDLogError("Account lookup failed with error: \(error)") + return nil + } + } + + // MARK: view controller factory + private func makeWelcomeViewModel() -> MigrationWelcomeViewModel { + MigrationWelcomeViewModel(account: makeAccount(), coordinator: migrationCoordinator) + } + + private func makeWelcomeViewController() -> UIViewController { + MigrationWelcomeViewController(viewModel: makeWelcomeViewModel()) + } + + private func makeNotificationsViewModel() -> MigrationNotificationsViewModel { + MigrationNotificationsViewModel(coordinator: migrationCoordinator) + } + + private func makeNotificationsViewController() -> UIViewController { + MigrationNotificationsViewController(viewModel: makeNotificationsViewModel()) + } + + private func makeDoneViewModel() -> MigrationDoneViewModel { + MigrationDoneViewModel(coordinator: migrationCoordinator) + } + + private func makeDoneViewController() -> UIViewController { + MigrationDoneViewController(viewModel: makeDoneViewModel()) + } +} From 14ebd9d3a478961d19f13685818e1ea7129ba6e1 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:03:22 -0600 Subject: [PATCH 02/35] Add MigrationNavigationController, custom, state-based navigation controller for wp-to-jp migration --- .../MigrationNavigationController.swift | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift new file mode 100644 index 000000000000..7d251d9a7af3 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift @@ -0,0 +1,55 @@ +import Combine +import UIKit + +class MigrationNavigationController: UINavigationController { + + private let coordinator: MigrationFlowCoordinator + /// The full navigation stack: keys are the states in which the corresponding view + /// controller should be the root + private let migrationStack: [MigrationStep: UIViewController] + /// Receives state changes to set the navigation stack accordingly + private var cancellable: AnyCancellable? + + init(coordinator: MigrationFlowCoordinator, migrationStack: [MigrationStep: UIViewController]) { + self.coordinator = coordinator + self.migrationStack = migrationStack + super.init(nibName: nil, bundle: nil) + configure() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func configure() { + let navigationBar = self.navigationBar + let standardAppearance = UINavigationBarAppearance() + standardAppearance.configureWithDefaultBackground() + let scrollEdgeAppearance = UINavigationBarAppearance() + scrollEdgeAppearance.configureWithTransparentBackground() + navigationBar.standardAppearance = standardAppearance + navigationBar.scrollEdgeAppearance = scrollEdgeAppearance + navigationBar.compactAppearance = standardAppearance + if #available(iOS 15.0, *) { + navigationBar.compactScrollEdgeAppearance = scrollEdgeAppearance + } + navigationBar.isTranslucent = true + listenForStateChanges() + } + + private func listenForStateChanges() { + cancellable = coordinator.$currentStep.sink { [weak self] step in + self?.updateStack(for: step) + } + } + + private func updateStack(for step: MigrationStep) { + // sets the stack for the next navigation step, if there's one + guard let viewController = migrationStack[step] else { + return + } + // if we want to support backwards navigation, we need to set + // also the previous steps in the stack + setViewControllers([viewController], animated: true) + } +} From 48a4c653a4c6a6f8ae928ee9d109dfe022b0d82c Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:04:43 -0600 Subject: [PATCH 03/35] Update MigrationFlowCoordinator, extract ui logic from coordinator --- .../Navigation/MigrationFlowCoordinator.swift | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift new file mode 100644 index 000000000000..06cc6b88a175 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift @@ -0,0 +1,26 @@ +import Combine + +/// Coordinator for the migration to jetpack flow +final class MigrationFlowCoordinator: ObservableObject { + + @Published private(set) var currentStep = MigrationStep.welcome + + func transitionToNextStep() { + if let nextStep = Self.nextStep(from: currentStep) { + self.currentStep = nextStep + } + } + + private static func nextStep(from step: MigrationStep) -> MigrationStep? { + switch step { + case .welcome: + return .notifications + case .notifications: + return .done + case .done: + return .dismiss + case .dismiss: + return nil + } + } +} From 30a79ab5630cd86db5bb77f5dd43f1fa3dee29b4 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:05:45 -0600 Subject: [PATCH 04/35] Add MigrationStepConfiguration, a refactor of existing configuration types --- .../MigrationStepConfiguration.swift | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift new file mode 100644 index 000000000000..f6da0b65f226 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift @@ -0,0 +1,180 @@ + +struct MigrationStepConfiguration { + let headerConfiguration: MigrationHeaderConfiguration + let actionsConfiguration: MigrationActionsViewConfiguration +} + +struct MigrationHeaderConfiguration { + + let step: MigrationStep + let title: String? + let image: UIImage? + let primaryDescription: String? + let secondaryDescription: String? + + init(step: MigrationStep, multiSite: Bool = false) { + self.step = step + + image = Appearance.image(for: step) + title = Appearance.title(for: step) + primaryDescription = Appearance.primaryDescription(for: step) + secondaryDescription = Appearance.secondaryDescription(for: step, multiSite: multiSite) + } +} + +private extension MigrationHeaderConfiguration { + + enum Appearance { + // TODO: Set the right images for notification and done states + static func image(for step: MigrationStep) -> UIImage? { + switch step { + case .welcome: + return UIImage(named: "wp-migration-welcome") + case .notifications: + return UIImage(named: "wp-migration-welcome") + case .done: + return UIImage(named: "wp-migration-welcome") + case .dismiss: + return nil + } + } + + static func title(for step: MigrationStep) -> String? { + switch step { + case .welcome: + return welcomeTitle + case .notifications: + return notificationsTitle + case .done: + return doneTitle + case .dismiss: + return nil + } + } + + static func primaryDescription(for step: MigrationStep) -> String? { + switch step { + case .welcome: + return welcomePrimaryDescription + case .notifications: + return notificationsPrimaryDescription + case .done: + return donePrimaryDescription + case .dismiss: + return nil + } + } + + static func secondaryDescription(for step: MigrationStep, multiSite: Bool = false) -> String? { + switch step { + case .welcome: + return welcomeSecondaryDescription(plural: multiSite) + case .notifications: + return notificationsSecondaryDescription + case .done: + return nil + case .dismiss: + return nil + } + } + + static let welcomeTitle = NSLocalizedString("migration.welcome.title", + value: "Welcome to Jetpack!", + comment: "The title in the migration welcome screen") + + static let notificationsTitle = NSLocalizedString("migration.notifications.title", + value: "Allow notifications to keep up with your site", + comment: "Title of the migration notifications screen.") + + static let doneTitle = NSLocalizedString("migration.done.title", + value: "Thanks for switching to Jetpack!", + comment: "Title of the migration done screen.") + + static let welcomePrimaryDescription = NSLocalizedString("migration.welcome.primaryDescription", + value: "It looks like you’re switching from the WordPress app.", + comment: "The primary description in the migration welcome screen") + + static let notificationsPrimaryDescription = NSLocalizedString("migration.notifications.primaryDescription", + value: "You’ll get all the same notifications but now they’ll come from the Jetpack app.", + comment: "Primary description in the migration notifications screen.") + + static let donePrimaryDescription = NSLocalizedString("migration.done.primaryDescription", + value: "We’ve transferred all your data and settings. Everything is right where you left it.", + comment: "Primary description in the migration done screen.") + + static let notificationsSecondaryDescription = NSLocalizedString("migration.notifications.secondaryDescription", + value: "We’ve disabled notifications for the WordPress app.", + comment: "Secondary description in the migration notifications screen") + + static func welcomeSecondaryDescription(plural: Bool) -> String { + let siteWord = plural ? "sites" : "site" + let value = "We found your \(siteWord). Continue to transfer all your data and sign in to Jetpack automatically." + if plural { + let comment = "The plural form of the secondary description in the migration welcome screen" + return NSLocalizedString("migration.welcome.secondaryDescription.plural", value: value, comment: comment) + } else { + let comment = "The singular form of the secondary description in the migration welcome screen" + return NSLocalizedString("migration.welcome.secondaryDescription.singular", value: value, comment: comment) + } + } + } +} + +struct MigrationActionsViewConfiguration { + let step: MigrationStep + let primaryTitle: String? + let secondaryTitle: String? + let primaryHandler: (() -> Void)? + let secondaryHandler: (() -> Void)? + + init(step: MigrationStep, primaryHandler: (() -> Void)? = nil, secondaryHandler: (() -> Void)? = nil) { + self.step = step + self.primaryHandler = primaryHandler + self.secondaryHandler = secondaryHandler + self.primaryTitle = Appearance.primaryTitle(for: step) + self.secondaryTitle = Appearance.secondaryTitle(for: step) + } +} + +private extension MigrationActionsViewConfiguration { + + enum Appearance { + + static func primaryTitle(for step: MigrationStep) -> String? { + switch step { + case .welcome, .notifications: + return Appearance.defaultPrimaryTitle + case .done: + return Appearance.donePrimaryTitle + case.dismiss: + return nil + } + } + + static func secondaryTitle(for step: MigrationStep) -> String? { + switch step { + case .welcome: + return Appearance.welcomeSecondaryTitle + case .notifications: + return Appearance.notificationsSecondaryTitle + default: + return nil + } + } + + static let defaultPrimaryTitle = NSLocalizedString("Continue", + value: "Continue", + comment: "The primary button title in the migration welcome and notifications screens.") + + static let donePrimaryTitle = NSLocalizedString("migration.done.actions.primary.title", + value: "Finish", + comment: "Primary button title in the migration done screen.") + + static let welcomeSecondaryTitle = NSLocalizedString("Need help?", + comment: "The secondary button title in the migration welcome screen") + + static let notificationsSecondaryTitle = NSLocalizedString("migration.notifications.actions.secondary.title", + value: "Decide later", + comment: "Secondary button title in the migration notifications screen.") + } +} From e2cdb123f58ae2cb006fe18ba90ddae47ced0c28 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:07:16 -0600 Subject: [PATCH 05/35] Add MigrationStepView, a common base view for migration step screens --- .../Common/Views/MigrationStepView.swift | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift new file mode 100644 index 000000000000..ee2ce120fbbd --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift @@ -0,0 +1,37 @@ +import UIKit + +class MigrationStepView: UIView { + + private let headerView: MigrationHeaderView + private let centerView: UIView + private let actionsView: MigrationActionsView + + private lazy var mainStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [headerView, centerView, actionsView]) + stackView.axis = .vertical + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + init(headerView: MigrationHeaderView, + actionsView: MigrationActionsView, + centerView: UIView) { + + self.headerView = headerView + headerView.translatesAutoresizingMaskIntoConstraints = false + headerView.directionalLayoutMargins = Self.headerViewMargins + self.centerView = centerView + self.actionsView = actionsView + actionsView.translatesAutoresizingMaskIntoConstraints = false + super.init(frame: .zero) + backgroundColor = .systemBackground + addSubview(mainStackView) + pinSubviewToAllEdges(mainStackView) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + static let headerViewMargins = NSDirectionalEdgeInsets(top: 0, leading: 30, bottom: 30, trailing: 30) +} From 3b8216f7c81ec176e2d717f547f3f1299dfa43b4 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:09:07 -0600 Subject: [PATCH 06/35] Add MigrationNotificationsViewController, view controller for the wp-to-jp migration-notifications permissions step --- ...MigrationNotificationsViewController.swift | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift new file mode 100644 index 000000000000..6375b420e6f8 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift @@ -0,0 +1,24 @@ +import UIKit + +class MigrationNotificationsViewController: UIViewController { + + private let viewModel: MigrationNotificationsViewModel + + init(viewModel: MigrationNotificationsViewModel) { + self.viewModel = viewModel + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + let centerView = UIView() + centerView.translatesAutoresizingMaskIntoConstraints = false + centerView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .vertical) + view = MigrationStepView(headerView: MigrationHeaderView(configuration: viewModel.configuration.headerConfiguration), + actionsView: MigrationActionsView(configuration: viewModel.configuration.actionsConfiguration), + centerView: centerView) + } +} From 45e1c2ed58bab43a7cf543af539b49a33c4027f5 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:09:51 -0600 Subject: [PATCH 07/35] Add MigrationNotificationsViewModel, view model for the wp-to-jp migration-notifications permissions step --- .../MigrationNotificationsViewModel.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift new file mode 100644 index 000000000000..5d2af07da4b5 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift @@ -0,0 +1,15 @@ +import Foundation + +class MigrationNotificationsViewModel { + + let configuration: MigrationStepConfiguration + + init(coordinator: MigrationFlowCoordinator) { + self.configuration = MigrationStepConfiguration(headerConfiguration: MigrationHeaderConfiguration(step: .notifications), + actionsConfiguration: MigrationActionsViewConfiguration(step: .notifications, + primaryHandler: {}, + secondaryHandler: { [weak coordinator] in + coordinator?.transitionToNextStep() + })) + } +} From 8e7786afb14acc25c6bb7b6347f114652a7f8565 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:11:01 -0600 Subject: [PATCH 08/35] Add MigrationDoneViewController, view controller for the wp-to-jp migration-final step --- .../MigrationDoneViewController.swift | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift new file mode 100644 index 000000000000..8f239e2577e4 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift @@ -0,0 +1,25 @@ +import UIKit + +class MigrationDoneViewController: UIViewController { + + private let viewModel: MigrationDoneViewModel + + init(viewModel: MigrationDoneViewModel) { + self.viewModel = viewModel + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + let centerView = UIView() + centerView.translatesAutoresizingMaskIntoConstraints = false + centerView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .vertical) + + view = MigrationStepView(headerView: MigrationHeaderView(configuration: viewModel.configuration.headerConfiguration), + actionsView: MigrationActionsView(configuration: viewModel.configuration.actionsConfiguration), + centerView: centerView) + } +} From 81dfb1610fb87476741431d690fd1e77fe1628e7 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:11:38 -0600 Subject: [PATCH 09/35] Add MigrationDoneViewModel, view model for the wp-to-jp migration-final step --- .../All done/MigrationDoneViewModel.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift new file mode 100644 index 000000000000..3b01516ebc0e --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift @@ -0,0 +1,12 @@ +class MigrationDoneViewModel { + + let configuration: MigrationStepConfiguration + + init(coordinator: MigrationFlowCoordinator) { + + configuration = MigrationStepConfiguration(headerConfiguration: MigrationHeaderConfiguration(step: .done), + actionsConfiguration: MigrationActionsViewConfiguration(step: .done, primaryHandler: { [weak coordinator] in + coordinator?.transitionToNextStep() + })) + } +} From 58bffd028c3e0a96334a610776934512d2becc36 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:12:45 -0600 Subject: [PATCH 10/35] Update WindowManager, default optional completion to nil --- WordPress/Classes/System/WindowManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Classes/System/WindowManager.swift b/WordPress/Classes/System/WindowManager.swift index 3553b64bbe3d..e36bd6b5fc93 100644 --- a/WordPress/Classes/System/WindowManager.swift +++ b/WordPress/Classes/System/WindowManager.swift @@ -82,7 +82,7 @@ class WindowManager: NSObject { /// Shows the specified VC as the root VC for the managed window. Takes care of animating the transition whenever the existing /// root VC isn't `nil` (this is because a `nil` VC means we're showing the initial VC on a call to this method). /// - func show(_ viewController: UIViewController, completion: Completion?) { + func show(_ viewController: UIViewController, completion: Completion? = nil) { // When the App is launched, the root VC will be `nil`. // When this is the case we'll simply show the VC without any type of animation. guard window.rootViewController != nil else { From 6205fafc6b19f861856c6f166f6d86a20264d92c Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:13:41 -0600 Subject: [PATCH 11/35] Update JetpackWindowManager, refactor to enable showing the wp-to-jp migration flow, if needed --- .../Classes/System/JetpackWindowManager.swift | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift index 80d03e98aba7..8ed065171198 100644 --- a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift +++ b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift @@ -1,10 +1,14 @@ +import Combine import Foundation class JetpackWindowManager: WindowManager { + /// receives migration flow updates in order to dismiss it when needed. + private var cancellable: AnyCancellable? + override func showUI(for blog: Blog?) { // If the user is logged in and has blogs sync'd to their account if AccountHelper.isLoggedIn && AccountHelper.hasBlogs { - showAppUI(for: blog) + shouldShowMigrationUI ? showMigrationUI(blog) : showAppUI(for: blog) return } @@ -18,4 +22,27 @@ class JetpackWindowManager: WindowManager { // the `logOutDefaultWordPressComAccount` method will trigger the `showSignInUI` automatically AccountHelper.logOutDefaultWordPressComAccount() } + + private func showMigrationUI(_ blog: Blog?) { + let container = MigrationDependencyContainer() + cancellable = container.migrationCoordinator.$currentStep.sink { [weak self] step in + switch step { + case .welcome, .notifications, .done: + break + case .dismiss: + self?.switchToAppUI(for: blog) + } + } + self.show(container.makeInitialViewController()) + } + + private func switchToAppUI(for blog: Blog?) { + cancellable = nil + showAppUI(for: blog) + } + + // TODO: Add logic in here to trigger migration UI if needed + private var shouldShowMigrationUI: Bool { + true + } } From a89c8a20e0e26a3227a7be61793b24585fdabd86 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:14:41 -0600 Subject: [PATCH 12/35] Update MigrationStep, add missing steps and extract in separate file --- .../Common/Navigation/MigrationStep.swift | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationStep.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationStep.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationStep.swift new file mode 100644 index 000000000000..3edc828bb24b --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationStep.swift @@ -0,0 +1,8 @@ +import Foundation + +enum MigrationStep: String { + case welcome + case notifications + case done + case dismiss +} From e73c00e72d660df0887bad47b8751c72c5f2ed30 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:16:15 -0600 Subject: [PATCH 13/35] Update MigrationActionsView, refactors based on the refactor of configuration types --- .../Common/Views/MigrationActionsView.swift | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationActionsView.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationActionsView.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationActionsView.swift new file mode 100644 index 000000000000..d426ff5450b2 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationActionsView.swift @@ -0,0 +1,125 @@ +import UIKit +import WordPressUI + +final class MigrationActionsView: UIView { + + // MARK: - Views + + private let configuration: MigrationActionsViewConfiguration + + let primaryButton: UIButton = MigrationActionsView.primaryButton() + + let secondaryButton: UIButton = MigrationActionsView.secondaryButton() + + private let visualEffectView: UIVisualEffectView = { + let effect = UIBlurEffect(style: .regular) + let view = UIVisualEffectView(effect: effect) + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + private let separatorView: UIView = { + let view = UIView() + view.backgroundColor = UIColor.separator + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + private let stackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.alignment = .center + stackView.spacing = Constants.spacing + return stackView + }() + + // MARK: - Init + + init(configuration: MigrationActionsViewConfiguration) { + self.configuration = configuration + super.init(frame: .zero) + self.setup() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setup() { + // Set properties + self.directionalLayoutMargins = Constants.insets + + // Layout visual effect view + self.addSubview(visualEffectView) + self.pinSubviewToAllEdges(visualEffectView) + + // Layout separator view + self.addSubview(separatorView) + NSLayoutConstraint.activate([ + separatorView.topAnchor.constraint(equalTo: topAnchor), + separatorView.leadingAnchor.constraint(equalTo: leadingAnchor), + separatorView.trailingAnchor.constraint(equalTo: trailingAnchor), + separatorView.heightAnchor.constraint(equalToConstant: Constants.separatorHeight) + ]) + + // Layout buttons + self.stackView.addArrangedSubviews([primaryButton, secondaryButton]) + self.addSubview(stackView) + configureButtons() + NSLayoutConstraint.activate([ + primaryButton.leadingAnchor.constraint(equalTo: stackView.leadingAnchor), + primaryButton.trailingAnchor.constraint(equalTo: stackView.trailingAnchor), + stackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), + stackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor) + ]) + } + + private func configureButtons() { + primaryButton.setTitle(configuration.primaryTitle, for: .normal) + primaryButton.addTarget(self, action: #selector(didTapPrimaryButton), for: .touchUpInside) + secondaryButton.setTitle(configuration.secondaryTitle, for: .normal) + secondaryButton.addTarget(self, action: #selector(didTapSecondaryButton), for: .touchUpInside) + } + + @objc private func didTapPrimaryButton() { + configuration.primaryHandler?() + } + + @objc private func didTapSecondaryButton() { + configuration.secondaryHandler?() + } + + // MARK: - Button Factory + + private static func primaryButton() -> UIButton { + let button = FancyButton() + button.isPrimary = true + return button + } + + private static func secondaryButton() -> UIButton { + let button = UIButton() + let font = WPStyleGuide.fontForTextStyle(.headline) + button.setTitleColor(.text, for: .normal) + button.titleLabel?.font = font + button.titleLabel?.adjustsFontForContentSizeCategory = true + return button + } + + // MARK: - Configuring Intrinsic Size + + override var intrinsicContentSize: CGSize { + return .init(width: UIView.noIntrinsicMetric, height: stackView.intrinsicContentSize.height) + } + + // MARK: - Constants + + private struct Constants { + static let separatorHeight = CGFloat(0.5) + static let insets = NSDirectionalEdgeInsets(top: 20, leading: 30, bottom: 20, trailing: 30) + static let spacing = CGFloat(10) + } +} From b1bb8e90a990a66c46e3117cec01a9752ee52835 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:16:50 -0600 Subject: [PATCH 14/35] Update MigrationHeaderView, refactors based on the refactor of configuration types --- .../Common/Views/MigrationHeaderView.swift | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationHeaderView.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationHeaderView.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationHeaderView.swift new file mode 100644 index 000000000000..9df33dcc944c --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationHeaderView.swift @@ -0,0 +1,96 @@ +import UIKit + +final class MigrationHeaderView: UIView { + + // MARK: - Views + + let imageView = UIImageView() + + private let configuration: MigrationHeaderConfiguration + + let titleLabel: UILabel = { + let label = UILabel() + label.font = Constants.titleFont + label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true + return label + }() + + let primaryDescriptionLabel: UILabel = { + let label = UILabel() + label.font = Constants.primaryDescriptionFont + label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true + return label + }() + + let secondaryDescriptionLabel: UILabel = { + let label = UILabel() + label.font = Constants.secondaryDescriptionFont + label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true + return label + }() + + // MARK: - Init + + init(configuration: MigrationHeaderConfiguration) { + self.configuration = configuration + super.init(frame: .zero) + self.setup() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setup() { + // Set subviews + let labelsStackView = verticalStackView(arrangedSubviews: [titleLabel, primaryDescriptionLabel, secondaryDescriptionLabel]) + labelsStackView.translatesAutoresizingMaskIntoConstraints = false + labelsStackView.spacing = Constants.labelsSpacing + let mainStackView = verticalStackView(arrangedSubviews: [imageView, labelsStackView]) + mainStackView.spacing = Constants.spacing + mainStackView.alignment = .leading + mainStackView.translatesAutoresizingMaskIntoConstraints = false + self.addSubview(mainStackView) + configureAppearance() + // Set constraints + NSLayoutConstraint.activate([ + labelsStackView.widthAnchor.constraint(equalTo: mainStackView.widthAnchor), + mainStackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), + mainStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), + mainStackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), + mainStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor) + ]) + } + + // MARK: - Views Factory + + private func verticalStackView(arrangedSubviews: [UIView]) -> UIStackView { + let stackView = UIStackView(arrangedSubviews: arrangedSubviews) + stackView.axis = .vertical + return stackView + } + + private func configureAppearance() { + imageView.image = configuration.image + titleLabel.text = configuration.title + primaryDescriptionLabel.text = configuration.primaryDescription + secondaryDescriptionLabel.text = configuration.secondaryDescription + } + + // MARK: - Types + + private struct Constants { + /// Spacing of the top most stack view + static let spacing: CGFloat = 30 + + /// Spacing of the labels stack view + static let labelsSpacing: CGFloat = 20 + + static let titleFont: UIFont = WPStyleGuide.fontForTextStyle(.largeTitle, fontWeight: .bold) + static let primaryDescriptionFont: UIFont = WPStyleGuide.fontForTextStyle(.title2, fontWeight: .regular) + static let secondaryDescriptionFont: UIFont = WPStyleGuide.fontForTextStyle(.body, fontWeight: .regular) + } +} From 493c6940cc512e09aaa8df8185782f73a2054fa6 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 16:17:46 -0600 Subject: [PATCH 15/35] Files and groups re-arranged in WordPress-to-Jetpack migration group --- .../Types/MigrationFlowCoordinator.swift | 85 -------------- .../Types/MigrationStep.swift | 6 - .../Types/MigrationStepViewModel.swift | 37 ------ .../Views/MigrationActionsView.swift | 111 ------------------ .../Views/MigrationHeaderView.swift | 90 -------------- .../Welcome/MigrationWelcomeViewModel.swift | 75 ------------ .../MigrationWelcomeBlogTableViewCell.swift | 0 .../MigrationWelcomeViewController.swift | 28 ++--- .../Welcome/MigrationWelcomeViewModel.swift | 37 ++++++ WordPress/WordPress.xcodeproj/project.pbxproj | 84 +++++++++++-- 10 files changed, 116 insertions(+), 437 deletions(-) delete mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationFlowCoordinator.swift delete mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStep.swift delete mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStepViewModel.swift delete mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationActionsView.swift delete mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationHeaderView.swift delete mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewModel.swift rename WordPress/Jetpack/Classes/ViewRelated/{WordPress Migration => WordPress-to-Jetpack Migration}/Welcome/MigrationWelcomeBlogTableViewCell.swift (100%) rename WordPress/Jetpack/Classes/ViewRelated/{WordPress Migration => WordPress-to-Jetpack Migration}/Welcome/MigrationWelcomeViewController.swift (79%) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationFlowCoordinator.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationFlowCoordinator.swift deleted file mode 100644 index 7ebbef0cffcf..000000000000 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationFlowCoordinator.swift +++ /dev/null @@ -1,85 +0,0 @@ -import UIKit - -final class MigrationFlowCoordinator { - - // MARK: - Properties - - private let account: WPAccount - - private(set) lazy var navigationController: UINavigationController = { - let rootViewController = self.viewController(for: currentStep) - let navigationController = UINavigationController(rootViewController: rootViewController) - self.configure(navigationController: navigationController) - return navigationController - }() - - // MARK: - State - - private var currentStep = MigrationStep.welcome { - didSet { - self.didUpdateCurrentStep(currentStep) - } - } - - // MARK: - Init - - init(account: WPAccount) { - self.account = account - } - - // MARK: - Step Updates - - private func didUpdateCurrentStep(_ newValue: MigrationStep) { - let viewController = self.viewController(for: newValue) - self.navigationController.setViewControllers([viewController], animated: true) - } - - // MARK: - User Interaction - - private func didTapContinue(in step: MigrationStep) { - if let nextStep = Self.nextStep(from: step) { - self.currentStep = nextStep - } else { - // Migration Flow is done - } - } - - // MARK: - View Controllers - - private func viewController(for step: MigrationStep) -> UIViewController { - switch step { - case .welcome: - let viewModel = MigrationWelcomeViewModel(account: account, primaryAction: { self.didTapContinue(in: step) }) - return MigrationWelcomeViewController(viewModel: viewModel) - default: - // This is temporary - let viewController = UIViewController() - viewController.view.backgroundColor = .systemBackground - return viewController - } - } - - private func configure(navigationController: UINavigationController) { - let navigationBar = navigationController.navigationBar - let standardAppearance = UINavigationBarAppearance() - standardAppearance.configureWithDefaultBackground() - let scrollEdgeAppearance = UINavigationBarAppearance() - scrollEdgeAppearance.configureWithTransparentBackground() - navigationBar.standardAppearance = standardAppearance - navigationBar.scrollEdgeAppearance = scrollEdgeAppearance - navigationBar.compactAppearance = standardAppearance - if #available(iOS 15.0, *) { - navigationBar.compactScrollEdgeAppearance = scrollEdgeAppearance - } - navigationBar.isTranslucent = true - } - - // MARK: - Factories - - private static func nextStep(from step: MigrationStep) -> MigrationStep? { - switch step { - case .welcome: return .notification - case .notification: return nil - } - } -} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStep.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStep.swift deleted file mode 100644 index 29f6a4037862..000000000000 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStep.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation - -enum MigrationStep { - case welcome - case notification -} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStepViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStepViewModel.swift deleted file mode 100644 index deb660d3792b..000000000000 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Types/MigrationStepViewModel.swift +++ /dev/null @@ -1,37 +0,0 @@ -import UIKit - -class MigrationStepViewModel { - - // MARK: - Properties - - let image: UIImage? - let title: String - let descriptions: Descriptions - let actions: Actions - - // MARK: - Init - - init(title: String, image: UIImage?, descriptions: Descriptions, actions: Actions) { - self.title = title - self.image = image - self.descriptions = descriptions - self.actions = actions - } - - // MARK: - Types - - struct Actions { - let primary: Action - let secondary: Action - } - - struct Descriptions { - let primary: String - let secondary: String - } - - struct Action { - let title: String - let handler: () -> Void - } -} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationActionsView.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationActionsView.swift deleted file mode 100644 index c37cb298218d..000000000000 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationActionsView.swift +++ /dev/null @@ -1,111 +0,0 @@ -import UIKit -import WordPressUI - -final class MigrationActionsView: UIView { - - // MARK: - Views - - let primaryButton: UIButton = MigrationActionsView.primaryButton() - - let secondaryButton: UIButton = MigrationActionsView.secondaryButton() - - private let visualEffectView: UIVisualEffectView = { - let effect = UIBlurEffect(style: .regular) - let view = UIVisualEffectView(effect: effect) - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private let separatorView: UIView = { - let view = UIView() - view.backgroundColor = UIColor.separator - view.translatesAutoresizingMaskIntoConstraints = false - return view - }() - - private let stackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.axis = .vertical - stackView.alignment = .center - stackView.spacing = Constants.spacing - return stackView - }() - - // MARK: - Init - - init() { - super.init(frame: .zero) - self.setup() - } - - override init(frame: CGRect) { - super.init(frame: frame) - self.setup() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setup() { - // Set properties - self.directionalLayoutMargins = Constants.insets - - // Layout visual effect view - self.addSubview(visualEffectView) - self.pinSubviewToAllEdges(visualEffectView) - - // Layout separator view - self.addSubview(separatorView) - NSLayoutConstraint.activate([ - separatorView.topAnchor.constraint(equalTo: topAnchor), - separatorView.leadingAnchor.constraint(equalTo: leadingAnchor), - separatorView.trailingAnchor.constraint(equalTo: trailingAnchor), - separatorView.heightAnchor.constraint(equalToConstant: Constants.separatorHeight) - ]) - - // Layout buttons - self.stackView.addArrangedSubviews([primaryButton, secondaryButton]) - self.addSubview(stackView) - NSLayoutConstraint.activate([ - primaryButton.leadingAnchor.constraint(equalTo: stackView.leadingAnchor), - primaryButton.trailingAnchor.constraint(equalTo: stackView.trailingAnchor), - stackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), - stackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), - stackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), - stackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor) - ]) - } - - // MARK: - Button Factory - - private static func primaryButton() -> UIButton { - let button = FancyButton() - button.isPrimary = true - return button - } - - private static func secondaryButton() -> UIButton { - let button = UIButton() - let font = WPStyleGuide.fontForTextStyle(.headline) - button.setTitleColor(.text, for: .normal) - button.titleLabel?.font = font - button.titleLabel?.adjustsFontForContentSizeCategory = true - return button - } - - // MARK: - Configuring Intrinsic Size - - override var intrinsicContentSize: CGSize { - return .init(width: UIView.noIntrinsicMetric, height: stackView.intrinsicContentSize.height) - } - - // MARK: - Constants - - private struct Constants { - static let separatorHeight = CGFloat(0.5) - static let insets = NSDirectionalEdgeInsets(top: 20, leading: 30, bottom: 20, trailing: 30) - static let spacing = CGFloat(10) - } -} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationHeaderView.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationHeaderView.swift deleted file mode 100644 index de3718f4df1f..000000000000 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Views/MigrationHeaderView.swift +++ /dev/null @@ -1,90 +0,0 @@ -import UIKit - -final class MigrationHeaderView: UIView { - - // MARK: - Views - - let imageView = UIImageView() - - let titleLabel: UILabel = { - let label = UILabel() - label.font = Constants.titleFont - label.numberOfLines = 0 - label.adjustsFontForContentSizeCategory = true - return label - }() - - let primaryDescriptionLabel: UILabel = { - let label = UILabel() - label.font = Constants.primaryDescriptionFont - label.numberOfLines = 0 - label.adjustsFontForContentSizeCategory = true - return label - }() - - let secondaryDescriptionLabel: UILabel = { - let label = UILabel() - label.font = Constants.secondaryDescriptionFont - label.numberOfLines = 0 - label.adjustsFontForContentSizeCategory = true - return label - }() - - // MARK: - Init - - init() { - super.init(frame: .zero) - self.setup() - } - - override init(frame: CGRect) { - super.init(frame: frame) - self.setup() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private func setup() { - // Set subviews - let labelsStackView = Self.verticalStackView(arrangedSubviews: [titleLabel, primaryDescriptionLabel, secondaryDescriptionLabel]) - labelsStackView.spacing = Constants.labelsSpacing - let mainStackView = Self.verticalStackView(arrangedSubviews: [imageView, labelsStackView]) - mainStackView.spacing = Constants.spacing - mainStackView.translatesAutoresizingMaskIntoConstraints = false - self.addSubview(mainStackView) - - // Set constraints - NSLayoutConstraint.activate([ - mainStackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), - mainStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), - mainStackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), - mainStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor) - ]) - } - - // MARK: - Views Factory - - private static func verticalStackView(arrangedSubviews: [UIView]) -> UIStackView { - let stackView = UIStackView(arrangedSubviews: arrangedSubviews) - stackView.axis = .vertical - stackView.alignment = .leading - stackView.distribution = .fill - return stackView - } - - // MARK: - Types - - private struct Constants { - /// Spacing of the top most stack view - static let spacing: CGFloat = 30 - - /// Spacing of the labels stack view - static let labelsSpacing: CGFloat = 20 - - static let titleFont: UIFont = WPStyleGuide.fontForTextStyle(.largeTitle, fontWeight: .bold) - static let primaryDescriptionFont: UIFont = WPStyleGuide.fontForTextStyle(.title2, fontWeight: .regular) - static let secondaryDescriptionFont: UIFont = WPStyleGuide.fontForTextStyle(.body, fontWeight: .regular) - } -} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewModel.swift deleted file mode 100644 index ec08a1dd90a2..000000000000 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewModel.swift +++ /dev/null @@ -1,75 +0,0 @@ -import UIKit - -final class MigrationWelcomeViewModel: MigrationStepViewModel { - - // MARK: - Properties - - let gravatarEmail: String - - let blogListDataSource: BlogListDataSource - - // MARK: - Init - - init(account: WPAccount, primaryAction: @escaping () -> Void) { - self.gravatarEmail = account.email - - self.blogListDataSource = BlogListDataSource() - self.blogListDataSource.loggedIn = true - self.blogListDataSource.account = account - - let primaryAction = Action(title: Strings.primaryButtonTitle, handler: primaryAction) - let secondaryAction = Action(title: Strings.secondaryButtonTitle, handler: {}) - let actions = Actions(primary: primaryAction, secondary: secondaryAction) - - let secondaryDescription = Strings.secondaryDescription(plural: blogListDataSource.visibleBlogsCount > 1) - let descriptions = Descriptions(primary: Strings.primaryDescription, secondary: secondaryDescription) - - super.init( - title: Strings.title, - image: UIImage(named: "wp-migration-welcome"), - descriptions: descriptions, - actions: actions - ) - } - - // MARK: - Constants - - struct Strings { - - static let title = NSLocalizedString( - "migration.welcome.title", - value: "Welcome to Jetpack!", - comment: "The title in the migration welcome screen" - ) - - static let primaryDescription = NSLocalizedString( - "migration.welcome.primaryDescription", - value: "It looks like you’re switching from the WordPress app.", - comment: "The primary description in the migration welcome screen" - ) - - static func secondaryDescription(plural: Bool) -> String { - let comment = "The secondary description in the migration welcome screen" - let siteWord = plural ? "sites" : "site" - let value = "We found your \(siteWord). Continue to transfer all your data and sign in to Jetpack automatically." - if plural { - let comment = "The plural form of the secondary description in the migration welcome screen" - return NSLocalizedString("migration.welcome.secondaryDescription.plural", value: value, comment: comment) - } else { - let comment = "The singular form of the secondary description in the migration welcome screen" - return NSLocalizedString("migration.welcome.secondaryDescription.singular", value: value, comment: comment) - } - } - - static let primaryButtonTitle = NSLocalizedString( - "Continue", - value: "Continue", - comment: "The primary button title in the migration welcome screen" - ) - - static let secondaryButtonTitle = NSLocalizedString( - "Need help?", - comment: "The secondary button title in the migration welcome screen" - ) - } -} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeBlogTableViewCell.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeBlogTableViewCell.swift similarity index 100% rename from WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeBlogTableViewCell.swift rename to WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeBlogTableViewCell.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewController.swift similarity index 79% rename from WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewController.swift rename to WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewController.swift index fa06ea1a8e91..a3d20166d9b6 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress Migration/Welcome/MigrationWelcomeViewController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewController.swift @@ -10,14 +10,18 @@ final class MigrationWelcomeViewController: UIViewController { private let tableView = UITableView(frame: .zero, style: .plain) - private let headerView: MigrationHeaderView = { - let view = MigrationHeaderView() + private lazy var headerView: MigrationHeaderView = { + let view = MigrationHeaderView(configuration: viewModel.configuration.headerConfiguration) view.translatesAutoresizingMaskIntoConstraints = true view.directionalLayoutMargins = Constants.tableHeaderViewMargins return view }() - private let bottomSheet = MigrationActionsView() + private lazy var bottomSheet: MigrationActionsView = { + let actionsView = MigrationActionsView(configuration: viewModel.configuration.actionsConfiguration) + actionsView.translatesAutoresizingMaskIntoConstraints = false + return actionsView + }() // MARK: - Lifecycle @@ -39,7 +43,6 @@ final class MigrationWelcomeViewController: UIViewController { self.setupTableView() self.setupBottomSheet() self.setupNavigationBar() - self.updateTableHeaderView(with: viewModel) } override func viewDidLayoutSubviews() { @@ -66,8 +69,6 @@ final class MigrationWelcomeViewController: UIViewController { } private func setupBottomSheet() { - self.bottomSheet.translatesAutoresizingMaskIntoConstraints = false - self.bottomSheet.primaryButton.addTarget(self, action: #selector(didTapContinue), for: .touchUpInside) self.view.addSubview(bottomSheet) NSLayoutConstraint.activate([ bottomSheet.leadingAnchor.constraint(equalTo: view.leadingAnchor), @@ -76,15 +77,6 @@ final class MigrationWelcomeViewController: UIViewController { ]) } - private func updateTableHeaderView(with viewModel: MigrationWelcomeViewModel) { - self.headerView.imageView.image = viewModel.image - self.headerView.titleLabel.text = viewModel.title - self.headerView.primaryDescriptionLabel.text = viewModel.descriptions.primary - self.headerView.secondaryDescriptionLabel.text = viewModel.descriptions.secondary - self.bottomSheet.primaryButton.setTitle(viewModel.actions.primary.title, for: .normal) - self.bottomSheet.secondaryButton.setTitle(viewModel.actions.secondary.title, for: .normal) - } - /// Increases the tableView's bottom inset so it doesn't cover the bottom actions sheet. private func updateTableViewContentInset() { let bottomInset = -view.safeAreaInsets.bottom + bottomSheet.bounds.height @@ -92,12 +84,6 @@ final class MigrationWelcomeViewController: UIViewController { self.tableView.verticalScrollIndicatorInsets.bottom = bottomInset } - // MARK: - User Interaction - - @objc private func didTapContinue() { - self.viewModel.actions.primary.handler() - } - // MARK: - Constants private struct Constants { diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift new file mode 100644 index 000000000000..2ff2719988b4 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift @@ -0,0 +1,37 @@ +import UIKit + +final class MigrationWelcomeViewModel { + + // MARK: - Properties + + var gravatarEmail: String? + + let blogListDataSource: BlogListDataSource + + let configuration: MigrationStepConfiguration + + // MARK: - Init + + init(account: WPAccount?, coordinator: MigrationFlowCoordinator) { + if let account { + self.gravatarEmail = account.email + } + + self.blogListDataSource = BlogListDataSource() + self.blogListDataSource.loggedIn = true + self.blogListDataSource.account = account + + configuration = MigrationStepConfiguration(headerConfiguration: + MigrationHeaderConfiguration(step: .welcome, + multiSite: blogListDataSource.visibleBlogsCount > 1), + actionsConfiguration: + MigrationActionsViewConfiguration(step: .welcome, + primaryHandler: { [weak coordinator] in + coordinator?.transitionToNextStep() + }, + secondaryHandler: { + + })) + + } +} diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index bf9354388bbb..8bf8d99e16a3 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -747,6 +747,14 @@ 3FEC241525D73E8B007AFE63 /* ConfettiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FEC241425D73E8B007AFE63 /* ConfettiView.swift */; }; 3FF1A853242D5FCB00373F5D /* WPTabBarController+ReaderTabNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FF1A852242D5FCB00373F5D /* WPTabBarController+ReaderTabNavigation.swift */; }; 3FFA5ED22876152E00830E28 /* JetpackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFA5ED12876152E00830E28 /* JetpackButton.swift */; }; + 3FFDEF7829177D7500B625CE /* MigrationNotificationsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF7729177D7500B625CE /* MigrationNotificationsViewModel.swift */; }; + 3FFDEF7A29177D8C00B625CE /* MigrationNotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF7929177D8C00B625CE /* MigrationNotificationsViewController.swift */; }; + 3FFDEF7F29177FB100B625CE /* MigrationStepConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF7E29177FB100B625CE /* MigrationStepConfiguration.swift */; }; + 3FFDEF812917882800B625CE /* MigrationNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF802917882800B625CE /* MigrationNavigationController.swift */; }; + 3FFDEF8329179CD000B625CE /* MigrationDependencyContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF8229179CD000B625CE /* MigrationDependencyContainer.swift */; }; + 3FFDEF852918215700B625CE /* MigrationStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF842918215700B625CE /* MigrationStepView.swift */; }; + 3FFDEF882918596B00B625CE /* MigrationDoneViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF872918596B00B625CE /* MigrationDoneViewModel.swift */; }; + 3FFDEF8A2918597700B625CE /* MigrationDoneViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF892918597700B625CE /* MigrationDoneViewController.swift */; }; 3FFE3C0828FE00D10021BB96 /* StatsSegmentedControlDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFE3C0728FE00D10021BB96 /* StatsSegmentedControlDataTests.swift */; }; 400199AB222590E100EB0906 /* AllTimeStatsRecordValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400199AA222590E100EB0906 /* AllTimeStatsRecordValueTests.swift */; }; 400199AD22259FF300EB0906 /* AnnualAndMostPopularTimeStatsRecordValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400199AC22259FF300EB0906 /* AnnualAndMostPopularTimeStatsRecordValueTests.swift */; }; @@ -3212,7 +3220,6 @@ F41BDD73290BBDCA00B7F2B0 /* MigrationActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD72290BBDCA00B7F2B0 /* MigrationActionsView.swift */; }; F41BDD792910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD782910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift */; }; F41BDD7B29114E2400B7F2B0 /* MigrationStep.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD7A29114E2400B7F2B0 /* MigrationStep.swift */; }; - F41BDD7D29114E9700B7F2B0 /* MigrationStepViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41BDD7C29114E9700B7F2B0 /* MigrationStepViewModel.swift */; }; F41E32FE287B47A500F89082 /* SuggestionsListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41E32FD287B47A500F89082 /* SuggestionsListViewModel.swift */; }; F41E32FF287B47A500F89082 /* SuggestionsListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41E32FD287B47A500F89082 /* SuggestionsListViewModel.swift */; }; F41E3301287B5FE500F89082 /* SuggestionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41E3300287B5FE500F89082 /* SuggestionViewModel.swift */; }; @@ -6107,6 +6114,14 @@ 3FEC241425D73E8B007AFE63 /* ConfettiView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfettiView.swift; sourceTree = ""; }; 3FF1A852242D5FCB00373F5D /* WPTabBarController+ReaderTabNavigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WPTabBarController+ReaderTabNavigation.swift"; sourceTree = ""; }; 3FFA5ED12876152E00830E28 /* JetpackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackButton.swift; sourceTree = ""; }; + 3FFDEF7729177D7500B625CE /* MigrationNotificationsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationNotificationsViewModel.swift; sourceTree = ""; }; + 3FFDEF7929177D8C00B625CE /* MigrationNotificationsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationNotificationsViewController.swift; sourceTree = ""; }; + 3FFDEF7E29177FB100B625CE /* MigrationStepConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationStepConfiguration.swift; sourceTree = ""; }; + 3FFDEF802917882800B625CE /* MigrationNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationNavigationController.swift; sourceTree = ""; }; + 3FFDEF8229179CD000B625CE /* MigrationDependencyContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationDependencyContainer.swift; sourceTree = ""; }; + 3FFDEF842918215700B625CE /* MigrationStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationStepView.swift; sourceTree = ""; }; + 3FFDEF872918596B00B625CE /* MigrationDoneViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationDoneViewModel.swift; sourceTree = ""; }; + 3FFDEF892918597700B625CE /* MigrationDoneViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationDoneViewController.swift; sourceTree = ""; }; 3FFE3C0728FE00D10021BB96 /* StatsSegmentedControlDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsSegmentedControlDataTests.swift; sourceTree = ""; }; 400199AA222590E100EB0906 /* AllTimeStatsRecordValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllTimeStatsRecordValueTests.swift; sourceTree = ""; }; 400199AC22259FF300EB0906 /* AnnualAndMostPopularTimeStatsRecordValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnualAndMostPopularTimeStatsRecordValueTests.swift; sourceTree = ""; }; @@ -8388,7 +8403,6 @@ F41BDD72290BBDCA00B7F2B0 /* MigrationActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationActionsView.swift; sourceTree = ""; }; F41BDD782910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationFlowCoordinator.swift; sourceTree = ""; }; F41BDD7A29114E2400B7F2B0 /* MigrationStep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationStep.swift; sourceTree = ""; }; - F41BDD7C29114E9700B7F2B0 /* MigrationStepViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationStepViewModel.swift; sourceTree = ""; }; F41E32FD287B47A500F89082 /* SuggestionsListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionsListViewModel.swift; sourceTree = ""; }; F41E3300287B5FE500F89082 /* SuggestionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionViewModel.swift; sourceTree = ""; }; F41E4E8B28F18B7B001880C6 /* AppIconListViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconListViewModelTests.swift; sourceTree = ""; }; @@ -10202,6 +10216,15 @@ path = Stats; sourceTree = ""; }; + 3F00739D2915BAA100A37FD1 /* Notifications Permission */ = { + isa = PBXGroup; + children = ( + 3FFDEF7929177D8C00B625CE /* MigrationNotificationsViewController.swift */, + 3FFDEF7729177D7500B625CE /* MigrationNotificationsViewModel.swift */, + ); + path = "Notifications Permission"; + sourceTree = ""; + }; 3F09CCA62428FE8600D00A8C /* Tab Navigation */ = { isa = PBXGroup; children = ( @@ -10909,6 +10932,33 @@ path = Widgets; sourceTree = ""; }; + 3FFDEF7D29177F4200B625CE /* Common */ = { + isa = PBXGroup; + children = ( + 3FFDEF8229179CD000B625CE /* MigrationDependencyContainer.swift */, + F41BDD772910AFB900B7F2B0 /* Navigation */, + F4F9D5EE29096D0400502576 /* Views */, + ); + path = Common; + sourceTree = ""; + }; + 3FFDEF862918595200B625CE /* All done */ = { + isa = PBXGroup; + children = ( + 3FFDEF892918597700B625CE /* MigrationDoneViewController.swift */, + 3FFDEF872918596B00B625CE /* MigrationDoneViewModel.swift */, + ); + path = "All done"; + sourceTree = ""; + }; + 3FFDEF8D2918625600B625CE /* Configuration */ = { + isa = PBXGroup; + children = ( + 3FFDEF7E29177FB100B625CE /* MigrationStepConfiguration.swift */, + ); + path = Configuration; + sourceTree = ""; + }; 400A2C8D2217AAA1000A8A59 /* Time-based data */ = { isa = PBXGroup; children = ( @@ -15065,7 +15115,7 @@ C7F7AC72261CF1C900CE547F /* ViewRelated */ = { isa = PBXGroup; children = ( - F4F9D5E82909615D00502576 /* WordPress Migration */, + F4F9D5E82909615D00502576 /* WordPress-to-Jetpack Migration */, C72A4FB12641837A009CA633 /* Login Error */, ); path = ViewRelated; @@ -16143,14 +16193,14 @@ path = WordPressIntents; sourceTree = ""; }; - F41BDD772910AFB900B7F2B0 /* Types */ = { + F41BDD772910AFB900B7F2B0 /* Navigation */ = { isa = PBXGroup; children = ( F41BDD782910AFCA00B7F2B0 /* MigrationFlowCoordinator.swift */, + 3FFDEF802917882800B625CE /* MigrationNavigationController.swift */, F41BDD7A29114E2400B7F2B0 /* MigrationStep.swift */, - F41BDD7C29114E9700B7F2B0 /* MigrationStepViewModel.swift */, ); - path = Types; + path = Navigation; sourceTree = ""; }; F41E4E8F28F1949D001880C6 /* App Icons */ = { @@ -16498,14 +16548,15 @@ path = "white-on-pink"; sourceTree = ""; }; - F4F9D5E82909615D00502576 /* WordPress Migration */ = { + F4F9D5E82909615D00502576 /* WordPress-to-Jetpack Migration */ = { isa = PBXGroup; children = ( - F41BDD772910AFB900B7F2B0 /* Types */, - F4F9D5EE29096D0400502576 /* Views */, + 3FFDEF7D29177F4200B625CE /* Common */, F4F9D5ED29096CFC00502576 /* Welcome */, + 3F00739D2915BAA100A37FD1 /* Notifications Permission */, + 3FFDEF862918595200B625CE /* All done */, ); - path = "WordPress Migration"; + path = "WordPress-to-Jetpack Migration"; sourceTree = ""; }; F4F9D5ED29096CFC00502576 /* Welcome */ = { @@ -16521,8 +16572,10 @@ F4F9D5EE29096D0400502576 /* Views */ = { isa = PBXGroup; children = ( - F4F9D5EB29096CF500502576 /* MigrationHeaderView.swift */, F41BDD72290BBDCA00B7F2B0 /* MigrationActionsView.swift */, + F4F9D5EB29096CF500502576 /* MigrationHeaderView.swift */, + 3FFDEF842918215700B625CE /* MigrationStepView.swift */, + 3FFDEF8D2918625600B625CE /* Configuration */, ); path = Views; sourceTree = ""; @@ -22654,6 +22707,7 @@ F1585419267D3B5700A2E966 /* BloggingRemindersScheduler.swift in Sources */, FABB21812602FC2C00C8785C /* DiffContentValue.swift in Sources */, FABB21822602FC2C00C8785C /* FormattableTextContent.swift in Sources */, + 3FFDEF7A29177D8C00B625CE /* MigrationNotificationsViewController.swift in Sources */, FABB21832602FC2C00C8785C /* WordPress-61-62.xcmappingmodel in Sources */, FABB21842602FC2C00C8785C /* WhatIsNewView.swift in Sources */, FABB21852602FC2C00C8785C /* GravatarService.swift in Sources */, @@ -22819,6 +22873,7 @@ 3F946C5A2684DD8E00B946F6 /* BloggingRemindersActions.swift in Sources */, C387B7A22638D66F00BDEF86 /* PostAuthorSelectorViewController.swift in Sources */, 171096CC270F01EA001BCDD6 /* DomainSuggestionsTableViewController.swift in Sources */, + 3FFDEF7F29177FB100B625CE /* MigrationStepConfiguration.swift in Sources */, FABB22052602FC2C00C8785C /* SubjectContentGroup.swift in Sources */, FABB22062602FC2C00C8785C /* PluginListRow.swift in Sources */, FABB22072602FC2C00C8785C /* BlogSettings+DateAndTimeFormat.swift in Sources */, @@ -23152,6 +23207,7 @@ FABB230B2602FC2C00C8785C /* GutenbergViewController.swift in Sources */, FABB230C2602FC2C00C8785C /* EditPageViewController.swift in Sources */, FABB230D2602FC2C00C8785C /* SiteCreator.swift in Sources */, + 3FFDEF8329179CD000B625CE /* MigrationDependencyContainer.swift in Sources */, 3F5B9B45288B0761001D17E9 /* DashboardBadgeCell.swift in Sources */, FABB230E2602FC2C00C8785C /* CalendarMonthView.swift in Sources */, FABB230F2602FC2C00C8785C /* RestoreStatusFailedView.swift in Sources */, @@ -23199,6 +23255,7 @@ FABB23342602FC2C00C8785C /* BlogDetailsSectionFooterView.swift in Sources */, 3F435221289B2B5100CE19ED /* JetpackOverlayViewController.swift in Sources */, FABB23362602FC2C00C8785C /* TenorGIFCollection.swift in Sources */, + 3FFDEF7829177D7500B625CE /* MigrationNotificationsViewModel.swift in Sources */, FABB23372602FC2C00C8785C /* WebNavigationDelegate.swift in Sources */, FAFC065227D27241002F0483 /* BlogDetailsViewController+Dashboard.swift in Sources */, 8B55FAAD2614FC87007D618E /* Text+BoldSubString.swift in Sources */, @@ -23278,6 +23335,7 @@ C9F1D4B82706ED7C00BDF917 /* EditHomepageViewController.swift in Sources */, FABB23772602FC2C00C8785C /* MediaImageExporter.swift in Sources */, FABB23782602FC2C00C8785C /* GutenbergViewController+InformativeDialog.swift in Sources */, + 3FFDEF8A2918597700B625CE /* MigrationDoneViewController.swift in Sources */, 8B55F9DC2614D902007D618E /* CircledIcon.swift in Sources */, FABB23792602FC2C00C8785C /* ChangePasswordViewController.swift in Sources */, 3FE3D1FD26A6F34900F3CD10 /* WPStyleGuide+List.swift in Sources */, @@ -23304,6 +23362,7 @@ FABB23892602FC2C00C8785C /* FormattableUserContent.swift in Sources */, FABB238A2602FC2C00C8785C /* RegisterDomainDetailsViewController+HeaderFooter.swift in Sources */, FABB238B2602FC2C00C8785C /* ReaderSpacerView.swift in Sources */, + 3FFDEF852918215700B625CE /* MigrationStepView.swift in Sources */, FABB238D2602FC2C00C8785C /* WPStyleGuide+SiteCreation.swift in Sources */, F41E32FF287B47A500F89082 /* SuggestionsListViewModel.swift in Sources */, FABB238E2602FC2C00C8785C /* NotificationSettingsService.swift in Sources */, @@ -23575,6 +23634,7 @@ FABB246C2602FC2C00C8785C /* ActivityPostRange.swift in Sources */, FABB246D2602FC2C00C8785C /* ReaderSelectInterestsViewController.swift in Sources */, FABB246E2602FC2C00C8785C /* ReaderShowMenuAction.swift in Sources */, + 3FFDEF882918596B00B625CE /* MigrationDoneViewModel.swift in Sources */, FABB246F2602FC2C00C8785C /* NSURLCache+Helpers.swift in Sources */, FABB24702602FC2C00C8785C /* String+Extensions.swift in Sources */, FABB24712602FC2C00C8785C /* CollapsableHeaderFilterBar.swift in Sources */, @@ -23631,7 +23691,6 @@ DC772AF2282009BA00664C02 /* InsightsLineChart.swift in Sources */, 176CE91727FB44C100F1E32B /* StatsBaseCell.swift in Sources */, 934098C12719577D00B3E77E /* InsightType.swift in Sources */, - F41BDD7D29114E9700B7F2B0 /* MigrationStepViewModel.swift in Sources */, FABB24992602FC2C00C8785C /* StreakStatsRecordValue+CoreDataProperties.swift in Sources */, 46F583AA2624CE790010A723 /* BlockEditorSettings+CoreDataClass.swift in Sources */, FABB249A2602FC2C00C8785C /* Header+WordPress.swift in Sources */, @@ -23995,6 +24054,7 @@ FABB25B92602FC2C00C8785C /* UITextField+WorkaroundContinueIssue.swift in Sources */, FABB25BA2602FC2C00C8785C /* StoreKit+Debug.swift in Sources */, FABB25BB2602FC2C00C8785C /* PrivacySettingsViewController.swift in Sources */, + 3FFDEF812917882800B625CE /* MigrationNavigationController.swift in Sources */, FABB25BC2602FC2C00C8785C /* SharingDetailViewController.m in Sources */, 837B49DE283C2AE80061A657 /* BloggingPromptSettingsReminderDays+CoreDataProperties.swift in Sources */, FABB25BD2602FC2C00C8785C /* OtherAndTotalViewsCount+CoreDataProperties.swift in Sources */, From dadb84f2e8be4f983d7a5324015fa12fd8aa914d Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 17:49:37 -0600 Subject: [PATCH 16/35] Update MigrationStepConfiguration, put separate types in separate files --- .../MigrationActionsConfiguration.swift | 58 ++++++ .../MigrationHeaderConfiguration.swift | 115 ++++++++++++ .../MigrationStepConfiguration.swift | 176 ------------------ WordPress/WordPress.xcodeproj/project.pbxproj | 8 + 4 files changed, 181 insertions(+), 176 deletions(-) create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationActionsConfiguration.swift create mode 100644 WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationHeaderConfiguration.swift diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationActionsConfiguration.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationActionsConfiguration.swift new file mode 100644 index 000000000000..2a70d2144ee7 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationActionsConfiguration.swift @@ -0,0 +1,58 @@ +struct MigrationActionsViewConfiguration { + let step: MigrationStep + let primaryTitle: String? + let secondaryTitle: String? + let primaryHandler: (() -> Void)? + let secondaryHandler: (() -> Void)? + + init(step: MigrationStep, primaryHandler: (() -> Void)? = nil, secondaryHandler: (() -> Void)? = nil) { + self.step = step + self.primaryHandler = primaryHandler + self.secondaryHandler = secondaryHandler + self.primaryTitle = Appearance.primaryTitle(for: step) + self.secondaryTitle = Appearance.secondaryTitle(for: step) + } +} + +private extension MigrationActionsViewConfiguration { + + enum Appearance { + + static func primaryTitle(for step: MigrationStep) -> String? { + switch step { + case .welcome, .notifications: + return Appearance.defaultPrimaryTitle + case .done: + return Appearance.donePrimaryTitle + case.dismiss: + return nil + } + } + + static func secondaryTitle(for step: MigrationStep) -> String? { + switch step { + case .welcome: + return Appearance.welcomeSecondaryTitle + case .notifications: + return Appearance.notificationsSecondaryTitle + default: + return nil + } + } + + static let defaultPrimaryTitle = NSLocalizedString("Continue", + value: "Continue", + comment: "The primary button title in the migration welcome and notifications screens.") + + static let donePrimaryTitle = NSLocalizedString("migration.done.actions.primary.title", + value: "Finish", + comment: "Primary button title in the migration done screen.") + + static let welcomeSecondaryTitle = NSLocalizedString("Need help?", + comment: "The secondary button title in the migration welcome screen") + + static let notificationsSecondaryTitle = NSLocalizedString("migration.notifications.actions.secondary.title", + value: "Decide later", + comment: "Secondary button title in the migration notifications screen.") + } +} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationHeaderConfiguration.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationHeaderConfiguration.swift new file mode 100644 index 000000000000..e0949caa9b16 --- /dev/null +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationHeaderConfiguration.swift @@ -0,0 +1,115 @@ +struct MigrationHeaderConfiguration { + + let step: MigrationStep + let title: String? + let image: UIImage? + let primaryDescription: String? + let secondaryDescription: String? + + init(step: MigrationStep, multiSite: Bool = false) { + self.step = step + + image = Appearance.image(for: step) + title = Appearance.title(for: step) + primaryDescription = Appearance.primaryDescription(for: step) + secondaryDescription = Appearance.secondaryDescription(for: step, multiSite: multiSite) + } +} + +private extension MigrationHeaderConfiguration { + + enum Appearance { + // TODO: Set the right images for notification and done states + static func image(for step: MigrationStep) -> UIImage? { + switch step { + case .welcome: + return UIImage(named: "wp-migration-welcome") + case .notifications: + return UIImage(named: "wp-migration-welcome") + case .done: + return UIImage(named: "wp-migration-welcome") + case .dismiss: + return nil + } + } + + static func title(for step: MigrationStep) -> String? { + switch step { + case .welcome: + return welcomeTitle + case .notifications: + return notificationsTitle + case .done: + return doneTitle + case .dismiss: + return nil + } + } + + static func primaryDescription(for step: MigrationStep) -> String? { + switch step { + case .welcome: + return welcomePrimaryDescription + case .notifications: + return notificationsPrimaryDescription + case .done: + return donePrimaryDescription + case .dismiss: + return nil + } + } + + static func secondaryDescription(for step: MigrationStep, multiSite: Bool = false) -> String? { + switch step { + case .welcome: + return welcomeSecondaryDescription(plural: multiSite) + case .notifications: + return notificationsSecondaryDescription + case .done: + return nil + case .dismiss: + return nil + } + } + + static let welcomeTitle = NSLocalizedString("migration.welcome.title", + value: "Welcome to Jetpack!", + comment: "The title in the migration welcome screen") + + static let notificationsTitle = NSLocalizedString("migration.notifications.title", + value: "Allow notifications to keep up with your site", + comment: "Title of the migration notifications screen.") + + static let doneTitle = NSLocalizedString("migration.done.title", + value: "Thanks for switching to Jetpack!", + comment: "Title of the migration done screen.") + + static let welcomePrimaryDescription = NSLocalizedString("migration.welcome.primaryDescription", + value: "It looks like you’re switching from the WordPress app.", + comment: "The primary description in the migration welcome screen") + + static let notificationsPrimaryDescription = NSLocalizedString("migration.notifications.primaryDescription", + value: "You’ll get all the same notifications but now they’ll come from the Jetpack app.", + comment: "Primary description in the migration notifications screen.") + + static let donePrimaryDescription = NSLocalizedString("migration.done.primaryDescription", + value: "We’ve transferred all your data and settings. Everything is right where you left it.", + comment: "Primary description in the migration done screen.") + + static let notificationsSecondaryDescription = NSLocalizedString("migration.notifications.secondaryDescription", + value: "We’ve disabled notifications for the WordPress app.", + comment: "Secondary description in the migration notifications screen") + + static func welcomeSecondaryDescription(plural: Bool) -> String { + let siteWord = plural ? "sites" : "site" + let value = "We found your \(siteWord). Continue to transfer all your data and sign in to Jetpack automatically." + if plural { + let comment = "The plural form of the secondary description in the migration welcome screen" + return NSLocalizedString("migration.welcome.secondaryDescription.plural", value: value, comment: comment) + } else { + let comment = "The singular form of the secondary description in the migration welcome screen" + return NSLocalizedString("migration.welcome.secondaryDescription.singular", value: value, comment: comment) + } + } + } +} diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift index f6da0b65f226..406eb1a22185 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/Configuration/MigrationStepConfiguration.swift @@ -1,180 +1,4 @@ - struct MigrationStepConfiguration { let headerConfiguration: MigrationHeaderConfiguration let actionsConfiguration: MigrationActionsViewConfiguration } - -struct MigrationHeaderConfiguration { - - let step: MigrationStep - let title: String? - let image: UIImage? - let primaryDescription: String? - let secondaryDescription: String? - - init(step: MigrationStep, multiSite: Bool = false) { - self.step = step - - image = Appearance.image(for: step) - title = Appearance.title(for: step) - primaryDescription = Appearance.primaryDescription(for: step) - secondaryDescription = Appearance.secondaryDescription(for: step, multiSite: multiSite) - } -} - -private extension MigrationHeaderConfiguration { - - enum Appearance { - // TODO: Set the right images for notification and done states - static func image(for step: MigrationStep) -> UIImage? { - switch step { - case .welcome: - return UIImage(named: "wp-migration-welcome") - case .notifications: - return UIImage(named: "wp-migration-welcome") - case .done: - return UIImage(named: "wp-migration-welcome") - case .dismiss: - return nil - } - } - - static func title(for step: MigrationStep) -> String? { - switch step { - case .welcome: - return welcomeTitle - case .notifications: - return notificationsTitle - case .done: - return doneTitle - case .dismiss: - return nil - } - } - - static func primaryDescription(for step: MigrationStep) -> String? { - switch step { - case .welcome: - return welcomePrimaryDescription - case .notifications: - return notificationsPrimaryDescription - case .done: - return donePrimaryDescription - case .dismiss: - return nil - } - } - - static func secondaryDescription(for step: MigrationStep, multiSite: Bool = false) -> String? { - switch step { - case .welcome: - return welcomeSecondaryDescription(plural: multiSite) - case .notifications: - return notificationsSecondaryDescription - case .done: - return nil - case .dismiss: - return nil - } - } - - static let welcomeTitle = NSLocalizedString("migration.welcome.title", - value: "Welcome to Jetpack!", - comment: "The title in the migration welcome screen") - - static let notificationsTitle = NSLocalizedString("migration.notifications.title", - value: "Allow notifications to keep up with your site", - comment: "Title of the migration notifications screen.") - - static let doneTitle = NSLocalizedString("migration.done.title", - value: "Thanks for switching to Jetpack!", - comment: "Title of the migration done screen.") - - static let welcomePrimaryDescription = NSLocalizedString("migration.welcome.primaryDescription", - value: "It looks like you’re switching from the WordPress app.", - comment: "The primary description in the migration welcome screen") - - static let notificationsPrimaryDescription = NSLocalizedString("migration.notifications.primaryDescription", - value: "You’ll get all the same notifications but now they’ll come from the Jetpack app.", - comment: "Primary description in the migration notifications screen.") - - static let donePrimaryDescription = NSLocalizedString("migration.done.primaryDescription", - value: "We’ve transferred all your data and settings. Everything is right where you left it.", - comment: "Primary description in the migration done screen.") - - static let notificationsSecondaryDescription = NSLocalizedString("migration.notifications.secondaryDescription", - value: "We’ve disabled notifications for the WordPress app.", - comment: "Secondary description in the migration notifications screen") - - static func welcomeSecondaryDescription(plural: Bool) -> String { - let siteWord = plural ? "sites" : "site" - let value = "We found your \(siteWord). Continue to transfer all your data and sign in to Jetpack automatically." - if plural { - let comment = "The plural form of the secondary description in the migration welcome screen" - return NSLocalizedString("migration.welcome.secondaryDescription.plural", value: value, comment: comment) - } else { - let comment = "The singular form of the secondary description in the migration welcome screen" - return NSLocalizedString("migration.welcome.secondaryDescription.singular", value: value, comment: comment) - } - } - } -} - -struct MigrationActionsViewConfiguration { - let step: MigrationStep - let primaryTitle: String? - let secondaryTitle: String? - let primaryHandler: (() -> Void)? - let secondaryHandler: (() -> Void)? - - init(step: MigrationStep, primaryHandler: (() -> Void)? = nil, secondaryHandler: (() -> Void)? = nil) { - self.step = step - self.primaryHandler = primaryHandler - self.secondaryHandler = secondaryHandler - self.primaryTitle = Appearance.primaryTitle(for: step) - self.secondaryTitle = Appearance.secondaryTitle(for: step) - } -} - -private extension MigrationActionsViewConfiguration { - - enum Appearance { - - static func primaryTitle(for step: MigrationStep) -> String? { - switch step { - case .welcome, .notifications: - return Appearance.defaultPrimaryTitle - case .done: - return Appearance.donePrimaryTitle - case.dismiss: - return nil - } - } - - static func secondaryTitle(for step: MigrationStep) -> String? { - switch step { - case .welcome: - return Appearance.welcomeSecondaryTitle - case .notifications: - return Appearance.notificationsSecondaryTitle - default: - return nil - } - } - - static let defaultPrimaryTitle = NSLocalizedString("Continue", - value: "Continue", - comment: "The primary button title in the migration welcome and notifications screens.") - - static let donePrimaryTitle = NSLocalizedString("migration.done.actions.primary.title", - value: "Finish", - comment: "Primary button title in the migration done screen.") - - static let welcomeSecondaryTitle = NSLocalizedString("Need help?", - comment: "The secondary button title in the migration welcome screen") - - static let notificationsSecondaryTitle = NSLocalizedString("migration.notifications.actions.secondary.title", - value: "Decide later", - comment: "Secondary button title in the migration notifications screen.") - } -} diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 8bf8d99e16a3..026f7f2ed3ca 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -755,6 +755,8 @@ 3FFDEF852918215700B625CE /* MigrationStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF842918215700B625CE /* MigrationStepView.swift */; }; 3FFDEF882918596B00B625CE /* MigrationDoneViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF872918596B00B625CE /* MigrationDoneViewModel.swift */; }; 3FFDEF8A2918597700B625CE /* MigrationDoneViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF892918597700B625CE /* MigrationDoneViewController.swift */; }; + 3FFDEF8F29187F1200B625CE /* MigrationHeaderConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF8E29187F1200B625CE /* MigrationHeaderConfiguration.swift */; }; + 3FFDEF9129187F2100B625CE /* MigrationActionsConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFDEF9029187F2100B625CE /* MigrationActionsConfiguration.swift */; }; 3FFE3C0828FE00D10021BB96 /* StatsSegmentedControlDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FFE3C0728FE00D10021BB96 /* StatsSegmentedControlDataTests.swift */; }; 400199AB222590E100EB0906 /* AllTimeStatsRecordValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400199AA222590E100EB0906 /* AllTimeStatsRecordValueTests.swift */; }; 400199AD22259FF300EB0906 /* AnnualAndMostPopularTimeStatsRecordValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400199AC22259FF300EB0906 /* AnnualAndMostPopularTimeStatsRecordValueTests.swift */; }; @@ -6122,6 +6124,8 @@ 3FFDEF842918215700B625CE /* MigrationStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationStepView.swift; sourceTree = ""; }; 3FFDEF872918596B00B625CE /* MigrationDoneViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationDoneViewModel.swift; sourceTree = ""; }; 3FFDEF892918597700B625CE /* MigrationDoneViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationDoneViewController.swift; sourceTree = ""; }; + 3FFDEF8E29187F1200B625CE /* MigrationHeaderConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationHeaderConfiguration.swift; sourceTree = ""; }; + 3FFDEF9029187F2100B625CE /* MigrationActionsConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationActionsConfiguration.swift; sourceTree = ""; }; 3FFE3C0728FE00D10021BB96 /* StatsSegmentedControlDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsSegmentedControlDataTests.swift; sourceTree = ""; }; 400199AA222590E100EB0906 /* AllTimeStatsRecordValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllTimeStatsRecordValueTests.swift; sourceTree = ""; }; 400199AC22259FF300EB0906 /* AnnualAndMostPopularTimeStatsRecordValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnualAndMostPopularTimeStatsRecordValueTests.swift; sourceTree = ""; }; @@ -10954,6 +10958,8 @@ 3FFDEF8D2918625600B625CE /* Configuration */ = { isa = PBXGroup; children = ( + 3FFDEF9029187F2100B625CE /* MigrationActionsConfiguration.swift */, + 3FFDEF8E29187F1200B625CE /* MigrationHeaderConfiguration.swift */, 3FFDEF7E29177FB100B625CE /* MigrationStepConfiguration.swift */, ); path = Configuration; @@ -23492,6 +23498,7 @@ 3F2ABE1D277118CC005D8916 /* WPMediaAsset+VideoLimits.swift in Sources */, FABB23FB2602FC2C00C8785C /* WPTabBarController+MeNavigation.swift in Sources */, 80EF928B280D28140064A971 /* Atomic.swift in Sources */, + 3FFDEF9129187F2100B625CE /* MigrationActionsConfiguration.swift in Sources */, FABB23FC2602FC2C00C8785C /* SitePromptView.swift in Sources */, 8B4EDADE27DF9D5E004073B6 /* Blog+MySite.swift in Sources */, FABB23FD2602FC2C00C8785C /* BaseRestoreCompleteViewController.swift in Sources */, @@ -23543,6 +23550,7 @@ 830A58D92793AB4500CDE94F /* LoginEpilogueAnimator.swift in Sources */, FABB24262602FC2C00C8785C /* SiteAssemblyStep.swift in Sources */, FABB24272602FC2C00C8785C /* SiteSettingsViewController+Swift.swift in Sources */, + 3FFDEF8F29187F1200B625CE /* MigrationHeaderConfiguration.swift in Sources */, FABB24282602FC2C00C8785C /* FilterTableData.swift in Sources */, FABB24292602FC2C00C8785C /* ReaderGapMarker.m in Sources */, FABB242A2602FC2C00C8785C /* Pattern.swift in Sources */, From be02a8bd9e5c5894bf3722b170b6b88ffe56f012 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 18:08:03 -0600 Subject: [PATCH 17/35] Update MigrationDoneViewController, MigrationNotificationsViewController, add some comments --- .../All done/MigrationDoneViewController.swift | 1 + .../MigrationNotificationsViewController.swift | 2 ++ 2 files changed, 3 insertions(+) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift index 8f239e2577e4..f04210ed55c3 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewController.swift @@ -14,6 +14,7 @@ class MigrationDoneViewController: UIViewController { } override func loadView() { + // TODO: replace this blank center view with the actual content let centerView = UIView() centerView.translatesAutoresizingMaskIntoConstraints = false centerView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .vertical) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift index 6375b420e6f8..ae75f70bfa52 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewController.swift @@ -14,9 +14,11 @@ class MigrationNotificationsViewController: UIViewController { } override func loadView() { + // TODO: replace this blank center view with the actual content let centerView = UIView() centerView.translatesAutoresizingMaskIntoConstraints = false centerView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .vertical) + view = MigrationStepView(headerView: MigrationHeaderView(configuration: viewModel.configuration.headerConfiguration), actionsView: MigrationActionsView(configuration: viewModel.configuration.actionsConfiguration), centerView: centerView) From f258dd33d4b57737c184590b03fbbc9481edbcda Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 18:20:15 -0600 Subject: [PATCH 18/35] Update MigrationDependencyContainer, remove incorrect comment --- .../Common/MigrationDependencyContainer.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift index 43fb00f72575..a6a80893afd6 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift @@ -20,7 +20,6 @@ class MigrationDependencyContainer { } } - // MARK: view controller factory private func makeWelcomeViewModel() -> MigrationWelcomeViewModel { MigrationWelcomeViewModel(account: makeAccount(), coordinator: migrationCoordinator) } From 2660dca905859b4c8b4157e7e46d77c15ebc9c35 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Sun, 6 Nov 2022 18:34:48 -0600 Subject: [PATCH 19/35] Update MigrationStepView, remove unnecessary settings --- .../Common/Views/MigrationStepView.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift index ee2ce120fbbd..cca338a1ffc7 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Views/MigrationStepView.swift @@ -18,11 +18,9 @@ class MigrationStepView: UIView { centerView: UIView) { self.headerView = headerView - headerView.translatesAutoresizingMaskIntoConstraints = false headerView.directionalLayoutMargins = Self.headerViewMargins self.centerView = centerView self.actionsView = actionsView - actionsView.translatesAutoresizingMaskIntoConstraints = false super.init(frame: .zero) backgroundColor = .systemBackground addSubview(mainStackView) From 85e8e05dac59594699d0f65b3f3774060e3df288 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 14:57:40 -0600 Subject: [PATCH 20/35] Fix trailing space violations --- .../Navigation/MigrationNavigationController.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift index 7d251d9a7af3..da10994b46ff 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift @@ -10,6 +10,18 @@ class MigrationNavigationController: UINavigationController { /// Receives state changes to set the navigation stack accordingly private var cancellable: AnyCancellable? + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + if WPDeviceIdentification.isiPhone() { + return .portrait + } else { + return .allButUpsideDown + } + } + + override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { + .portrait + } + init(coordinator: MigrationFlowCoordinator, migrationStack: [MigrationStep: UIViewController]) { self.coordinator = coordinator self.migrationStack = migrationStack From b60e047c86d9459942cdf9d05eaeffc7e4eddef0 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 15:08:35 -0600 Subject: [PATCH 21/35] Update migration view models, improve code legibility --- .../All done/MigrationDoneViewModel.swift | 11 ++++++---- .../MigrationNotificationsViewModel.swift | 16 +++++++++------ .../Welcome/MigrationWelcomeViewModel.swift | 20 +++++++++---------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift index 3b01516ebc0e..61e6885f57c5 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift @@ -4,9 +4,12 @@ class MigrationDoneViewModel { init(coordinator: MigrationFlowCoordinator) { - configuration = MigrationStepConfiguration(headerConfiguration: MigrationHeaderConfiguration(step: .done), - actionsConfiguration: MigrationActionsViewConfiguration(step: .done, primaryHandler: { [weak coordinator] in - coordinator?.transitionToNextStep() - })) + let headerConfiguration = MigrationHeaderConfiguration(step: .done) + + let actionsConfiguration = MigrationActionsViewConfiguration(step: .done, primaryHandler: { [weak coordinator] in + coordinator?.transitionToNextStep() + }) + configuration = MigrationStepConfiguration(headerConfiguration: headerConfiguration, + actionsConfiguration: actionsConfiguration) } } diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift index 5d2af07da4b5..4d72469c3517 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift @@ -5,11 +5,15 @@ class MigrationNotificationsViewModel { let configuration: MigrationStepConfiguration init(coordinator: MigrationFlowCoordinator) { - self.configuration = MigrationStepConfiguration(headerConfiguration: MigrationHeaderConfiguration(step: .notifications), - actionsConfiguration: MigrationActionsViewConfiguration(step: .notifications, - primaryHandler: {}, - secondaryHandler: { [weak coordinator] in - coordinator?.transitionToNextStep() - })) + + let headerConfiguration = MigrationHeaderConfiguration(step: .notifications) + + let actionsConfiguration = MigrationActionsViewConfiguration(step: .notifications, + primaryHandler: {}, + secondaryHandler: { [weak coordinator] in + coordinator?.transitionToNextStep() + }) + + configuration = MigrationStepConfiguration(headerConfiguration: headerConfiguration, actionsConfiguration: actionsConfiguration) } } diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift index 2ff2719988b4..737fe460600e 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift @@ -21,17 +21,15 @@ final class MigrationWelcomeViewModel { self.blogListDataSource.loggedIn = true self.blogListDataSource.account = account - configuration = MigrationStepConfiguration(headerConfiguration: - MigrationHeaderConfiguration(step: .welcome, - multiSite: blogListDataSource.visibleBlogsCount > 1), - actionsConfiguration: - MigrationActionsViewConfiguration(step: .welcome, - primaryHandler: { [weak coordinator] in - coordinator?.transitionToNextStep() - }, - secondaryHandler: { - - })) + let headerConfiguration = MigrationHeaderConfiguration(step: .welcome, + multiSite: blogListDataSource.visibleBlogsCount > 1) + let actionsConfiguration = MigrationActionsViewConfiguration(step: .welcome, + primaryHandler: { [weak coordinator] in + coordinator?.transitionToNextStep() + }, + secondaryHandler: { }) + + configuration = MigrationStepConfiguration(headerConfiguration: headerConfiguration, actionsConfiguration: actionsConfiguration) } } From 39864a37a89c6fe3ddc58899bc3e6a5447add654 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 15:44:19 -0600 Subject: [PATCH 22/35] Update MigrationDependencyContainer, extract view controller factory, now passed to the navigation view controller --- .../Common/MigrationDependencyContainer.swift | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift index a6a80893afd6..bc46c3614c6e 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift @@ -4,9 +4,29 @@ class MigrationDependencyContainer { func makeInitialViewController() -> UIViewController { MigrationNavigationController(coordinator: migrationCoordinator, - migrationStack: [.welcome: makeWelcomeViewController(), - .notifications: makeNotificationsViewController(), - .done: makeDoneViewController()]) + factory: MigrationViewControllerFactory(coordinator: migrationCoordinator)) + } +} + +struct MigrationViewControllerFactory { + + let coordinator: MigrationFlowCoordinator + + init(coordinator: MigrationFlowCoordinator) { + self.coordinator = coordinator + } + + func viewController(for step: MigrationStep) -> UIViewController? { + switch step { + case .welcome: + return makeWelcomeViewController() + case .notifications: + return makeNotificationsViewController() + case .done: + return makeDoneViewController() + case .dismiss: + return nil + } } private func makeAccount() -> WPAccount? { @@ -21,7 +41,7 @@ class MigrationDependencyContainer { } private func makeWelcomeViewModel() -> MigrationWelcomeViewModel { - MigrationWelcomeViewModel(account: makeAccount(), coordinator: migrationCoordinator) + MigrationWelcomeViewModel(account: makeAccount(), coordinator: coordinator) } private func makeWelcomeViewController() -> UIViewController { @@ -29,7 +49,7 @@ class MigrationDependencyContainer { } private func makeNotificationsViewModel() -> MigrationNotificationsViewModel { - MigrationNotificationsViewModel(coordinator: migrationCoordinator) + MigrationNotificationsViewModel(coordinator: coordinator) } private func makeNotificationsViewController() -> UIViewController { @@ -37,7 +57,7 @@ class MigrationDependencyContainer { } private func makeDoneViewModel() -> MigrationDoneViewModel { - MigrationDoneViewModel(coordinator: migrationCoordinator) + MigrationDoneViewModel(coordinator: coordinator) } private func makeDoneViewController() -> UIViewController { From a33da86dc309002d82b6f5fac4a9297c00ebee73 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 15:44:52 -0600 Subject: [PATCH 23/35] Update MigrationNavigationController, use view controller factory to instantiate and push vcs to the stack --- .../Navigation/MigrationNavigationController.swift | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift index da10994b46ff..022f2f096951 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift @@ -2,11 +2,10 @@ import Combine import UIKit class MigrationNavigationController: UINavigationController { - + /// Navigation coordinator private let coordinator: MigrationFlowCoordinator - /// The full navigation stack: keys are the states in which the corresponding view - /// controller should be the root - private let migrationStack: [MigrationStep: UIViewController] + /// The view controller factory used to push view controllers on the stack + private let factory: MigrationViewControllerFactory /// Receives state changes to set the navigation stack accordingly private var cancellable: AnyCancellable? @@ -22,9 +21,9 @@ class MigrationNavigationController: UINavigationController { .portrait } - init(coordinator: MigrationFlowCoordinator, migrationStack: [MigrationStep: UIViewController]) { + init(coordinator: MigrationFlowCoordinator, factory: MigrationViewControllerFactory) { self.coordinator = coordinator - self.migrationStack = migrationStack + self.factory = factory super.init(nibName: nil, bundle: nil) configure() } @@ -57,7 +56,7 @@ class MigrationNavigationController: UINavigationController { private func updateStack(for step: MigrationStep) { // sets the stack for the next navigation step, if there's one - guard let viewController = migrationStack[step] else { + guard let viewController = factory.viewController(for: step) else { return } // if we want to support backwards navigation, we need to set From 15e7a29d73e8d1d7002b2d8d629465c2dabaff53 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 15:57:42 -0600 Subject: [PATCH 24/35] Update JetpackWindowManager, simplify logic and make sure that the ui is always instantiated on the main thread --- .../Classes/System/JetpackWindowManager.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift index 8ed065171198..d70d8ee4db85 100644 --- a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift +++ b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift @@ -26,19 +26,19 @@ class JetpackWindowManager: WindowManager { private func showMigrationUI(_ blog: Blog?) { let container = MigrationDependencyContainer() cancellable = container.migrationCoordinator.$currentStep.sink { [weak self] step in - switch step { - case .welcome, .notifications, .done: - break - case .dismiss: - self?.switchToAppUI(for: blog) + guard step == .dismiss else { + return } + self?.switchToAppUI(for: blog) } self.show(container.makeInitialViewController()) } private func switchToAppUI(for blog: Blog?) { cancellable = nil - showAppUI(for: blog) + DispatchQueue.main.async { [weak self] in + self?.showAppUI(for: blog) + } } // TODO: Add logic in here to trigger migration UI if needed From 3bf7ef721c80bbc129bc8ccf508e37417b1ff47e Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 16:17:02 -0600 Subject: [PATCH 25/35] Update MigrationFlowCoordinator, add logic to skip notifications permission screen if users have already decided --- .../Navigation/MigrationFlowCoordinator.swift | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift index 06cc6b88a175..b93a0679b90e 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift @@ -1,4 +1,5 @@ import Combine +import UserNotifications /// Coordinator for the migration to jetpack flow final class MigrationFlowCoordinator: ObservableObject { @@ -6,15 +7,24 @@ final class MigrationFlowCoordinator: ObservableObject { @Published private(set) var currentStep = MigrationStep.welcome func transitionToNextStep() { - if let nextStep = Self.nextStep(from: currentStep) { - self.currentStep = nextStep + Task { [weak self] in + if let nextStep = await Self.nextStep(from: currentStep) { + self?.currentStep = nextStep + } } } - private static func nextStep(from step: MigrationStep) -> MigrationStep? { + private static func shouldSkipNotificationsScreen() async -> Bool { + let settings = await UNUserNotificationCenter.current().notificationSettings() + let authStatus = settings.authorizationStatus + return authStatus == .authorized || authStatus == .denied + } + + private static func nextStep(from step: MigrationStep) async -> MigrationStep? { switch step { case .welcome: - return .notifications + let shouldSkipNotifications = await shouldSkipNotificationsScreen() + return shouldSkipNotifications ? .done : .notifications case .notifications: return .done case .done: From 3387916e8f9f3822019005ceb6de5e4a9995e504 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 16:18:13 -0600 Subject: [PATCH 26/35] Update MigrationNavigationController, always create and assign view controllers on the main thread --- .../Common/Navigation/MigrationNavigationController.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift index 022f2f096951..29e19213c8b1 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift @@ -50,7 +50,9 @@ class MigrationNavigationController: UINavigationController { private func listenForStateChanges() { cancellable = coordinator.$currentStep.sink { [weak self] step in - self?.updateStack(for: step) + DispatchQueue.main.async { + self?.updateStack(for: step) + } } } From 1d7ccdc44b4f362c1683d5119fa3085188c74f58 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Mon, 7 Nov 2022 16:20:01 -0600 Subject: [PATCH 27/35] Update migration view models, add notification permission logic and fix indentation --- .../All done/MigrationDoneViewModel.swift | 4 ++-- .../MigrationNotificationsViewModel.swift | 10 +++++++--- .../Welcome/MigrationWelcomeViewModel.swift | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift index 61e6885f57c5..1ed1986d7d9e 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/All done/MigrationDoneViewModel.swift @@ -7,8 +7,8 @@ class MigrationDoneViewModel { let headerConfiguration = MigrationHeaderConfiguration(step: .done) let actionsConfiguration = MigrationActionsViewConfiguration(step: .done, primaryHandler: { [weak coordinator] in - coordinator?.transitionToNextStep() - }) + coordinator?.transitionToNextStep() + }) configuration = MigrationStepConfiguration(headerConfiguration: headerConfiguration, actionsConfiguration: actionsConfiguration) } diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift index 4d72469c3517..de8d5e0491e7 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Notifications Permission/MigrationNotificationsViewModel.swift @@ -9,10 +9,14 @@ class MigrationNotificationsViewModel { let headerConfiguration = MigrationHeaderConfiguration(step: .notifications) let actionsConfiguration = MigrationActionsViewConfiguration(step: .notifications, - primaryHandler: {}, + primaryHandler: { + InteractiveNotificationsManager.shared.requestAuthorization { [weak coordinator] authorized in + coordinator?.transitionToNextStep() + } + }, secondaryHandler: { [weak coordinator] in - coordinator?.transitionToNextStep() - }) + coordinator?.transitionToNextStep() + }) configuration = MigrationStepConfiguration(headerConfiguration: headerConfiguration, actionsConfiguration: actionsConfiguration) } diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift index 737fe460600e..1c267c0f62c6 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Welcome/MigrationWelcomeViewModel.swift @@ -26,8 +26,8 @@ final class MigrationWelcomeViewModel { let actionsConfiguration = MigrationActionsViewConfiguration(step: .welcome, primaryHandler: { [weak coordinator] in - coordinator?.transitionToNextStep() - }, + coordinator?.transitionToNextStep() + }, secondaryHandler: { }) configuration = MigrationStepConfiguration(headerConfiguration: headerConfiguration, actionsConfiguration: actionsConfiguration) From eabe689d5c9ddaa0b06a5100579199849c52b057 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 10:40:41 -0600 Subject: [PATCH 28/35] Update MigrationDependencyContainer, changed to struct since we don't need to hold a reference to it --- .../Common/MigrationDependencyContainer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift index bc46c3614c6e..fe5c5ca4e1e2 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift @@ -1,4 +1,4 @@ -class MigrationDependencyContainer { +struct MigrationDependencyContainer { let migrationCoordinator = MigrationFlowCoordinator() From 959f68758a77a61a0849a3e4eb2343ef0cfdaa44 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 10:41:23 -0600 Subject: [PATCH 29/35] Update MigrationNavigationController, instantiate with rootViewController to avoid initial glitch --- .../Common/Navigation/MigrationNavigationController.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift index 29e19213c8b1..66c54585ebcd 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift @@ -24,7 +24,11 @@ class MigrationNavigationController: UINavigationController { init(coordinator: MigrationFlowCoordinator, factory: MigrationViewControllerFactory) { self.coordinator = coordinator self.factory = factory - super.init(nibName: nil, bundle: nil) + if let initialController = factory.viewController(for: .welcome) { + super.init(rootViewController: initialController) + } else { + super.init(nibName: nil, bundle: nil) + } configure() } From 40127dacef269eca3cb5f9b9b297a14dd057f5c0 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 11:08:35 -0600 Subject: [PATCH 30/35] Update MigrationViewControllerFactory, add method initialViewController() --- .../Common/MigrationDependencyContainer.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift index fe5c5ca4e1e2..f37424fb1a17 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/MigrationDependencyContainer.swift @@ -29,6 +29,10 @@ struct MigrationViewControllerFactory { } } + func initialViewController() -> UIViewController? { + viewController(for: coordinator.currentStep) + } + private func makeAccount() -> WPAccount? { let context = ContextManager.shared.mainContext From 40be3486890f8d771cb07fdde70c34336683328e Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 11:09:29 -0600 Subject: [PATCH 31/35] Update MigrationNavigationController, set initial root from factory and drop first state change, since it already corresponds to the same initial vc --- .../Navigation/MigrationNavigationController.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift index 66c54585ebcd..ee334108bfb7 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationNavigationController.swift @@ -24,8 +24,8 @@ class MigrationNavigationController: UINavigationController { init(coordinator: MigrationFlowCoordinator, factory: MigrationViewControllerFactory) { self.coordinator = coordinator self.factory = factory - if let initialController = factory.viewController(for: .welcome) { - super.init(rootViewController: initialController) + if let initialViewController = factory.initialViewController() { + super.init(rootViewController: initialViewController) } else { super.init(nibName: nil, bundle: nil) } @@ -53,11 +53,12 @@ class MigrationNavigationController: UINavigationController { } private func listenForStateChanges() { - cancellable = coordinator.$currentStep.sink { [weak self] step in - DispatchQueue.main.async { + cancellable = coordinator.$currentStep + .dropFirst() + .receive(on: DispatchQueue.main) + .sink { [weak self] step in self?.updateStack(for: step) } - } } private func updateStack(for step: MigrationStep) { From 313c2031cb473adf1e4217df6a0837eb3d252265 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 11:13:02 -0600 Subject: [PATCH 32/35] Update MigrationFlowCoordinator, add comments --- .../Common/Navigation/MigrationFlowCoordinator.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift index b93a0679b90e..6bf3a0d8e589 100644 --- a/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift +++ b/WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Common/Navigation/MigrationFlowCoordinator.swift @@ -3,7 +3,9 @@ import UserNotifications /// Coordinator for the migration to jetpack flow final class MigrationFlowCoordinator: ObservableObject { - + // beware that changes won't be published on the main thread, + // so always make sure to return to the main thread for UI updates + // related to this property. @Published private(set) var currentStep = MigrationStep.welcome func transitionToNextStep() { From 5d9d95fa6a9324cad75a9a0665059bc612780345 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 11:49:43 -0600 Subject: [PATCH 33/35] Update JetpackWindowManager, small refactor --- .../Classes/System/JetpackWindowManager.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift index d70d8ee4db85..e0e62817a468 100644 --- a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift +++ b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift @@ -25,20 +25,20 @@ class JetpackWindowManager: WindowManager { private func showMigrationUI(_ blog: Blog?) { let container = MigrationDependencyContainer() - cancellable = container.migrationCoordinator.$currentStep.sink { [weak self] step in - guard step == .dismiss else { - return + cancellable = container.migrationCoordinator.$currentStep + .receive(on: DispatchQueue.main) + .sink { [weak self] step in + guard step == .dismiss else { + return + } + self?.switchToAppUI(for: blog) } - self?.switchToAppUI(for: blog) - } self.show(container.makeInitialViewController()) } private func switchToAppUI(for blog: Blog?) { cancellable = nil - DispatchQueue.main.async { [weak self] in - self?.showAppUI(for: blog) - } + self?.showAppUI(for: blog) } // TODO: Add logic in here to trigger migration UI if needed From 750bafa5bb92f51487f5d01d71a06bf37fe2842b Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 11:50:05 -0600 Subject: [PATCH 34/35] Update JetpackWindowManager, small refactor --- WordPress/Jetpack/Classes/System/JetpackWindowManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift index e0e62817a468..510388966881 100644 --- a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift +++ b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift @@ -38,7 +38,7 @@ class JetpackWindowManager: WindowManager { private func switchToAppUI(for blog: Blog?) { cancellable = nil - self?.showAppUI(for: blog) + showAppUI(for: blog) } // TODO: Add logic in here to trigger migration UI if needed From 670a52eeced9a9f4632486c16bf5bf9b40f99c65 Mon Sep 17 00:00:00 2001 From: Giorgio Ruscigno Date: Tue, 8 Nov 2022 15:41:33 -0600 Subject: [PATCH 35/35] Update JetpackWindowManager, disable migration UI --- WordPress/Jetpack/Classes/System/JetpackWindowManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift index 510388966881..ae05026d55bb 100644 --- a/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift +++ b/WordPress/Jetpack/Classes/System/JetpackWindowManager.swift @@ -43,6 +43,6 @@ class JetpackWindowManager: WindowManager { // TODO: Add logic in here to trigger migration UI if needed private var shouldShowMigrationUI: Bool { - true + false } }