Bug 1831068 - Incorporate Nimbus experiment 'lifestyle image' resources

fenix/115.2.0
t-p-white 1 year ago committed by mergify[bot]
parent 5af6180068
commit 481894e950

@ -81,6 +81,10 @@ objects:
description: The resource id of the image to be displayed.
# This should never be defaulted.
default: ic_onboarding_welcome
image-is-illustration:
type: Boolean
description: True if the image type is an illustration.
default: true
ordering:
type: Int
description: Used to sequence the cards.

@ -1,5 +1,6 @@
package org.mozilla.fenix.onboarding.view
import androidx.compose.ui.layout.ContentScale
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
@ -31,6 +32,7 @@ class JunoOnboardingMapperTest {
private val defaultBrowserPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.DEFAULT_BROWSER,
imageRes = R.drawable.ic_onboarding_welcome,
imageResContentScale = ContentScale.Fit,
title = "default browser title",
description = "default browser body with link text",
linkText = "link text",
@ -40,6 +42,7 @@ private val defaultBrowserPageUiData = OnboardingPageUiData(
private val syncPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.SYNC_SIGN_IN,
imageRes = R.drawable.ic_onboarding_sync,
imageResContentScale = ContentScale.Fit,
title = "sync title",
description = "sync body",
primaryButtonLabel = "sync primary button text",
@ -48,6 +51,7 @@ private val syncPageUiData = OnboardingPageUiData(
private val notificationPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.NOTIFICATION_PERMISSION,
imageRes = R.drawable.ic_notification_permission,
imageResContentScale = ContentScale.Crop,
title = "notification title",
description = "notification body",
primaryButtonLabel = "notification primary button text",
@ -57,6 +61,7 @@ private val notificationPageUiData = OnboardingPageUiData(
private val defaultBrowserCardData = OnboardingCardData(
cardType = OnboardingCardType.DEFAULT_BROWSER,
imageRes = R.drawable.ic_onboarding_welcome,
imageIsIllustration = true,
title = StringHolder(null, "default browser title"),
body = StringHolder(null, "default browser body with link text"),
linkText = StringHolder(null, "link text"),
@ -67,6 +72,7 @@ private val defaultBrowserCardData = OnboardingCardData(
private val syncCardData = OnboardingCardData(
cardType = OnboardingCardType.SYNC_SIGN_IN,
imageRes = R.drawable.ic_onboarding_sync,
imageIsIllustration = true,
title = StringHolder(null, "sync title"),
body = StringHolder(null, "sync body"),
primaryButtonLabel = StringHolder(null, "sync primary button text"),
@ -76,6 +82,7 @@ private val syncCardData = OnboardingCardData(
private val notificationCardData = OnboardingCardData(
cardType = OnboardingCardType.NOTIFICATION_PERMISSION,
imageRes = R.drawable.ic_notification_permission,
imageIsIllustration = false,
title = StringHolder(null, "notification title"),
body = StringHolder(null, "notification body"),
primaryButtonLabel = StringHolder(null, "notification primary button text"),

@ -82,3 +82,21 @@ fun Modifier.debouncedClickable(
),
)
}
/**
* A conditional [Modifier.then] extension that allows chaining of conditional Modifiers.
*
* @param modifier The [Modifier] to return if the [predicate] is satisfied.
* @param predicate The predicate used to determine which [Modifier] to return.
*
* @return the appropriate [Modifier] given the [predicate].
*/
fun Modifier.thenConditional(
modifier: Modifier,
predicate: () -> Boolean,
): Modifier =
if (predicate()) {
then(modifier)
} else {
this
}

@ -4,6 +4,7 @@
package org.mozilla.fenix.onboarding.view
import androidx.compose.ui.layout.ContentScale
import org.mozilla.fenix.nimbus.OnboardingCardData
import org.mozilla.fenix.nimbus.OnboardingCardType
import org.mozilla.fenix.settings.SupportUtils
@ -24,6 +25,7 @@ internal fun Collection<OnboardingCardData>.toPageUiData(showNotificationPage: B
private fun OnboardingCardData.toPageUiData() = OnboardingPageUiData(
type = cardType.toPageUiDataType(),
imageRes = imageRes.resourceId,
imageResContentScale = imageIsIllustration.toContentScale(),
title = title,
description = body,
linkText = linkText,
@ -31,6 +33,12 @@ private fun OnboardingCardData.toPageUiData() = OnboardingPageUiData(
secondaryButtonLabel = secondaryButtonLabel,
)
private fun Boolean.toContentScale() = if (this) {
ContentScale.Fit
} else {
ContentScale.Crop
}
private fun OnboardingCardType.toPageUiDataType() = when (this) {
OnboardingCardType.DEFAULT_BROWSER -> OnboardingPageUiData.Type.DEFAULT_BROWSER
OnboardingCardType.SYNC_SIGN_IN -> OnboardingPageUiData.Type.SYNC_SIGN_IN

@ -28,6 +28,7 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
@ -173,7 +174,10 @@ private fun JunoOnboardingContent(
onNotificationPermissionButtonClick = onNotificationPermissionButtonClick,
onNotificationPermissionSkipClick = onNotificationPermissionSkipClick,
)
OnboardingPage(pageState = onboardingPageState)
OnboardingPage(
pageState = onboardingPageState,
imageResContentScale = pageUiState.imageResContentScale,
)
}
PagerIndicator(
@ -233,6 +237,7 @@ private fun defaultPreviewPages() = listOf(
OnboardingPageUiData(
type = OnboardingPageUiData.Type.DEFAULT_BROWSER,
imageRes = R.drawable.ic_onboarding_welcome,
imageResContentScale = ContentScale.Fit,
title = stringResource(R.string.juno_onboarding_default_browser_title_nimbus),
description = stringResource(R.string.juno_onboarding_default_browser_description_nimbus),
linkText = stringResource(R.string.juno_onboarding_default_browser_description_link_text),
@ -242,6 +247,7 @@ private fun defaultPreviewPages() = listOf(
OnboardingPageUiData(
type = OnboardingPageUiData.Type.SYNC_SIGN_IN,
imageRes = R.drawable.ic_onboarding_sync,
imageResContentScale = ContentScale.Fit,
title = stringResource(R.string.juno_onboarding_sign_in_title),
description = stringResource(R.string.juno_onboarding_sign_in_description),
primaryButtonLabel = stringResource(R.string.juno_onboarding_sign_in_positive_button),
@ -250,6 +256,7 @@ private fun defaultPreviewPages() = listOf(
OnboardingPageUiData(
type = OnboardingPageUiData.Type.NOTIFICATION_PERMISSION,
imageRes = R.drawable.ic_notification_permission,
imageResContentScale = ContentScale.Fit,
title = stringResource(R.string.juno_onboarding_enable_notifications_title_nimbus),
description = stringResource(R.string.juno_onboarding_enable_notifications_description_nimbus),
primaryButtonLabel = stringResource(R.string.juno_onboarding_enable_notifications_positive_button),

@ -19,11 +19,14 @@ import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
@ -36,6 +39,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.button.PrimaryButton
import org.mozilla.fenix.compose.button.SecondaryButton
import org.mozilla.fenix.compose.ext.thenConditional
import org.mozilla.fenix.theme.FirefoxTheme
/**
@ -66,12 +70,15 @@ private const val URL_TAG = "URL_TAG"
* @param modifier The modifier to be applied to the Composable.
* @param onDismiss Invoked when the user clicks the close button. This defaults to null. When null,
* it doesn't show the close button.
* @param imageResContentScale The [ContentScale] for the [OnboardingPageState.image].
*/
@Composable
@Suppress("LongMethod")
fun OnboardingPage(
pageState: OnboardingPageState,
modifier: Modifier = Modifier,
onDismiss: (() -> Unit)? = null,
imageResContentScale: ContentScale = ContentScale.Fit,
) {
BoxWithConstraints(
modifier = Modifier
@ -109,7 +116,12 @@ fun OnboardingPage(
Image(
painter = painterResource(id = pageState.image),
contentDescription = null,
modifier = Modifier.height(imageHeight(boxWithConstraintsScope)),
contentScale = imageResContentScale,
modifier = Modifier
.height(imageHeight(boxWithConstraintsScope))
.thenConditional(Modifier.clip(MaterialTheme.shapes.medium)) {
imageResContentScale == ContentScale.Crop
},
)
Spacer(modifier = Modifier.height(32.dp))

@ -5,6 +5,7 @@
package org.mozilla.fenix.onboarding.view
import androidx.annotation.DrawableRes
import androidx.compose.ui.layout.ContentScale
import org.mozilla.fenix.nimbus.OnboardingCardData
/**
@ -13,6 +14,7 @@ import org.mozilla.fenix.nimbus.OnboardingCardData
data class OnboardingPageUiData(
val type: Type,
@DrawableRes val imageRes: Int,
val imageResContentScale: ContentScale,
val title: String,
val description: String,
val linkText: String? = null,

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/onboarding_default_browser,@drawable/onboarding_sync,@drawable/onboarding_notification" />

@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.compose.ext
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.junit.Assert.assertEquals
import org.junit.Test
class ModifierTest {
@Test
fun `GIVEN predicate is false WHEN thenConditional called THEN the original modifier is returned`() {
val modifier = Modifier.height(1.dp)
assertEquals(modifier, modifier.thenConditional(Modifier.width(1.dp)) { false })
}
@Test
fun `GIVEN predicate is true WHEN thenConditional called THEN the updated modifier is returned`() {
val modifier = Modifier.height(1.dp)
val expected = Modifier
.height(1.dp)
.width(1.dp)
val actual = modifier.thenConditional(Modifier.width(1.dp)) { true }
assertEquals(expected, actual)
}
}

@ -4,6 +4,7 @@
package org.mozilla.fenix.onboarding.view
import androidx.compose.ui.layout.ContentScale
import org.junit.Assert.assertEquals
import org.junit.Test
import org.mozilla.fenix.R
@ -29,6 +30,7 @@ class JunoOnboardingMapperTest {
val onboardingPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.DEFAULT_BROWSER,
imageRes = R.drawable.ic_onboarding_welcome,
imageResContentScale = ContentScale.Fit,
title = "default browser title",
description = "default browser body with link text",
linkText = "link text",
@ -62,6 +64,7 @@ class JunoOnboardingMapperTest {
val onboardingPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.SYNC_SIGN_IN,
imageRes = R.drawable.ic_onboarding_sync,
imageResContentScale = ContentScale.Fit,
title = "sync title",
description = "sync body",
linkText = null,
@ -95,6 +98,7 @@ class JunoOnboardingMapperTest {
val onboardingPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.NOTIFICATION_PERMISSION,
imageRes = R.drawable.ic_notification_permission,
imageResContentScale = ContentScale.Fit,
title = "notification title",
description = "notification body",
linkText = null,

@ -4,6 +4,7 @@
package org.mozilla.fenix.onboarding.view
import androidx.compose.ui.layout.ContentScale
import org.junit.Assert.assertEquals
import org.junit.Test
import org.mozilla.fenix.R
@ -54,6 +55,7 @@ class OnboardingPageUiDataTest {
private val defaultBrowserPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.DEFAULT_BROWSER,
imageRes = R.drawable.ic_onboarding_welcome,
imageResContentScale = ContentScale.Fit,
title = "default browser title",
description = "default browser body with link text",
linkText = "link text",
@ -64,6 +66,7 @@ private val defaultBrowserPageUiData = OnboardingPageUiData(
private val syncPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.SYNC_SIGN_IN,
imageRes = R.drawable.ic_onboarding_sync,
imageResContentScale = ContentScale.Fit,
title = "sync title",
description = "sync body",
primaryButtonLabel = "sync primary button text",
@ -73,6 +76,7 @@ private val syncPageUiData = OnboardingPageUiData(
private val notificationPageUiData = OnboardingPageUiData(
type = OnboardingPageUiData.Type.NOTIFICATION_PERMISSION,
imageRes = R.drawable.ic_notification_permission,
imageResContentScale = ContentScale.Fit,
title = "notification title",
description = "notification body",
primaryButtonLabel = "notification primary button text",

Loading…
Cancel
Save