@ -32,6 +32,7 @@ import mozilla.components.feature.webcompat.reporter.WebCompatReporterFeature
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
@ -69,7 +70,12 @@ class DefaultToolbarMenu(
override val menuBuilder by lazy {
WebExtensionBrowserMenuBuilder (
menuItems ,
items =
if ( FeatureFlags . toolbarMenuFeature ) {
newCoreMenuItems
} else {
oldCoreMenuItems
} ,
endOfMenuAlwaysVisible = ! shouldReverseItems ,
store = store ,
webExtIconTintColorResource = primaryTextColor ( ) ,
@ -179,7 +185,148 @@ class DefaultToolbarMenu(
} ?: false
// End of predicates //
private val menuItems by lazy {
private val oldCoreMenuItems by lazy {
val settings = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _settings ) ,
startImageResource = R . drawable . ic _settings ,
iconTintColorResource = if ( hasAccountProblem )
ThemeManager . resolveAttribute ( R . attr . syncDisconnected , context ) else
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 desktopMode = BrowserMenuImageSwitch (
imageResource = R . drawable . ic _desktop ,
label = context . getString ( R . string . browser _menu _desktop _site ) ,
initialState = {
selectedSession ?. content ?. desktopMode ?: false
}
) { checked ->
onItemTapped . invoke ( ToolbarMenu . Item . RequestDesktop ( checked ) )
}
val addToTopSites = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _add _to _top _sites ) ,
imageResource = R . drawable . ic _top _sites ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToTopSites )
}
val addToHomescreen = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _add _to _homescreen ) ,
imageResource = R . drawable . ic _add _to _homescreen ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToHomeScreen )
}
val syncedTabs = BrowserMenuImageText (
label = context . getString ( R . string . synced _tabs ) ,
imageResource = R . drawable . ic _synced _tabs ,
iconTintColorResource = primaryTextColor ( )
) {
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 (
label = context . getString ( R . string . browser _menu _find _in _page ) ,
imageResource = R . drawable . mozac _ic _search ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . FindInPage )
}
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem (
id = WebCompatReporterFeature . WEBCOMPAT _REPORTER _EXTENSION _ID
)
val saveToCollection = BrowserMenuImageText (
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 deleteDataOnQuit = BrowserMenuImageText (
label = context . getString ( R . string . delete _browsing _data _on _quit _action ) ,
imageResource = R . drawable . ic _exit ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Quit )
}
val readerAppearance = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _read _appearance ) ,
imageResource = R . drawable . ic _readermode _appearance ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . ReaderModeAppearance )
}
val openInApp = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _open _app _link ) ,
startImageResource = R . drawable . ic _open _in _app ,
iconTintColorResource = primaryTextColor ( ) ,
highlight = BrowserMenuHighlight . LowPriority (
label = context . getString ( R . string . browser _menu _open _app _link ) ,
notificationTint = getColor ( context , R . color . whats _new _notification _color )
) ,
isHighlighted = { ! context . settings ( ) . openInAppOpened }
) {
onItemTapped . invoke ( ToolbarMenu . Item . OpenInApp )
}
val historyItem = BrowserMenuImageText (
context . getString ( R . string . library _history ) ,
R . drawable . ic _history ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . History )
}
val bookmarksItem = BrowserMenuImageText (
context . getString ( R . string . library _bookmarks ) ,
R . drawable . ic _bookmark _filled ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Bookmarks )
}
val downloadsItem = BrowserMenuImageText (
context . getString ( R . string . library _downloads ) ,
R . drawable . ic _download ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Downloads )
}
// Predicates that are called once, during screen init
val shouldShowSaveToCollection = ( context . asActivity ( ) as ? HomeActivity )
?. browsingModeManager ?. mode == BrowsingMode . Normal
@ -216,151 +363,149 @@ class DefaultToolbarMenu(
}
}
private val settings = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _settings ) ,
startImageResource = R . drawable . ic _settings ,
iconTintColorResource = if ( hasAccountProblem )
ThemeManager . resolveAttribute ( R . attr . syncDisconnected , context ) else
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 )
}
private val newCoreMenuItems by lazy {
val newTabItem = BrowserMenuImageText (
context . getString ( R . string . library _new _tab ) ,
R . drawable . ic _bookmark _filled ,
disabledTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . NewTab )
}
private val desktopMode = BrowserMenuImageSwitch (
imageResource = R . drawable . ic _desktop ,
label = context . getString ( R . string . browser _menu _desktop _site ) ,
initialState = {
selectedSession ?. content ?. desktopMode ?: false
val bookmarksItem = BrowserMenuImageText (
context . getString ( R . string . library _bookmarks ) ,
R . drawable . ic _bookmark _filled ,
disabledTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Bookmarks )
}
) { checked ->
onItemTapped . invoke ( ToolbarMenu . Item . RequestDesktop ( checked ) )
}
private val addToTopSites = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _add _to _top _sites ) ,
imageResource = R . drawable . ic _top _sites ,
iconTintColorResource = primary TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToTopSites )
}
val historyItem = BrowserMenuImageText (
context . getString ( R . string . library _history ) ,
R . drawable . ic _history ,
disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . History )
}
private val addToHomescreen = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _add _to _homescreen ) ,
imageResource = R . drawable . ic _add _to _homescreen ,
iconTintColorResource = primary TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToHomeScreen )
}
val downloadsItem = BrowserMenuImageText (
context . getString ( R . string . library _downloads ) ,
R . drawable . ic _download ,
disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Downloads )
}
private val syncedTabs = BrowserMenuImageText (
label = context . getString ( R . string . synced _tab s) ,
imageResource = R . drawable . ic _synced _tab s,
iconTintColorResource = primary TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . SyncedTabs )
}
val extensionsItem = BrowserMenuImageText (
context . getString ( R . string . browser _menu _extension s) ,
R . drawable . ic _addons _extension s,
disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddonsManager )
}
private 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
val syncedTabsItem = BrowserMenuImageText (
context . getString ( R . string . library _synced _tabs ) ,
R . drawable . ic _synced _tabs ,
disabledTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . SyncedTabs )
}
) {
onItemTapped . invoke ( ToolbarMenu . Item . InstallToHomeScreen )
}
private val findInPage = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _find _in _page ) ,
imageResource = R . drawable . mozac _ic _search ,
iconTintColorResource = primary TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . FindInPage )
}
val findInPageItem = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _find _in _page ) ,
imageResource = R . drawable . mozac _ic _search ,
iconTintColorResource = disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . FindInPage )
}
private val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem (
id = WebCompatReporterFeature . WEBCOMPAT _REPORTER _EXTENSION _ID
)
val desktopSiteItem = BrowserMenuImageSwitch (
imageResource = R . drawable . ic _desktop ,
label = context . getString ( R . string . browser _menu _desktop _site ) ,
initialState = {
selectedSession ?. content ?. desktopMode ?: false
}
) { checked ->
onItemTapped . invoke ( ToolbarMenu . Item . RequestDesktop ( checked ) )
}
private val saveToCollection = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _save _to _collection _2 ) ,
imageResource = R . drawable . ic _tab _collection ,
iconTintColorResource = primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . SaveToCollectio n)
}
val addToHomeScreenItem = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _ add_to _homescreen ) ,
imageResource = R . drawable . ic _ add_to _homescree n,
iconTintColorResource = disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToHomeScree n)
}
private val deleteDataOnQuit = BrowserMenuImageText (
label = context . getString ( R . string . delete_browsing _data _on _quit _action ) ,
imageResource = R . drawable . ic _ exit ,
iconTintColorResource = primary TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Quit )
}
val addToTopSitesItem = BrowserMenuImageText (
label = context . getString ( R . string . browser_menu _add _to _top _sites ) ,
imageResource = R . drawable . ic _ top_sites ,
iconTintColorResource = disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . AddToTopSites )
}
private val readerAppearance = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _ read_appearance ) ,
imageResource = R . drawable . ic _ readermode_appearance ,
iconTintColorResource = primary TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . ReaderModeAppearance )
}
val saveToCollectionItem = BrowserMenuImageText (
label = context . getString ( R . string . browser _menu _ save_to _collection _2 ) ,
imageResource = R . drawable . ic _ tab_collection ,
iconTintColorResource = disabled TextColor( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . SaveToCollection )
}
private val openInApp = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _open _app _link ) ,
startImageResource = R . drawable . ic _open _in _app ,
iconTintColorResource = primaryTextColor ( ) ,
highlight = BrowserMenuHighlight . LowPriority (
label = context . getString ( R . string . browser _menu _open _app _link ) ,
notificationTint = getColor ( context , R . color . whats _new _notification _color )
) ,
isHighlighted = { ! context . settings ( ) . openInAppOpened }
) {
onItemTapped . invoke ( ToolbarMenu . Item . OpenInApp )
}
val settingsItem = BrowserMenuHighlightableItem (
label = context . getString ( R . string . browser _menu _settings ) ,
startImageResource = R . drawable . ic _settings ,
iconTintColorResource = disabledTextColor ( ) ,
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 historyItem = BrowserMenuImageText (
context . getString ( R . string . library _history ) ,
R . drawable . ic _history ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . History )
}
val syncedTabsInTabsTray = context . components . settings
. syncedTabsInTabsTray
val bookmarksItem = BrowserMenuImageText (
context . getString ( R . string . library _bookmarks ) ,
R . drawable . ic _bookmark _filled ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Bookmarks )
}
val menuItems = listOfNotNull (
newTabItem ,
BrowserMenuDivider ( ) ,
bookmarksItem ,
historyItem ,
downloadsItem ,
extensionsItem ,
if ( syncedTabsInTabsTray ) null else syncedTabsItem ,
BrowserMenuDivider ( ) ,
findInPageItem ,
desktopSiteItem ,
BrowserMenuDivider ( ) ,
addToHomeScreenItem . apply { visible = :: canAddToHomescreen } ,
addToTopSitesItem ,
saveToCollectionItem ,
BrowserMenuDivider ( ) ,
settingsItem ,
BrowserMenuDivider ( ) ,
menuToolbar
)
val downloadsItem = BrowserMenuImageText (
context . getString ( R . string . library _downloads ) ,
R . drawable . ic _download ,
primaryTextColor ( )
) {
onItemTapped . invoke ( ToolbarMenu . Item . Downloads )
menuItems
}
@ColorRes
@VisibleForTesting
internal fun primaryTextColor ( ) = ThemeManager . resolveAttribute ( R . attr . primaryText , context )
@ColorRes
@VisibleForTesting
internal fun disabledTextColor ( ) = R . color . toolbar _menu _transparent
@VisibleForTesting
internal fun registerForIsBookmarkedUpdates ( ) {
store . flowScoped ( lifecycleOwner ) { flow ->