@ -7,6 +7,7 @@ package org.mozilla.fenix.components.toolbar
import android.content.Context
import android.content.Context
import androidx.annotation.ColorRes
import androidx.annotation.ColorRes
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.PRIVATE
import androidx.core.content.ContextCompat.getColor
import androidx.core.content.ContextCompat.getColor
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.lifecycleScope
@ -21,6 +22,7 @@ import mozilla.components.browser.menu.item.BrowserMenuDivider
import mozilla.components.browser.menu.item.BrowserMenuHighlightableItem
import mozilla.components.browser.menu.item.BrowserMenuHighlightableItem
import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.browser.menu.item.BrowserMenuImageTextCheckboxButton
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.menu.item.WebExtensionPlaceholderMenuItem
import mozilla.components.browser.menu.item.WebExtensionPlaceholderMenuItem
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.selector.findTab
@ -33,13 +35,19 @@ import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.FeatureFlags.tabsTrayRewrite
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.accounts.FenixAccountManager
import org.mozilla.fenix.experiments.ExperimentBranch
import org.mozilla.fenix.experiments.Experiments
import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.withExperiment
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.BrowsersCache
/ * *
/ * *
* Builds the toolbar object used with the 3 - dot menu in the browser fragment .
* Builds the toolbar object used with the 3 - dot menu in the browser fragment .
@ -50,13 +58,12 @@ import org.mozilla.fenix.theme.ThemeManager
* @param lifecycleOwner View lifecycle owner used to determine when to cancel UI jobs .
* @param lifecycleOwner View lifecycle owner used to determine when to cancel UI jobs .
* @param bookmarksStorage Used to check if a page is bookmarked .
* @param bookmarksStorage Used to check if a page is bookmarked .
* /
* /
@Suppress ( " LargeClass " , " LongParameterList " )
@Suppress ( " LargeClass " , " LongParameterList " , " TooManyFunctions " )
@ExperimentalCoroutinesApi
@ExperimentalCoroutinesApi
class DefaultToolbarMenu (
open class DefaultToolbarMenu (
private val context : Context ,
private val context : Context ,
private val store : BrowserStore ,
private val store : BrowserStore ,
hasAccountProblem : Boolean = false ,
hasAccountProblem : Boolean = false ,
shouldReverseItems : Boolean ,
private val onItemTapped : ( ToolbarMenu . Item ) -> Unit = { } ,
private val onItemTapped : ( ToolbarMenu . Item ) -> Unit = { } ,
private val lifecycleOwner : LifecycleOwner ,
private val lifecycleOwner : LifecycleOwner ,
private val bookmarksStorage : BookmarksStorage ,
private val bookmarksStorage : BookmarksStorage ,
@ -65,7 +72,11 @@ class DefaultToolbarMenu(
private var isCurrentUrlBookmarked = false
private var isCurrentUrlBookmarked = false
private var isBookmarkedJob : Job ? = null
private var isBookmarkedJob : Job ? = null
private val isTopToolbarSelected = shouldReverseItems
private val shouldDeleteDataOnQuit = context . settings ( ) . shouldDeleteBrowsingDataOnQuit
private val shouldUseBottomToolbar = context . settings ( ) . shouldUseBottomToolbar
private val accountManager = FenixAccountManager ( context )
private val selectedSession : TabSessionState ?
private val selectedSession : TabSessionState ?
get ( ) = store . state . selectedTab
get ( ) = store . state . selectedTab
@ -77,13 +88,16 @@ class DefaultToolbarMenu(
} else {
} else {
oldCoreMenuItems
oldCoreMenuItems
} ,
} ,
endOfMenuAlwaysVisible = ! shouldReverseItems ,
endOfMenuAlwaysVisible = shouldUseBottomToolbar ,
store = store ,
store = store ,
webExtIconTintColorResource = primaryTextColor ( ) ,
style = WebExtensionBrowserMenuBuilder . Style (
webExtIconTintColorResource = primaryTextColor ( ) ,
addonsManagerMenuItemDrawableRes = R . drawable . ic _addons _extensions
) ,
onAddonsManagerTapped = {
onAddonsManagerTapped = {
onItemTapped . invoke ( ToolbarMenu . Item . AddonsManager )
onItemTapped . invoke ( ToolbarMenu . Item . AddonsManager )
} ,
} ,
appendExtensionSubMenuAtStart = ! shouldReverseItems
appendExtensionSubMenuAtStart = shouldUseBottomToolbar
)
)
}
}
@ -137,7 +151,7 @@ class DefaultToolbarMenu(
}
}
val share = BrowserMenuItemToolbar . Button (
val share = BrowserMenuItemToolbar . Button (
imageResource = R . drawable . ic _share _filled ,
imageResource = R . drawable . ic _share ,
contentDescription = context . getString ( R . string . browser _menu _share ) ,
contentDescription = context . getString ( R . string . browser _menu _share ) ,
iconTintColorResource = primaryTextColor ( ) ,
iconTintColorResource = primaryTextColor ( ) ,
listener = {
listener = {
@ -148,7 +162,7 @@ class DefaultToolbarMenu(
registerForIsBookmarkedUpdates ( )
registerForIsBookmarkedUpdates ( )
if ( FeatureFlags . toolbarMenuFeature ) {
if ( FeatureFlags . toolbarMenuFeature ) {
BrowserMenuItemToolbar ( listOf ( back , forward , share , refresh ) )
BrowserMenuItemToolbar ( listOf ( back , forward , share , refresh ) , isSticky = true )
} else {
} else {
val bookmark = BrowserMenuItemToolbar . TwoStateButton (
val bookmark = BrowserMenuItemToolbar . TwoStateButton (
primaryImageResource = R . drawable . ic _bookmark _filled ,
primaryImageResource = R . drawable . ic _bookmark _filled ,
@ -163,8 +177,7 @@ class DefaultToolbarMenu(
secondaryImageTintResource = primaryTextColor ( ) ,
secondaryImageTintResource = primaryTextColor ( ) ,
disableInSecondaryState = false
disableInSecondaryState = false
) {
) {
if ( !is CurrentUrlBookmarked ) isCurrentUrlBookmarked = true
handleBookmarkItemTapped ( )
onItemTapped . invoke ( ToolbarMenu . Item . Bookmark )
}
}
BrowserMenuItemToolbar ( listOf ( back , forward , bookmark , share , refresh ) )
BrowserMenuItemToolbar ( listOf ( back , forward , bookmark , share , refresh ) )
@ -172,24 +185,43 @@ class DefaultToolbarMenu(
}
}
// Predicates that need to be repeatedly called as the session changes
// Predicates that need to be repeatedly called as the session changes
private fun canAddToHomescreen ( ) : Boolean =
@VisibleForTesting ( otherwise = PRIVATE )
fun canAddToHomescreen ( ) : Boolean =
selectedSession != null && isPinningSupported &&
selectedSession != null && isPinningSupported &&
! context . components . useCases . webAppUseCases . isInstallable ( )
! context . components . useCases . webAppUseCases . isInstallable ( )
private fun canInstall ( ) : Boolean =
@VisibleForTesting ( otherwise = PRIVATE )
fun canInstall ( ) : Boolean =
selectedSession != null && isPinningSupported &&
selectedSession != null && isPinningSupported &&
context . components . useCases . webAppUseCases . isInstallable ( )
context . components . useCases . webAppUseCases . isInstallable ( )
private fun shouldShowOpenInApp ( ) : Boolean = selectedSession ?. let { session ->
@VisibleForTesting ( otherwise = PRIVATE )
fun shouldShowOpenInApp ( ) : Boolean = selectedSession ?. let { session ->
val appLink = context . components . useCases . appLinksUseCases . appLinkRedirect
val appLink = context . components . useCases . appLinksUseCases . appLinkRedirect
appLink ( session . content . url ) . hasExternalApp ( )
appLink ( session . content . url ) . hasExternalApp ( )
} ?: false
} ?: false
private fun shouldShowReaderViewCustomization ( ) : Boolean = selectedSession ?. let {
@VisibleForTesting ( otherwise = PRIVATE )
fun shouldShowReaderViewCustomization ( ) : Boolean = selectedSession ?. let {
store . state . findTab ( it . id ) ?. readerState ?. active
store . state . findTab ( it . id ) ?. readerState ?. active
} ?: false
} ?: false
// End of predicates //
// End of predicates //
val installToHomescreen = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _install _on _homescreen ) ,
startImageResource = R . drawable . ic _add _to _homescreen ,
iconTintColorResource = primaryTextColor ( ) ,
highlight = BrowserMenuHighlight . LowPriority (
label = context . getString ( R . string . browser _menu _install _on _homescreen ) ,
notificationTint = getColor ( context , R . color . whats _new _notification _color )
) ,
isHighlighted = {
! context . settings ( ) . installPwaOpened
}
) {
onItemTapped . invoke ( ToolbarMenu . Item . InstallPwaToHomeScreen )
}
private val oldCoreMenuItems by lazy {
private val oldCoreMenuItems by lazy {
val settings = BrowserMenuHighlightableItem (
val settings = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _settings ) ,
label = context . getString ( R . string . browser _menu _settings ) ,
@ -244,21 +276,6 @@ class DefaultToolbarMenu(
onItemTapped . invoke ( ToolbarMenu . Item . SyncedTabs )
onItemTapped . invoke ( ToolbarMenu . Item . SyncedTabs )
}
}
val installToHomescreen = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _install _on _homescreen ) ,
startImageResource = R . drawable . ic _add _to _homescreen ,
iconTintColorResource = primaryTextColor ( ) ,
highlight = BrowserMenuHighlight . LowPriority (
label = context . getString ( R . string . browser _menu _install _on _homescreen ) ,
notificationTint = getColor ( context , R . color . whats _new _notification _color )
) ,
isHighlighted = {
! context . settings ( ) . installPwaOpened
}
) {
onItemTapped . invoke ( ToolbarMenu . Item . InstallToHomeScreen )
}
val findInPage = BrowserMenuImageText (
val findInPage = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _find _in _page ) ,
label = context . getString ( R . string . browser _menu _find _in _page ) ,
imageResource = R . drawable . mozac _ic _search ,
imageResource = R . drawable . mozac _ic _search ,
@ -348,6 +365,9 @@ class DefaultToolbarMenu(
BrowserMenuDivider ( ) ,
BrowserMenuDivider ( ) ,
reportSiteIssuePlaceholder ,
reportSiteIssuePlaceholder ,
findInPage ,
findInPage ,
getSetDefaultBrowserItem ( ) ?. let { BrowserMenuDivider ( ) } ,
getSetDefaultBrowserItem ( ) ,
getSetDefaultBrowserItem ( ) ?. let { BrowserMenuDivider ( ) } ,
addToTopSites ,
addToTopSites ,
addToHomescreen . apply { visible = :: canAddToHomescreen } ,
addToHomescreen . apply { visible = :: canAddToHomescreen } ,
installToHomescreen . apply { visible = :: canInstall } ,
installToHomescreen . apply { visible = :: canInstall } ,
@ -359,157 +379,195 @@ class DefaultToolbarMenu(
menuToolbar
menuToolbar
)
)
if ( shouldReverseItems ) {
if ( shouldUseBottomToolbar ) {
menuItems . reversed ( )
} else {
menuItems
menuItems
} else {
menuItems . reversed ( )
}
}
}
}
private val newCoreMenuItems by lazy {
val newTabItem = BrowserMenuImageText (
val newTabItem = BrowserMenuImageText (
context . getString ( R . string . library _new _tab ) ,
context . getString ( R . string . library _new _tab ) ,
R . drawable . ic _new ,
R . drawable . ic _new ,
primaryTextColor ( )
primaryTextColor ( )
) {
) {
onItemTapped . invoke ( ToolbarMenu . Item . NewTab )
onItemTapped . invoke ( ToolbarMenu . Item . NewTab )
}
}
val bookmarks Item = BrowserMenuImageText (
val history Item = BrowserMenuImageText (
context . getString ( R . string . library _ bookmarks ) ,
context . getString ( R . string . library _ history ) ,
R . drawable . ic _ bookmark_filled ,
R . drawable . ic _ history ,
primaryTextColor ( )
primaryTextColor ( )
) {
) {
onItemTapped . invoke ( ToolbarMenu . Item . Bookmarks )
onItemTapped . invoke ( ToolbarMenu . Item . History )
}
}
val history Item = BrowserMenuImageText (
val downloads Item = BrowserMenuImageText (
context . getString ( R . string . library _ history ) ,
context . getString ( R . string . library _ downloads ) ,
R . drawable . ic _ history ,
R . drawable . ic _ download ,
primaryTextColor ( )
primaryTextColor ( )
) {
) {
onItemTapped . invoke ( ToolbarMenu . Item . History )
onItemTapped . invoke ( ToolbarMenu . Item . Downloads )
}
}
val downloadsItem = BrowserMenuImageText (
val extensionsItem = WebExtensionPlaceholderMenuItem (
context . getString ( R . string . library _downloads ) ,
id = WebExtensionPlaceholderMenuItem . MAIN _EXTENSIONS _MENU _ID
R . drawable . ic _download ,
)
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Downloads )
}
val extensions Item = BrowserMenuImageText (
val findInPageItem = BrowserMenuImageText (
context . getString ( R . string . browser _menu _ extensions ) ,
label = context . getString ( R . string . browser _menu _find _in _page ) ,
R . drawable . ic _addons _extensions ,
imageResource = R . drawable . mozac _ic _search ,
primaryTextColor ( )
iconTintColorResource = primaryTextColor ( )
) {
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddonsManager )
onItemTapped . invoke ( ToolbarMenu . Item . FindInPage )
}
}
val syncedTabs = BrowserMenuImageText (
val desktopSiteItem = BrowserMenuImageSwitch (
label = context . getString ( R . string . synced _tabs ) ,
imageResource = R . drawable . ic _desktop ,
imageResource = R . drawable . ic _synced _tabs ,
label = context . getString ( R . string . browser _menu _desktop _site ) ,
iconTintColorResource = primaryTextColor ( )
initialState = {
) {
selectedSession ?. content ?. desktopMode ?: false
onItemTapped . invoke ( ToolbarMenu . Item . SyncedTabs )
}
}
) { checked ->
onItemTapped . invoke ( ToolbarMenu . Item . RequestDesktop ( checked ) )
}
val findInPageItem = BrowserMenuImageText (
val customizeReaderView = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _find _in _page ) ,
label = context . getString ( R . string . browser _menu _ customize_reader _view ) ,
imageResource = R . drawable . mozac_ic _search ,
imageResource = R . drawable . ic_readermode _appearance ,
iconTintColorResource = primaryTextColor ( )
iconTintColorResource = primaryTextColor ( )
) {
) {
onItemTapped . invoke ( ToolbarMenu . Item . FindInPage )
onItemTapped . invoke ( ToolbarMenu . Item . CustomizeReaderView )
}
}
val desktopSiteItem = BrowserMenuImageSwitch (
val openInApp = BrowserMenuHighlightableItem (
imageResource = R . drawable . ic _desktop ,
label = context . getString ( R . string . browser _menu _open _app _link ) ,
label = context . getString ( R . string . browser _menu _desktop _site ) ,
startImageResource = R . drawable . ic _open _in _app ,
initialState = {
iconTintColorResource = primaryTextColor ( ) ,
selectedSession ?. content ?. desktopMode ?: false
highlight = BrowserMenuHighlight . LowPriority (
}
label = context . getString ( R . string . browser _menu _open _app _link ) ,
) { checked ->
notificationTint = getColor ( context , R . color . whats _new _notification _color )
onItemTapped . invoke ( ToolbarMenu . Item . RequestDesktop ( checked ) )
) ,
}
isHighlighted = { ! context . settings ( ) . openInAppOpened }
) {
onItemTapped . invoke ( ToolbarMenu . Item . OpenInApp )
}
val customizeReaderView = BrowserMenuImageText (
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem (
label = context . getString ( R . string . browser _menu _customize _reader _view ) ,
id = WebCompatReporterFeature . WEBCOMPAT _REPORTER _EXTENSION _ID
imageResource = R . drawable . ic _readermode _appearance ,
)
iconTintColorResource = primaryTextColor ( )
) {
val addToHomeScreenItem = BrowserMenuImageText (
onItemTapped . invoke ( ToolbarMenu . Item . CustomizeReaderView )
label = context . getString ( R . string . browser _menu _add _to _homescreen ) ,
}
imageResource = R . drawable . ic _add _to _homescreen ,
iconTintColorResource = primaryTextColor ( ) ,
isCollapsingMenuLimit = true
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToHomeScreen )
}
val openInApp = BrowserMenuHighlightableItem (
val addToTopSitesItem = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _open _app _link ) ,
label = context . getString ( R . string . browser _menu _add _to _top _sites ) ,
startImageResource = R . drawable . ic _open _in _app ,
imageResource = R . drawable . ic _top _sites ,
iconTintColorResource = primaryTextColor ( ) ,
iconTintColorResource = primaryTextColor ( )
highlight = BrowserMenuHighlight . LowPriority (
) {
label = context . getString ( R . string . browser _menu _open _app _link ) ,
onItemTapped . invoke ( ToolbarMenu . Item . AddToTopSites )
notificationTint = getColor ( context , R . color . whats _new _notification _color )
}
) ,
isHighlighted = { ! context . settings ( ) . openInAppOpened }
) {
onItemTapped . invoke ( ToolbarMenu . Item . OpenInApp )
}
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem (
val saveToCollectionItem = BrowserMenuImageText (
id = WebCompatReporterFeature . WEBCOMPAT _REPORTER _EXTENSION _ID
label = context . getString ( R . string . browser _menu _save _to _collection _2 ) ,
)
imageResource = R . drawable . ic _tab _collection ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . SaveToCollection )
}
val addToHomeScreenItem = BrowserMenuImageText (
val settingsItem = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _add _to _homescreen ) ,
label = context . getString ( R . string . browser _menu _settings ) ,
imageResource = R . drawable . ic _add _to _homescreen ,
startImageResource = R . drawable . ic _settings ,
iconTintColorResource = primaryTextColor ( )
iconTintColorResource = if ( hasAccountProblem )
) {
ThemeManager . resolveAttribute ( R . attr . syncDisconnected , context ) else
onItemTapped . invoke ( ToolbarMenu . Item . AddToHomeScreen )
primaryTextColor ( ) ,
}
textColorResource = if ( hasAccountProblem )
ThemeManager . resolveAttribute ( R . attr . primaryText , context ) else
primaryTextColor ( ) ,
highlight = BrowserMenuHighlight . HighPriority (
endImageResource = R . drawable . ic _sync _disconnected ,
backgroundTint = context . getColorFromAttr ( R . attr . syncDisconnectedBackground ) ,
canPropagate = false
) ,
isHighlighted = { hasAccountProblem }
) {
onItemTapped . invoke ( ToolbarMenu . Item . Settings )
}
val addToTopSitesItem = BrowserMenuImageText (
val bookmarksItem = BrowserMenuImageTextCheckboxButton (
label = context . getString ( R . string . browser _menu _add _to _top _sites ) ,
imageResource = R . drawable . ic _bookmarks _menu ,
imageResource = R . drawable . ic _top _sites ,
iconTintColorResource = primaryTextColor ( ) ,
iconTintColorResource = primaryTextColor ( )
label = context . getString ( R . string . library _bookmarks ) ,
) {
labelListener = {
onItemTapped . invoke ( ToolbarMenu . Item . AddToTopSites )
onItemTapped . invoke ( ToolbarMenu . Item . Bookmarks )
}
} ,
primaryStateIconResource = R . drawable . ic _bookmark _outline ,
secondaryStateIconResource = R . drawable . ic _bookmark _filled ,
tintColorResource = menuItemButtonTintColor ( ) ,
primaryLabel = context . getString ( R . string . browser _menu _add ) ,
secondaryLabel = context . getString ( R . string . browser _menu _edit ) ,
isInPrimaryState = { !is CurrentUrlBookmarked }
) {
handleBookmarkItemTapped ( )
}
val saveToCollectionItem = BrowserMenuImageText (
val deleteDataOnQuit = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _save _to _collection _2 ) ,
label = context . getString ( R . string . delete_browsing _data _on _quit _action ) ,
imageResource = R . drawable . ic _tab _collection ,
imageResource = R . drawable . ic _ exit ,
iconTintColorResource = primaryTextColor ( )
iconTintColorResource = primaryTextColor ( )
) {
) {
onItemTapped . invoke ( ToolbarMenu . Item . SaveToCollection )
onItemTapped . invoke ( ToolbarMenu . Item . Quit )
}
}
val settingsItem = BrowserMenuHighlightableItem (
val syncedTabsItem = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _settings ) ,
context . getString ( R . string . synced _tabs ) ,
startImageResource = R . drawable . ic _settings ,
R . drawable . ic _synced _tabs ,
iconTintColorResource = primaryTextColor ( ) ,
primaryTextColor ( )
textColorResource = if ( hasAccountProblem )
) {
ThemeManager . resolveAttribute ( R . attr . primaryText , context ) else
onItemTapped . invoke ( ToolbarMenu . Item . SyncedTabs )
primaryTextColor ( ) ,
}
highlight = BrowserMenuHighlight . HighPriority (
endImageResource = R . drawable . ic _sync _disconnected ,
private fun getSyncItemTitle ( ) : String {
backgroundTint = context . getColorFromAttr ( R . attr . syncDisconnectedBackground ) ,
val authenticatedAccount = accountManager . authenticatedAccount
canPropagate = false
val email = accountManager . accountProfileEmail
) ,
isHighlighted = { hasAccountProblem }
return if ( authenticatedAccount && ! email . isNullOrEmpty ( ) ) {
) {
email
onItemTapped . invoke ( ToolbarMenu . Item . Settings )
} else {
context . getString ( R . string . sync _menu _sign _in )
}
}
}
val syncMenuItem = BrowserMenuImageText (
getSyncItemTitle ( ) ,
R . drawable . ic _signed _out ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . SyncAccount ( accountManager . signedInToFxa ( ) ) )
}
@VisibleForTesting ( otherwise = PRIVATE )
val newCoreMenuItems by lazy {
val menuItems =
val menuItems =
listOfNotNull (
listOfNotNull (
if ( isTopToolbarSelected ) menuToolbar else null ,
if ( shouldUseBottomToolbar) null else menuToolbar ,
newTabItem ,
newTabItem ,
BrowserMenuDivider ( ) ,
BrowserMenuDivider ( ) ,
bookmarksItem ,
bookmarksItem ,
historyItem ,
historyItem ,
downloadsItem ,
downloadsItem ,
extensionsItem ,
extensionsItem ,
syncedTabs ,
if ( tabsTrayRewrite ) syncMenuItem else syncedTabs Item ,
BrowserMenuDivider ( ) ,
BrowserMenuDivider ( ) ,
getSetDefaultBrowserItem ( ) ,
getSetDefaultBrowserItem ( ) ?. let { BrowserMenuDivider ( ) } ,
findInPageItem ,
findInPageItem ,
desktopSiteItem ,
desktopSiteItem ,
customizeReaderView . apply { visible = :: shouldShowReaderViewCustomization } ,
customizeReaderView . apply { visible = :: shouldShowReaderViewCustomization } ,
@ -517,21 +575,32 @@ class DefaultToolbarMenu(
reportSiteIssuePlaceholder ,
reportSiteIssuePlaceholder ,
BrowserMenuDivider ( ) ,
BrowserMenuDivider ( ) ,
addToHomeScreenItem . apply { visible = :: canAddToHomescreen } ,
addToHomeScreenItem . apply { visible = :: canAddToHomescreen } ,
installToHomescreen . apply { visible = :: canInstall } ,
addToTopSitesItem ,
addToTopSitesItem ,
saveToCollectionItem ,
saveToCollectionItem ,
BrowserMenuDivider ( ) ,
BrowserMenuDivider ( ) ,
settingsItem ,
settingsItem ,
if ( isTopToolbarSelected ) null else BrowserMenuDivider ( ) ,
if ( shouldDeleteDataOnQuit ) deleteDataOnQuit else null ,
if ( isTopToolbarSelected ) null else menuToolbar
if ( shouldUseBottomToolbar ) BrowserMenuDivider ( ) else null ,
if ( shouldUseBottomToolbar ) menuToolbar else null
)
)
menuItems
menuItems
}
}
private fun handleBookmarkItemTapped ( ) {
if ( !is CurrentUrlBookmarked ) isCurrentUrlBookmarked = true
onItemTapped . invoke ( ToolbarMenu . Item . Bookmark )
}
@ColorRes
@ColorRes
@VisibleForTesting
@VisibleForTesting
internal fun primaryTextColor ( ) = ThemeManager . resolveAttribute ( R . attr . primaryText , context )
internal fun primaryTextColor ( ) = ThemeManager . resolveAttribute ( R . attr . primaryText , context )
@ColorRes
@VisibleForTesting
internal fun menuItemButtonTintColor ( ) = ThemeManager . resolveAttribute ( R . attr . menuItemButtonTintColor , context )
@VisibleForTesting
@VisibleForTesting
internal fun registerForIsBookmarkedUpdates ( ) {
internal fun registerForIsBookmarkedUpdates ( ) {
store . flowScoped ( lifecycleOwner ) { flow ->
store . flowScoped ( lifecycleOwner ) { flow ->
@ -558,4 +627,24 @@ class DefaultToolbarMenu(
. any { it . url == newUrl }
. any { it . url == newUrl }
}
}
}
}
private fun getSetDefaultBrowserItem ( ) : BrowserMenuImageText ? {
val experiments = context . components . analytics . experiments
val browsers = BrowsersCache . all ( context )
return experiments . withExperiment ( Experiments . DEFAULT _BROWSER ) { experimentBranch ->
if ( experimentBranch == ExperimentBranch . DEFAULT _BROWSER _TOOLBAR _MENU &&
! browsers . isFirefoxDefaultBrowser
) {
return @withExperiment BrowserMenuImageText (
label = context . getString ( R . string . preferences _set _as _default _browser ) ,
imageResource = R . mipmap . ic _launcher
) {
onItemTapped . invoke ( ToolbarMenu . Item . SetDefaultBrowser )
}
} else {
null
}
}
}
}
}