Bug 1821726 - Part 1: Prepare for adding juno onboarding telemetry

fenix/113.0
rahulsainani 1 year ago committed by mergify[bot]
parent f94e6b241d
commit f108eb7a1e

@ -19,33 +19,26 @@ import org.mozilla.fenix.settings.SupportUtils
@Suppress("LongParameterList")
internal fun mapToOnboardingPageState(
onboardingPageType: JunoOnboardingPageType,
scrollToNextPageOrDismiss: () -> Unit,
onMakeFirefoxDefaultClick: () -> Unit,
onMakeFirefoxDefaultSkipClick: () -> Unit,
onPrivacyPolicyClick: (String) -> Unit,
onSignInButtonClick: () -> Unit,
onSignInSkipClick: () -> Unit,
onNotificationPermissionButtonClick: () -> Unit,
onNotificationPermissionSkipClick: () -> Unit,
): OnboardingPageState = when (onboardingPageType) {
JunoOnboardingPageType.DEFAULT_BROWSER -> defaultBrowserPageState(
onPositiveButtonClick = {
onMakeFirefoxDefaultClick()
scrollToNextPageOrDismiss()
},
onNegativeButtonClick = scrollToNextPageOrDismiss,
onPositiveButtonClick = onMakeFirefoxDefaultClick,
onNegativeButtonClick = onMakeFirefoxDefaultSkipClick,
onUrlClick = onPrivacyPolicyClick,
)
JunoOnboardingPageType.SYNC_SIGN_IN -> syncSignInPageState(
onPositiveButtonClick = {
onSignInButtonClick()
scrollToNextPageOrDismiss()
},
onNegativeButtonClick = scrollToNextPageOrDismiss,
onPositiveButtonClick = onSignInButtonClick,
onNegativeButtonClick = onSignInSkipClick,
)
JunoOnboardingPageType.NOTIFICATION_PERMISSION -> notificationPermissionPageState(
onPositiveButtonClick = {
onNotificationPermissionButtonClick()
scrollToNextPageOrDismiss()
},
onNegativeButtonClick = scrollToNextPageOrDismiss,
onPositiveButtonClick = onNotificationPermissionButtonClick,
onNegativeButtonClick = onNotificationPermissionSkipClick,
)
}

@ -6,9 +6,31 @@ package org.mozilla.fenix.onboarding.view
/**
* Model for different types of Onboarding Pages.
* @param sequencePosition Position of the page in the onboarding flow, used in telemetry.
* @param id Identifier for the page, used in telemetry.
*/
enum class JunoOnboardingPageType {
DEFAULT_BROWSER,
SYNC_SIGN_IN,
NOTIFICATION_PERMISSION,
enum class JunoOnboardingPageType(
val sequencePosition: String,
val id: String,
) {
DEFAULT_BROWSER(
sequencePosition = "1",
id = "default",
),
SYNC_SIGN_IN(
sequencePosition = "2",
id = "sync",
),
NOTIFICATION_PERMISSION(
sequencePosition = "3",
id = "notification",
),
}
/**
* Helper function for telemetry that maps List<JunoOnboardingPageType> to a string of page names
* separated by an underscore.
* e.g. [DEFAULT_BROWSER, SYNC_SIGN_IN] will be mapped to "default_sync".
*/
fun List<JunoOnboardingPageType>.telemetrySequenceId(): String =
joinToString(separator = "_") { it.id }

@ -15,6 +15,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@ -32,30 +33,34 @@ import org.mozilla.fenix.compose.PagerIndicator
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.theme.FirefoxTheme
private val OnboardingPageTypeList = listOf(
JunoOnboardingPageType.DEFAULT_BROWSER,
JunoOnboardingPageType.NOTIFICATION_PERMISSION,
JunoOnboardingPageType.SYNC_SIGN_IN,
)
/**
* A screen for displaying juno onboarding.
*
* @param onMakeFirefoxDefaultClick Invoked when the positive button on default browser page is
* clicked.
* @param onboardingPageTypeList List of pages to be displayed in onboarding pager ui.
* @param onMakeFirefoxDefaultClick Invoked when positive button on default browser page is clicked.
* @param onSkipDefaultClick Invoked when negative button on default browser page is clicked.
* @param onPrivacyPolicyClick Invoked when the privacy policy link text is clicked.
* @param onSignInButtonClick Invoked when the positive button on the sign in page is clicked.
* @param onNotificationPermissionButtonClick Invoked when the positive button on notification
* page is clicked.
* @param onSkipSignInClick Invoked when the negative button on the sign in page is clicked.
* @param onNotificationPermissionButtonClick Invoked when positive button on notification page is
* clicked.
* @param onSkipNotificationClick Invoked when negative button on notification page is clicked.
* @param onFinish Invoked when the onboarding is completed.
* @param onImpression Invoked when a page in the pager is displayed.
*/
@Composable
@Suppress("LongParameterList")
fun JunoOnboardingScreen(
onboardingPageTypeList: List<JunoOnboardingPageType>,
onMakeFirefoxDefaultClick: () -> Unit,
onPrivacyPolicyClick: (String) -> Unit,
onSkipDefaultClick: () -> Unit = {},
onPrivacyPolicyClick: (url: String) -> Unit,
onSignInButtonClick: () -> Unit,
onSkipSignInClick: () -> Unit = {},
onNotificationPermissionButtonClick: () -> Unit,
onSkipNotificationClick: () -> Unit = {},
onFinish: () -> Unit,
onImpression: (pageType: JunoOnboardingPageType) -> Unit = {},
) {
val coroutineScope = rememberCoroutineScope()
val pagerState = rememberPagerState()
@ -84,25 +89,57 @@ fun JunoOnboardingScreen(
}
}
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.currentPage }.collect { page ->
onImpression(onboardingPageTypeList[page])
}
}
JunoOnboardingContent(
onboardingPageTypeList = onboardingPageTypeList,
pagerState = pagerState,
scrollToNextPageOrDismiss = scrollToNextPageOrDismiss,
onMakeFirefoxDefaultClick = onMakeFirefoxDefaultClick,
onPrivacyPolicyClick = onPrivacyPolicyClick,
onSignInButtonClick = onSignInButtonClick,
onNotificationPermissionButtonClick = onNotificationPermissionButtonClick,
onMakeFirefoxDefaultClick = {
scrollToNextPageOrDismiss()
onMakeFirefoxDefaultClick()
},
onMakeFirefoxDefaultSkipClick = {
scrollToNextPageOrDismiss()
onSkipDefaultClick()
},
onPrivacyPolicyClick = {
onPrivacyPolicyClick(it)
},
onSignInButtonClick = {
onSignInButtonClick()
scrollToNextPageOrDismiss()
},
onSignInSkipClick = {
scrollToNextPageOrDismiss()
onSkipSignInClick()
},
onNotificationPermissionButtonClick = {
scrollToNextPageOrDismiss()
onNotificationPermissionButtonClick()
},
onNotificationPermissionSkipClick = {
scrollToNextPageOrDismiss()
onSkipNotificationClick()
},
)
}
@Composable
@Suppress("LongParameterList")
private fun JunoOnboardingContent(
onboardingPageTypeList: List<JunoOnboardingPageType>,
pagerState: PagerState,
scrollToNextPageOrDismiss: () -> Unit,
onMakeFirefoxDefaultClick: () -> Unit,
onMakeFirefoxDefaultSkipClick: () -> Unit,
onPrivacyPolicyClick: (String) -> Unit,
onSignInButtonClick: () -> Unit,
onSignInSkipClick: () -> Unit,
onNotificationPermissionButtonClick: () -> Unit,
onNotificationPermissionSkipClick: () -> Unit,
) {
val nestedScrollConnection = remember { DisableForwardSwipeNestedScrollConnection(pagerState) }
@ -113,21 +150,23 @@ private fun JunoOnboardingContent(
.navigationBarsPadding(),
) {
HorizontalPager(
count = OnboardingPageTypeList.size,
count = onboardingPageTypeList.size,
state = pagerState,
key = { OnboardingPageTypeList[it] },
key = { onboardingPageTypeList[it] },
modifier = Modifier
.weight(1f)
.nestedScroll(nestedScrollConnection),
) { pageIndex ->
val onboardingPageType = OnboardingPageTypeList[pageIndex]
val onboardingPageType = onboardingPageTypeList[pageIndex]
val pageState = mapToOnboardingPageState(
onboardingPageType = onboardingPageType,
scrollToNextPageOrDismiss = scrollToNextPageOrDismiss,
onMakeFirefoxDefaultClick = onMakeFirefoxDefaultClick,
onMakeFirefoxDefaultSkipClick = onMakeFirefoxDefaultSkipClick,
onPrivacyPolicyClick = onPrivacyPolicyClick,
onSignInButtonClick = onSignInButtonClick,
onSignInSkipClick = onSignInSkipClick,
onNotificationPermissionButtonClick = onNotificationPermissionButtonClick,
onNotificationPermissionSkipClick = onNotificationPermissionSkipClick,
)
OnboardingPage(pageState = pageState)
}
@ -171,12 +210,19 @@ private class DisableForwardSwipeNestedScrollConnection(
private fun JunoOnboardingScreenPreview() {
FirefoxTheme {
JunoOnboardingContent(
onboardingPageTypeList = listOf(
JunoOnboardingPageType.DEFAULT_BROWSER,
JunoOnboardingPageType.SYNC_SIGN_IN,
JunoOnboardingPageType.NOTIFICATION_PERMISSION,
),
pagerState = PagerState(0),
onMakeFirefoxDefaultClick = {},
onMakeFirefoxDefaultSkipClick = {},
onPrivacyPolicyClick = {},
onSignInButtonClick = {},
onSignInSkipClick = {},
onNotificationPermissionButtonClick = {},
scrollToNextPageOrDismiss = {},
onNotificationPermissionSkipClick = {},
)
}
}

@ -0,0 +1,44 @@
package org.mozilla.fenix.onboarding.view
import org.junit.Assert.assertEquals
import org.junit.Test
class JunoOnboardingPageTypeTest {
@Test
fun `GIVEN a list of JunoOnboardingPageType sequenceId() should map to the correct sequence id - 1`() {
val list = listOf(
JunoOnboardingPageType.DEFAULT_BROWSER,
JunoOnboardingPageType.SYNC_SIGN_IN,
JunoOnboardingPageType.NOTIFICATION_PERMISSION,
)
val expected = "default_sync_notification"
val actual = list.telemetrySequenceId()
assertEquals(expected, actual)
}
@Test
fun `GIVEN a list of JunoOnboardingPageType sequenceId() should map to the correct sequence id - 2`() {
val list = listOf(
JunoOnboardingPageType.DEFAULT_BROWSER,
JunoOnboardingPageType.SYNC_SIGN_IN,
)
val expected = "default_sync"
val actual = list.telemetrySequenceId()
assertEquals(expected, actual)
}
@Test
fun `GIVEN a list of JunoOnboardingPageType sequenceId() should map to the correct sequence id - 3`() {
val list = listOf(JunoOnboardingPageType.DEFAULT_BROWSER)
val expected = "default"
val actual = list.telemetrySequenceId()
assertEquals(expected, actual)
}
}
Loading…
Cancel
Save