tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 4494dbcf540bfe146e07d21d4d21179c892115d8
parent 78bb0dc552f20c0e49ef74c98c172a9107b966fe
Author: John Oberhauser <j.git-global@obez.io>
Date:   Tue,  9 Dec 2025 06:25:19 +0000

Bug 2003325 - Part 2: Refactoring MessageCard to use the new Banner base compose component r=android-reviewers,devota,mavduevskiy

Differential Revision: https://phabricator.services.mozilla.com/D274816

Diffstat:
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt | 291++++++++++++++++++++++---------------------------------------------------------
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/fake/FakeHomepagePreview.kt | 4++--
2 files changed, 84 insertions(+), 211 deletions(-)

diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/compose/MessageCard.kt @@ -6,39 +6,23 @@ package org.mozilla.fenix.compose import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import mozilla.components.compose.base.button.FilledButton +import mozilla.components.compose.base.Banner +import mozilla.components.compose.base.BannerColors import mozilla.components.service.nimbus.messaging.Message import org.mozilla.fenix.R import org.mozilla.fenix.home.fake.FakeHomepagePreview import org.mozilla.fenix.theme.FirefoxTheme -import org.mozilla.fenix.wallpapers.Wallpaper +import org.mozilla.fenix.theme.Theme import org.mozilla.fenix.wallpapers.WallpaperState -import mozilla.components.ui.icons.R as iconsR /** * State-based Message Card. @@ -56,183 +40,53 @@ fun MessageCard( onCloseButtonClick: () -> Unit = {}, ) { with(messageCardState) { - MessageCard( + Banner( messageText = messageText, - modifier = modifier, - titleText = titleText, - buttonText = buttonText, - messageColors = messageColors, - onClick = onClick, - onCloseButtonClick = onCloseButtonClick, - ) - } -} - -/** - * Message Card. - * - * @param messageText The message card's body text to be displayed. - * @param modifier Modifier to be applied to the card. - * @param titleText An optional title of message card. If the provided title text is blank or null, - * the title will not be shown. - * @param buttonText An optional button text of the message card. If the provided button text is blank or null, - * the button won't be shown. - * @param messageColors The color set defined by [MessageCardColors] used to style the message card. - * @param onClick Invoked when user clicks on the message card. - * @param onCloseButtonClick Invoked when user clicks on close button to remove message. - */ -@Suppress("LongMethod") -@Composable -fun MessageCard( - messageText: String, - modifier: Modifier = Modifier, - titleText: String? = null, - buttonText: String? = null, - messageColors: MessageCardColors = MessageCardColors.buildMessageCardColors(), - onClick: () -> Unit, - onCloseButtonClick: () -> Unit, -) { - Card( - modifier = modifier - .padding(vertical = 16.dp) - .then( + modifier = modifier + .then( if (buttonText.isNullOrBlank()) { Modifier.clickable(onClick = onClick) } else { Modifier }, ), - shape = RoundedCornerShape(16.dp), - border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant), - colors = CardDefaults.cardColors(containerColor = messageColors.backgroundColor), - ) { - Column( - Modifier - .padding(all = 16.dp) - .fillMaxWidth(), - ) { - if (!titleText.isNullOrBlank()) { - Row( - modifier = Modifier.fillMaxWidth(), - ) { - Text( - text = titleText, - modifier = Modifier.weight(1f), - color = messageColors.titleTextColor, - overflow = TextOverflow.Ellipsis, - maxLines = 2, - style = FirefoxTheme.typography.headline7, - ) - - MessageCardIconButton( - iconTint = messageColors.iconColor, - onCloseButtonClick = onCloseButtonClick, - ) - } - - Text( - text = messageText, - modifier = Modifier.fillMaxWidth(), - fontSize = 14.sp, - color = messageColors.messageTextColor, - ) - } else { - Row( - modifier = Modifier.fillMaxWidth(), - ) { - Text( - text = messageText, - modifier = Modifier.weight(1f), - fontSize = 14.sp, - color = messageColors.titleTextColor, - ) - - MessageCardIconButton( - iconTint = messageColors.iconColor, - onCloseButtonClick = onCloseButtonClick, - ) - } - } - - if (!buttonText.isNullOrBlank()) { - Spacer(modifier = Modifier.height(16.dp)) - - FilledButton( - text = buttonText, - modifier = Modifier.fillMaxWidth(), - contentColor = messageColors.buttonTextColor, - containerColor = messageColors.buttonColor, - onClick = onClick, - ) - } - } + titleText = titleText, + positiveButtonText = buttonText, + positiveOnClick = onClick, + colors = bannerColors, + border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant), + onCloseButtonClick = onCloseButtonClick, + ) } } -/** - * IconButton within a MessageCard. - * - * @param iconTint The [Color] used to tint the button's icon. - * @param onCloseButtonClick Invoked when user clicks on close button to remove message. - */ @Composable -private fun MessageCardIconButton( - iconTint: Color, - onCloseButtonClick: () -> Unit, -) { - IconButton( - modifier = Modifier.size(20.dp), - onClick = onCloseButtonClick, - ) { - Icon( - painter = painterResource(iconsR.drawable.mozac_ic_cross_20), - contentDescription = stringResource( - R.string.content_description_close_button, - ), - tint = iconTint, - ) +@PreviewLightDark +private fun MessageCardPreview() { + FirefoxTheme { + Surface { + MessageCard( + messageCardState = FakeHomepagePreview.messageCardState(), + modifier = Modifier.padding(all = 16.dp), + onClick = {}, + onCloseButtonClick = {}, + ) + } } } -/** - * Wrapper for the color parameters of [MessageCard]. - * - * @property backgroundColor The background [Color] of the message. - * @property titleTextColor [Color] to apply to the message's title, or the body text when there is no title. - * @property messageTextColor [Color] to apply to the message's body text. - * @property iconColor [Color] to apply to the message's icon. - * @property buttonColor The background [Color] of the message's button. - * @property buttonTextColor [Color] to apply to the button text. - */ -data class MessageCardColors( - val backgroundColor: Color, - val titleTextColor: Color, - val messageTextColor: Color, - val iconColor: Color, - val buttonColor: Color, - val buttonTextColor: Color, -) { - companion object { - - /** - * Builder function used to construct an instance of [MessageCardColors]. - */ - @Composable - fun buildMessageCardColors( - backgroundColor: Color = MaterialTheme.colorScheme.surfaceContainerLowest, - titleTextColor: Color = MaterialTheme.colorScheme.onSurface, - messageTextColor: Color = MaterialTheme.colorScheme.onSurfaceVariant, - iconColor: Color = MaterialTheme.colorScheme.onSurface, - buttonColor: Color = ButtonDefaults.buttonColors().containerColor, - buttonTextColor: Color = ButtonDefaults.buttonColors().contentColor, - ): MessageCardColors { - return MessageCardColors( - backgroundColor = backgroundColor, - titleTextColor = titleTextColor, - messageTextColor = messageTextColor, - iconColor = iconColor, - buttonColor = buttonColor, - buttonTextColor = buttonTextColor, +@Composable +@Preview +private fun MessageCardPrivatePreview() { + FirefoxTheme( + theme = Theme.Private, + ) { + Surface { + MessageCard( + messageCardState = FakeHomepagePreview.messageCardState(), + modifier = Modifier.padding(all = 16.dp), + onClick = {}, + onCloseButtonClick = {}, ) } } @@ -240,11 +94,14 @@ data class MessageCardColors( @Composable @PreviewLightDark -private fun MessageCardPreview() { +private fun MessageCardWithoutTitlePreview() { FirefoxTheme { Surface { MessageCard( - messageCardState = FakeHomepagePreview.messageCardState(), + messageCardState = MessageCardState( + messageText = stringResource(id = R.string.default_browser_experiment_card_text), + bannerColors = BannerColors.bannerColors(), + ), modifier = Modifier.padding(all = 16.dp), onClick = {}, onCloseButtonClick = {}, @@ -254,12 +111,17 @@ private fun MessageCardPreview() { } @Composable -@PreviewLightDark -private fun MessageCardWithoutTitlePreview() { - FirefoxTheme { +@Preview +private fun MessageCardWithoutTitlePrivatePreview() { + FirefoxTheme( + theme = Theme.Private, + ) { Surface { MessageCard( - messageText = stringResource(id = R.string.default_browser_experiment_card_text), + messageCardState = MessageCardState( + messageText = stringResource(id = R.string.default_browser_experiment_card_text), + bannerColors = BannerColors.bannerColors(), + ), modifier = Modifier.padding(all = 16.dp), onClick = {}, onCloseButtonClick = {}, @@ -274,10 +136,33 @@ private fun MessageCardWithButtonLabelPreview() { FirefoxTheme { Surface { MessageCard( - messageText = stringResource(id = R.string.default_browser_experiment_card_text), - modifier = Modifier.padding(all = 16.dp), - titleText = stringResource(id = R.string.default_browser_experiment_card_title), - buttonText = stringResource(id = R.string.preferences_set_as_default_browser), + messageCardState = MessageCardState( + messageText = stringResource(id = R.string.default_browser_experiment_card_text), + titleText = stringResource(id = R.string.default_browser_experiment_card_title), + buttonText = stringResource(id = R.string.preferences_set_as_default_browser), + bannerColors = BannerColors.bannerColors(), + ), + onClick = {}, + onCloseButtonClick = {}, + ) + } + } +} + +@Composable +@Preview +private fun MessageCardWithButtonLabelPrivatePreview() { + FirefoxTheme( + theme = Theme.Private, + ) { + Surface { + MessageCard( + messageCardState = MessageCardState( + messageText = stringResource(id = R.string.default_browser_experiment_card_text), + titleText = stringResource(id = R.string.default_browser_experiment_card_title), + buttonText = stringResource(id = R.string.preferences_set_as_default_browser), + bannerColors = BannerColors.bannerColors(), + ), onClick = {}, onCloseButtonClick = {}, ) @@ -293,13 +178,13 @@ private fun MessageCardWithButtonLabelPreview() { * the title will not be shown. * @property buttonText An optional button text of the message card. If the provided button text is blank or null, * the button won't be shown. - * @property messageColors The color set defined by [MessageCardColors] used to style the message card. + * @property bannerColors The color set defined by [BannerColors] used to style the message card. */ data class MessageCardState( val messageText: String, val titleText: String? = null, val buttonText: String? = null, - val messageColors: MessageCardColors, + val bannerColors: BannerColors, ) { /** @@ -315,27 +200,15 @@ data class MessageCardState( */ @Composable fun build(message: Message, wallpaperState: WallpaperState): MessageCardState { - val isWallpaperNotDefault = - !Wallpaper.nameIsDefault(wallpaperState.currentWallpaper.name) - - var (_, _, _, _, buttonColor, buttonTextColor) = MessageCardColors.buildMessageCardColors() - - if (isWallpaperNotDefault) { - buttonColor = MaterialTheme.colorScheme.surface - buttonTextColor = MaterialTheme.colorScheme.onSurface - } - - val messageCardColors = MessageCardColors.buildMessageCardColors( + val bannerColors = BannerColors.bannerColors( backgroundColor = wallpaperState.cardBackgroundColor, - buttonColor = buttonColor, - buttonTextColor = buttonTextColor, ) return MessageCardState( messageText = message.text, titleText = message.title, buttonText = message.buttonLabel, - messageColors = messageCardColors, + bannerColors = bannerColors, ) } } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/fake/FakeHomepagePreview.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/fake/FakeHomepagePreview.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.res.stringResource import mozilla.components.browser.state.state.ContentState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.recover.RecoverableTab +import mozilla.components.compose.base.BannerColors import mozilla.components.concept.engine.Engine import mozilla.components.concept.sync.DeviceType import mozilla.components.feature.tab.collections.Tab @@ -27,7 +28,6 @@ import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.appstate.AppState import org.mozilla.fenix.components.appstate.setup.checklist.ChecklistItem -import org.mozilla.fenix.compose.MessageCardColors import org.mozilla.fenix.compose.MessageCardState import org.mozilla.fenix.ext.CONTENT_RECOMMENDATIONS_TO_SHOW_COUNT import org.mozilla.fenix.home.bookmarks.Bookmark @@ -232,7 +232,7 @@ internal object FakeHomepagePreview { messageText = stringResource(id = R.string.default_browser_experiment_card_text), titleText = stringResource(id = R.string.default_browser_experiment_card_title), buttonText = "", - messageColors = MessageCardColors.buildMessageCardColors(), + bannerColors = BannerColors.bannerColors(), ) internal fun message() = Message(