-
Notifications
You must be signed in to change notification settings - Fork 969
[Draft] Update 3x pixel-firing logic to more closely match broken site prompt #5862
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
base: develop
Are you sure you want to change the base?
Conversation
app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt
Outdated
Show resolved
Hide resolved
@laghee, If I understand correctly, the logic to reset refresh count is not affected (reset once 3x or more refreshes), however, if the user refreshes 4x, we'd only send the 2x once. Not sure if that's expected / what iOS does in that case |
app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt
Outdated
Show resolved
Hide resolved
} | ||
pixel.fire(AppPixelName.RELOAD_THREE_TIMES_WITHIN_20_SECONDS) | ||
Timber.d("KateTest--> should show bc 3 refreshes") | ||
site?.let { brokenSitePrompt.shouldShowBrokenSitePrompt(it.url) } ?: 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.
I guess null site here is an edge case here, so probably fine if pixel and prompt fall out of sync
} | ||
|
||
val dismissStreakResetDays = brokenSiteReportRepository.getDismissStreakResetDays().toLong() | ||
val dismissalCount = brokenSiteReportRepository.getDismissalCountBetween( | ||
currentTimestamp.minusDays(dismissStreakResetDays), | ||
currentTimestamp.minusMinutes(dismissStreakResetDays), |
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.
Careful to revert this later
|
||
return dismissalCount < brokenSiteReportRepository.getMaxDismissStreak() | ||
} | ||
|
||
override suspend fun ctaShown() { | ||
val currentTimestamp = currentTimeProvider.localDateTimeNow() | ||
val newNextShownDate = currentTimestamp.plusDays(brokenSiteReportRepository.getCoolDownDays()) | ||
val newNextShownDate = currentTimestamp.plusSeconds(brokenSiteReportRepository.getCoolDownDays()) |
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.
Same
@@ -3946,6 +3952,31 @@ class BrowserTabViewModel @Inject constructor( | |||
newTabPixels.get().fireNewTabDisplayed() | |||
} | |||
|
|||
private suspend fun shouldPromptForBrokenSiteReport(): Boolean { |
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.
From the method name, it's not obvious what it does
app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt
Outdated
Show resolved
Hide resolved
@@ -468,6 +469,7 @@ class BrowserTabViewModel @Inject constructor( | |||
private val defaultBrowserPromptsExperiment: DefaultBrowserPromptsExperiment, | |||
private val swipingTabsFeature: SwipingTabsFeatureProvider, | |||
private val visualDesignExperimentDataStore: VisualDesignExperimentDataStore, | |||
private val blockListPixelsPlugin: BlockListPixelsPlugin, |
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.
Don't think this is needed anymore
pixel.fire(CustomTabPixelNames.CUSTOM_TABS_MENU_REFRESH) | ||
} | ||
|
||
private fun sendTimeBasedPixels() { | ||
override fun sendBreakageRefreshPixels(patternsDetected: Set<Int>) { |
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 would call this method something like onRefreshPatternDetected
, the fact that internally we send a pixel or do something else is irrelevant to the caller so I wouldn't be that specific.
@@ -3946,6 +3950,16 @@ class BrowserTabViewModel @Inject constructor( | |||
newTabPixels.get().fireNewTabDisplayed() | |||
} | |||
|
|||
private suspend fun shouldShowPromptForBrokenSiteReport(): Boolean { |
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.
This method is called right before refreshCta
and the value it sends is used in the CtaViewModel
so why not doing it there instead?
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.
That's a good point. I originally moved it to avoid losing the context for the user refreshes and resetting the count too often, but now that the logic's been altered, that's probably no longer necessary.
val cta = withContext(dispatchers.io()) { | ||
ctaViewModel.refreshCta( | ||
dispatchers.io(), | ||
isBrowserShowing && !isErrorShowing, | ||
siteLiveData.value, | ||
showBrokenSitePrompt, |
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.
Overall I'm struggling with this. I don't fully get why we have pull this out of the CtaViewModel
to pass a boolean back to it when within the CtaViewModel
we still have access to the BrokenSitePrompt
. It seems an unnecessary journey for a value that we can directly get when needed in the CtaViewModel
|
||
blockListPixelsPlugin.get2XRefresh()!!.getPixelDefinitions().forEach { | ||
blockListPixelsPlugin.get2XRefresh()?.getPixelDefinitions()?.forEach { |
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.
Go back to !!
I want this test to fail if get2Refresh
returns null and this would bypass it.
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.
Whoops, unintentional
|
||
blockListPixelsPlugin.get3XRefresh()!!.getPixelDefinitions().forEach { | ||
blockListPixelsPlugin.get3XRefresh()?.getPixelDefinitions()?.forEach { |
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.
Same as above
@@ -143,181 +115,28 @@ class RefreshPixelSenderTest { | |||
} | |||
|
|||
@Test | |||
fun whenSendMenuRefreshPixelsThenTimeBasedPixelsFired() = runTest { |
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.
Overall a lot of tests have been deleted, are the others covering for the new logic, pixels, etc?
|
||
companion object { | ||
private const val TWICE_REFRESH = 2 | ||
private const val TWICE_REFRESH_WINDOW = 12L |
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.
Is this 12 seconds? minutes? Would change the const to TWICE_REFRESH_WINDOW_IN_SECS
or whatever the right thing is. Same for thrice.
@@ -59,15 +59,15 @@ interface BrokenSiteReportRepository { | |||
|
|||
fun resetRefreshCount() | |||
fun addRefresh(url: Uri, localDateTime: LocalDateTime) | |||
fun getAndUpdateUserRefreshesBetween(t1: LocalDateTime, t2: LocalDateTime): Int | |||
fun checkForRefreshPatterns(currentDateTime: LocalDateTime): Set<Int> |
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.
Would probably rename to getRefreshPatterns
rather than check. Check doesn't tell me what is the thing that is checking so a bit confusing. Also, this returns the refresh patterns but they are not associated to any URL so how do you know it's relevant for the current site?
Task/Issue URL: https://app.asana.com/0/72649045549333/1209712075249435/f
Description
We decided in https://app.asana.com/0/1205142657210376/1209698956036733 that we would prefer the separate 3x pixel to fire for distinct 3-refresh groupings in the chosen time period as opposed to 3 refreshes that fall into a sliding window of time to more closely match the breakage prompt trigger.
Steps to test this PR
NB: Logic is currently patched to delay 7 seconds between accepted prompts & stop prompting with 3+ dismissals within the past 30 min.
Feature 1