@ -8,9 +8,17 @@ import android.content.Context
import android.view.View
import androidx.annotation.VisibleForTesting
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.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
@ -34,8 +42,11 @@ import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.compose.cfr.CFRPopup
import mozilla.components.compose.cfr.CFRPopup.PopupAlignment.INDICATOR_CENTERED_IN_ANCHOR
import mozilla.components.compose.cfr.CFRPopupProperties
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingStatus
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import org.mozilla.fenix.GleanMetrics.CookieBanners
import org.mozilla.fenix.GleanMetrics.Shopping
import org.mozilla.fenix.GleanMetrics.TrackingProtection
import org.mozilla.fenix.R
@ -109,6 +120,24 @@ class BrowserToolbarCFRPresenter(
}
}
}
ToolbarCFR . COOKIE _BANNERS -> {
scope = browserStore . flowScoped { flow ->
flow . mapNotNull { it . findCustomTabOrSelectedTab ( sessionId ) }
. ifAnyChanged { tab ->
arrayOf (
tab . cookieBanner ,
)
}
. filter {
it . content . private && it . cookieBanner == CookieBannerHandlingStatus . HANDLED
}
. collect {
scope ?. cancel ( )
settings . shouldShowCookieBannersCFR = false
showCookieBannersCFR ( )
}
}
}
ToolbarCFR . SHOPPING , ToolbarCFR . SHOPPING _OPTED _IN -> {
scope = browserStore . flowScoped { flow ->
@ -190,6 +219,10 @@ class BrowserToolbarCFRPresenter(
settings . openTabsCount >= CFR _MINIMUM _NUMBER _OPENED _TABS
) -> ToolbarCFR . TCP
isPrivate && settings . shouldShowCookieBannersCFR && settings . shouldUseCookieBannerPrivateMode -> {
ToolbarCFR . COOKIE _BANNERS
}
shoppingExperienceFeature . isEnabled &&
settings . shouldShowReviewQualityCheckCFR -> whichShoppingCFR ( )
@ -325,6 +358,64 @@ class BrowserToolbarCFRPresenter(
}
}
@VisibleForTesting
@Suppress ( " LongMethod " )
internal fun showCookieBannersCFR ( ) {
CFRPopup (
anchor = toolbar . findViewById (
R . id . mozac _browser _toolbar _security _indicator ,
) ,
properties = CFRPopupProperties (
popupAlignment = INDICATOR _CENTERED _IN _ANCHOR ,
popupBodyColors = listOf (
getColor ( context , R . color . fx _mobile _layer _color _gradient _end ) ,
getColor ( context , R . color . fx _mobile _layer _color _gradient _start ) ,
) ,
popupVerticalOffset = CFR_TO_ANCHOR_VERTICAL_PADDING . dp ,
dismissButtonColor = getColor ( context , R . color . fx _mobile _icon _color _oncolor ) ,
indicatorDirection = if ( settings . toolbarPosition == ToolbarPosition . TOP ) {
CFRPopup . IndicatorDirection . UP
} else {
CFRPopup . IndicatorDirection . DOWN
} ,
) ,
onDismiss = {
CookieBanners . cfrDismissal . record ( NoExtras ( ) )
} ,
text = {
FirefoxTheme {
Column {
Row (
verticalAlignment = Alignment . CenterVertically ,
) {
Icon (
painter = painterResource ( id = R . drawable . ic _cookies _disabled ) ,
contentDescription = null ,
tint = FirefoxTheme . colors . iconPrimary ,
)
Spacer ( modifier = Modifier . width ( 8. dp ) )
Text (
text = context . getString ( R . string . cookie _banner _cfr _title ) ,
color = FirefoxTheme . colors . textOnColorPrimary ,
style = FirefoxTheme . typography . subtitle2 ,
)
}
Text (
text = context . getString ( R . string . cookie _banner _cfr _message ) ,
color = FirefoxTheme . colors . textOnColorPrimary ,
style = FirefoxTheme . typography . body2 ,
modifier = Modifier . padding ( top = 2. dp ) ,
)
}
}
} ,
) . run {
popup = this
show ( )
CookieBanners . cfrShown . record ( NoExtras ( ) )
}
}
@VisibleForTesting
internal fun showShoppingCFR ( shouldShowOptedInCFR : Boolean ) {
CFRPopup (
@ -395,5 +486,5 @@ class BrowserToolbarCFRPresenter(
* The CFR to be shown in the toolbar .
* /
private enum class ToolbarCFR {
TCP , SHOPPING , SHOPPING _OPTED _IN , ERASE , NONE
TCP , SHOPPING , SHOPPING _OPTED _IN , ERASE , COOKIE_BANNERS , NONE
}