WordPress to Jetpack flow: main flow implementation#19563
Conversation
…p-to-jp migration
…troller for wp-to-jp migration
…to-jp migration-notifications permissions step
…ation-notifications permissions step
…ration-final step
…migration flow, if needed
You can test the changes in Jetpack from this Pull Request by:
|
You can test the changes in WordPress from this Pull Request by:
|
…ler, add some comments
|
|
||
| func makeInitialViewController() -> UIViewController { | ||
| MigrationNavigationController(coordinator: migrationCoordinator, | ||
| migrationStack: [.welcome: makeWelcomeViewController(), |
There was a problem hiding this comment.
I'm not opposed to this approach of having a dictionary mapping MigrationStep to a UIViewController but I just want to point out that these view controllers will stay in memory even when they're dismissed ( not visible ).
Perhaps we can optimize this by injecting a closure like this:
let closure = { [weak self] (step: MigrationStep) -> UIViewController? in
switch step {
case .welcome: return self?.makeWelcomeViewController()
...
}
}There was a problem hiding this comment.
I like this idea: I added a factory that does exactly that, and we don't retain any unused vc in memory!
| import Combine | ||
|
|
||
| /// Coordinator for the migration to jetpack flow | ||
| final class MigrationFlowCoordinator: ObservableObject { |
There was a problem hiding this comment.
My understanding of Coordinator objects in the MVVM-C architecture is that they can instantiate and work with UIViewController objects ( e.g. this article and this ). That's why in the previous implementation, the coordinator was responsible for mapping a MigrationStep to a UIViewController and also pushing the view controllers to the navigation stack.
But I also like the idea of a UI-agnostic coordinator. But in this case, this object seems to me more of a ViewModel than a Coordinator. Maybe we should rename it to MigrationFlowViewModel?
What do you think?
There was a problem hiding this comment.
Thanks for the thoughtful design review and the following discussion we had on Slack! As discussed, we'll leave the current naming for now and re-consider it together with Tanner (avoid direct pinging on purpose 😄 ) when he comes back from the meetup!
| }, | ||
| secondaryHandler: { | ||
|
|
||
| })) |
There was a problem hiding this comment.
This is just a nice-to-have, but I honestly find this code a bit hard to read 🙈
Maybe we should breakdown this complex expression into multiple variables, something like this:
let headerConfig = MigrationHeaderConfiguration(step: .welcome, multiSite: blogListDataSource.visibleBlogsCount > 1)
let actionsConfig = MigrationActionsViewConfiguration(step: .welcome, primaryHandler:...)
configuration = MigrationStepConfiguration(headerConfiguration: headerConfig, actionsConfig: actionsConfig)There was a problem hiding this comment.
Totally agree. I did this in all view models
|
Thank you for the thorough review @salimbraksa !! |
… is always instantiated on the main thread
…ission screen if users have already decided
…ontrollers on the main thread
| migrationStack: [.welcome: makeWelcomeViewController(), | ||
| .notifications: makeNotificationsViewController(), | ||
| .done: makeDoneViewController()]) | ||
| factory: MigrationViewControllerFactory(coordinator: migrationCoordinator)) |
There was a problem hiding this comment.
I like this, it's better than passing a closure 👍
| self?.updateStack(for: step) | ||
| DispatchQueue.main.async { | ||
| self?.updateStack(for: step) | ||
| } |
There was a problem hiding this comment.
We can also use .receive(on:) if you prefer:
publisher
.receive(on: DispatchQueue.main)
.sink { value in
}Source: https://developer.apple.com/documentation/combine/fail/receive(on:options:)
| /// Coordinator for the migration to jetpack flow | ||
| final class MigrationFlowCoordinator: ObservableObject { | ||
|
|
||
| @Published private(set) var currentStep = MigrationStep.welcome |
There was a problem hiding this comment.
Perhaps we should add a documentation here mentioning that currentStep values are published in a background thread.
I'm pretty sure future developers can easily know this by reading the transitionToNextStep implementation details but it would be great to make finding about this detail extra easier.
Just realized there is a tiny UI glitch
|
@Gio2018 The latest changes look good to me and I actually went ahead and approved the PR but then I discovered there is a tiny UI glitch where the app appears black for a second before the Welcome Screen shows up. And I think the bug's root cause is: init(coordinator: MigrationFlowCoordinator, factory: MigrationViewControllerFactory) {
self.coordinator = coordinator
self.factory = factory
// `super.init(rootViewController:)` should be called for a smooth launch
super.init(nibName: nil, bundle: nil)
configure()
} |
… need to hold a reference to it
…ller to avoid initial glitch
Generated by 🚫 dangerJS |
good catch @salimbraksa ! I went ahead and changed the init to assign a root right away! |
…nd drop first state change, since it already corresponds to the same initial vc
|
@Gio2018 LGTM! 🚀 |

Ref #19517
Ref #19518
This PR implements the remaining wp-to-jp flow
NOTE: the UI is not finalized (text and images can be missing or wrong in the notifications and all done screens), nor optimized for landscape and multiple screens, the notifications permissions is not there yet, and the migration flow is shown by default at each launch. All these points will be addressed in separate PRs
To test:
Scenario A - Notifications permissions undetermined (user has not made a decision)
Case 1: skip notifications permission decision:
Case 2: skip notifications permission decision:
same as above, except on step 3, tap "Continue" and make sure the notifications permission alert shows up, then:
Scenario B - Notifications permissions determined (user has already made a decision)
Same as Scenario A - Case 1, except step 3 is missing: after tapping Continue in the welcome screen, make sure the all done screen appears. After that, continue normally with step 4
Regression Notes
Potential unintended areas of impact
None other the migration itself
What I did to test those areas of impact (or what existing automated tests I relied on)
What automated tests I added (or what prevented me from doing so)
PR submission checklist:
I have considered if this change warrants user-facing release notes and have added them toNot releasedRELEASE-NOTES.txtif necessary.