-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MOB-2759] Onboarding card NTP Experiment #778
Conversation
PR Reviewer Guide 🔍(Review updated until commit 18e7623)
|
PR Code Suggestions ✨
|
// TODO: Refactor `FeatureManagement.fetchConfiguration()` pre-condition - maybe a notification from FeatureManagement? | ||
Task { | ||
await FeatureManagement.fetchConfiguration() | ||
DispatchQueue.main.async { [weak self] in | ||
guard let self = self else { return } | ||
guard !OnboardingCardNTPExperiment.isEnabled else { | ||
self.parentCoordinator?.didFinishLaunch(from: self) | ||
return | ||
} | ||
self.presentIntroOnboarding(with: manager, isFullScreen: isFullScreen) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now this is working, but I don't think it looks great as it refreshes Unleash one extra time and mixes two concurrency patterns.
Maybe this could be some sort of Notification sent by FeatureManagement
whenever it is finished so that places in the code that depend on it can use to make sure it is initialised.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to think about it thoroughly. For the time being, given the experiment context, I thought about leaving it as is. As a next step, I made a DRAFT RFC in our Confluence page that will be document with a proposed solution for us to comment on and eventually apply.
@@ -58,7 +58,7 @@ extension NTPBookmarkNudgeCellViewModel: HomepageViewModelProtocol { | |||
} | |||
|
|||
var isEnabled: Bool { | |||
User.shared.showsBookmarksNTPNudgeCard() | |||
User.shared.showsBookmarksNTPNudgeCard() // TODO: Check why this logic is broken (`firstTime` false the first time it's executed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this might be related with the change asynchronous code to present onboarding, but bookmarks nudge card logic is broken since when it gets here the first time firstTime
is already false for the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue here is not encountered, especially after the latest changes performed.
let item = NSCollectionLayoutItem(layoutSize: itemSize) | ||
|
||
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), | ||
heightDimension: .estimated(128)) // TODO: Make cell automatically size it's height |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Struggled a bit to make it resize it's height automatically, even setting up all constraints. Must be missing something but did not have the proper time to debug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved ✅ . Adding this comment to track it 👍 . The issue was the right .estimated()
dimension to assign to both the item and the group.
// OnboardingCardNTPExperiment.shouldShowCard | ||
true // TODO: Why is there a `UICollectionViewCompositionalLayout` whenever this is false? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved ✅ . The root cause was essentially the order by which the viewModel
s in the HomepageViewController
where defined. Added a supporting comment as well.
3fb9d4d
to
c566aa7
Compare
Assuming all cards will be shown at the top
ce631bb
to
ac9ab67
Compare
Better handling of show/hide as well as minor cosmetic fixes
Persistent review updated to latest commit 18e7623 |
PR Code Suggestions ✨
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! ✨
No red flags, but tbh I am not entirely happy about the nested async call to Unleash. Maybe you find a clever way on bundling this with an overall start-up routine, because I assume this functionality is there to stay (e.g. controlling what's shown on first start via a flag)
I also added a few minor comments for wording, no blockers
@@ -279,9 +279,10 @@ class BrowserCoordinator: BaseCoordinator, | |||
browserViewController.presentIntroViewController() | |||
} | |||
|
|||
private func showIntroOnboarding() { | |||
// Ecosia: Add `forceSkipExperiment` - used for `OnboardingCardNTPExperiment` | |||
private func showIntroOnboarding(forceSkipExperiment: Bool = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a minor comment: skipExperiment
already says what the method should do, no real reason to use force
, or is there? ⚔️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The real reason behind it. I guess it was added mostly to advocate the imperative instruction. Can update 👍
} | ||
// TODO: Refactor `FeatureManagement.fetchConfiguration()` pre-condition - maybe a notification from FeatureManagement? | ||
Task { | ||
await FeatureManagement.fetchConfiguration() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering, what's seen on screen while this is being executed? Slightly relates to Luca's comment from line 52, but I would expect that at this point we have fetched the Unleash configuration already, so that we can make a synchronous decision.
Don't we still have a LoadingScreen that's used when we get an invite code? We could bundle all async start up tasks there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with all the above and YES, it does require a refactor as we are all far from being happy about it 😅 .
When I was shown that, it already sparked some thoughts about a possible refactor immediately but then, eventually, I decided to leave it as is to speed up the data gathering.
I replied to Luca's handover comment about that, deciding eventually to leave it as is.
I tackled next steps already, creating a DRAFT RFC where I'm collecting info regarding the improvement.
If you are OK with that too, I would be more than happy to present some of the improvements I thought about when will publish the RFC.
@@ -306,7 +313,7 @@ final class Analytics: AnalyticsProtocol { | |||
guard let page else { | |||
return | |||
} | |||
let event = Structured(category: Category.intro.rawValue, | |||
let event = Structured(category: OnboardingCardNTPExperiment.analyticsIntroCategory ?? Category.intro.rawValue, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matter of taste, but I am not really fond of this hidden fallback logic which relies on explicit knowledge in an allegedly agnostic function. Maybe we can have category
a function parameter, but with .intro
as default value. Then the caller has to decide explicitly which category to use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with that. I believe that was added for the simplicity of the experiment.
Will go ahead and merge it as approved already. My comments were supporting comments, alongside a single one tackled 👍 |
MOB-2759
Context
We want to experiment how enabling the users to have a self-paced onboarding affects retention.
Approach
Create an Experiment as usual, combined with a new Homepage cell and adjustments to the onboarding and it's flow as required by the acceptance criteria.
Before merging
Checklist
// Ecosia:
helper comments where needed