diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 6ed9a3715..22185e383 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -22,6 +22,7 @@ import androidx.annotation.CallSuper import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AlertDialog import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import androidx.core.view.isVisible import androidx.fragment.app.Fragment @@ -92,7 +93,6 @@ import mozilla.components.feature.session.PictureInPictureFeature import mozilla.components.feature.session.ScreenOrientationFeature import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SwipeRefreshFeature -import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.feature.sitepermissions.SitePermissionsFeature import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.lib.state.ext.consumeFlow @@ -454,27 +454,38 @@ abstract class BaseBrowserFragment : interactor = browserToolbarInteractor, customTabSession = customTabSessionId?.let { store.state.findCustomTab(it) }, lifecycleOwner = viewLifecycleOwner, - ) - - browserToolbar = browserToolbarView.view + ).also { + browserToolbar = it.view + } if (IncompleteRedesignToolbarFeature(context.settings()).isEnabled) { - val toolbarView = if (context.components.settings.toolbarPosition == ToolbarPosition.BOTTOM) { - // Should refactor this so there is no added view to remove to begin with - // https://bugzilla.mozilla.org/show_bug.cgi?id=1870976 - binding.browserLayout.removeView(browserToolbarView.view) - browserToolbarView.view - } else { - null + val isToolbarAtBottom = context.components.settings.toolbarPosition == ToolbarPosition.BOTTOM + + // The toolbar view has already been added directly to the container. + // We should remove it and add the view to the navigation bar container. + // Should refactor this so there is no added view to remove to begin with: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1870976 + if (isToolbarAtBottom) { + binding.browserLayout.removeView(browserToolbar) + } + + // We need a second menu button, but we could reuse the existing builder. + val menuButton = MenuButton(requireContext()).apply { + menuBuilder = browserToolbarView.menuToolbar.menuBuilder + setColorFilter( + ContextCompat.getColor( + context, + ThemeManager.resolveAttribute(R.attr.textPrimary, context), + ), + ) } BottomToolbarContainerView( context = context, container = binding.browserLayout, - androidToolbarView = toolbarView, - menuButton = MenuButton(requireContext()).apply { - menuBuilder = browserToolbarView.menuToolbar.menuBuilder - }, + androidToolbarView = if (isToolbarAtBottom) browserToolbar else null, + menuButton = menuButton, + browsingModeManager = activity.browsingModeManager, ) } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BottomToolbarContainerView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BottomToolbarContainerView.kt index bebc534fc..1422febdd 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BottomToolbarContainerView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BottomToolbarContainerView.kt @@ -13,7 +13,13 @@ import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.viewinterop.AndroidView import androidx.coordinatorlayout.widget.CoordinatorLayout import mozilla.components.browser.menu.view.MenuButton +import mozilla.components.browser.state.selector.normalTabs +import mozilla.components.browser.state.selector.privateTabs +import mozilla.components.lib.state.ext.observeAsState +import org.mozilla.fenix.browser.browsingmode.BrowsingMode +import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager import org.mozilla.fenix.compose.Divider +import org.mozilla.fenix.ext.components import org.mozilla.fenix.theme.FirefoxTheme /** @@ -23,7 +29,8 @@ import org.mozilla.fenix.theme.FirefoxTheme * @param container The ViewGroup into which the NavigationBar composable will be added. * @param navigationItems A list of [ActionItem] objects representing the items to be displayed in the navigation bar. * @param androidToolbarView An option toolbar view that will be added atop of the navigation bar. - * @param menuButton A [MenuButton] to be used for [ItemType.MENU] + * @param menuButton A [MenuButton] to be used for [ItemType.MENU]. + * @param browsingModeManager A helper class that provides access to the current [BrowsingMode]. * * Defaults to [NavigationItems.defaultItems] which provides a standard set of navigation items. */ @@ -33,11 +40,21 @@ class BottomToolbarContainerView( navigationItems: List = NavigationItems.defaultItems, androidToolbarView: View? = null, menuButton: MenuButton, + browsingModeManager: BrowsingModeManager, ) { init { val composeView = ComposeView(context).apply { setContent { + val isPrivate = browsingModeManager.mode.isPrivate + val tabCount = context.components.core.store.observeAsState(initialValue = 0) { browserState -> + if (isPrivate) { + browserState.privateTabs.size + } else { + browserState.normalTabs.size + } + }.value + FirefoxTheme { Column { if (androidToolbarView != null) { @@ -48,6 +65,7 @@ class BottomToolbarContainerView( NavigationBar( actionItems = navigationItems, + tabCount = tabCount, menuButton = menuButton, ) } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/NavigationBar.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/NavigationBar.kt index 58def5d2a..9660cd829 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/NavigationBar.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/NavigationBar.kt @@ -11,23 +11,24 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.size import androidx.compose.material.Icon import androidx.compose.material.IconButton -import androidx.compose.material.Text +import androidx.compose.material.LocalContentColor import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView import mozilla.components.browser.menu.view.MenuButton import org.mozilla.fenix.R +import org.mozilla.fenix.components.toolbar.ItemType.STANDARD +import org.mozilla.fenix.components.toolbar.ItemType.TAB_COUNTER +import org.mozilla.fenix.compose.TabCounter import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.Theme @@ -36,11 +37,13 @@ import org.mozilla.fenix.theme.Theme * Top-level UI for displaying the navigation bar. * * @param actionItems A list of [ActionItem] used to populate the bar. - * @param menuButton A [MenuButton] to be used for [ItemType.MENU] + * @param tabCount The number of opened tabs. + * @param menuButton A [MenuButton] to be used for [ItemType.MENU]. */ @Composable fun NavigationBar( actionItems: List, + tabCount: Int, menuButton: MenuButton? = null, ) { Box( @@ -68,21 +71,20 @@ fun NavigationBar( } } ItemType.TAB_COUNTER -> { - IconButton(onClick = {}) { - TabsIcon(item = it, tabsCount = 0) + CompositionLocalProvider(LocalContentColor provides FirefoxTheme.colors.iconPrimary) { + IconButton(onClick = {}) { + TabCounter(tabCount = tabCount) + } } } ItemType.MENU -> { - // Probably, [ActionItem] will be refactored in future to incorporate - // the [MenuButton] as well, so this check won't be necessary; - // will revisit it when doing tab counter and navigation buttons. + // [ActionItem] will be refactored here: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1878827 if (menuButton != null) { AndroidView( - modifier = Modifier.height(48.dp).width(48.dp), - factory = { _ -> - menuButton - }, + modifier = Modifier.size(48.dp), + factory = { _ -> menuButton }, ) } else { IconButton(onClick = {}) { @@ -100,25 +102,6 @@ fun NavigationBar( } } -@Composable -private fun TabsIcon(item: ActionItem, tabsCount: Int) { - Box(contentAlignment = Alignment.Center) { - Icon( - painter = painterResource(id = item.iconId), - contentDescription = stringResource(id = item.descriptionResourceId), - tint = FirefoxTheme.colors.iconPrimary, - ) - - Text( - text = tabsCount.toString(), - color = FirefoxTheme.colors.iconPrimary, - fontSize = 10.sp, - fontWeight = FontWeight.W700, - textAlign = TextAlign.Center, - ) - } -} - /** * Represents a navigation bar element. * @@ -180,7 +163,10 @@ object NavigationItems { @Composable private fun NavigationBarPreview() { FirefoxTheme { - NavigationBar(NavigationItems.defaultItems) + NavigationBar( + actionItems = NavigationItems.defaultItems, + tabCount = 0, + ) } } @@ -188,6 +174,9 @@ private fun NavigationBarPreview() { @Composable private fun NavigationBarPrivatePreview() { FirefoxTheme(theme = Theme.Private) { - NavigationBar(NavigationItems.defaultItems) + NavigationBar( + actionItems = NavigationItems.defaultItems, + tabCount = 0, + ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index f3813de69..2b1963ec6 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -435,14 +435,14 @@ class HomeFragment : Fragment() { ) if (IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled) { - val toolbarView = if (requireContext().components.settings.toolbarPosition == ToolbarPosition.BOTTOM) { - val toolbar = binding.toolbarLayout - // Should refactor this so there is no added view to remove to begin with - // https://bugzilla.mozilla.org/show_bug.cgi?id=1870976 - binding.root.removeView(toolbar) - toolbar - } else { - null + val isToolbarAtBottom = requireContext().components.settings.toolbarPosition == ToolbarPosition.BOTTOM + + // The toolbar view has already been added directly to the container. + // We should remove it and add the view to the navigation bar container. + // Should refactor this so there is no added view to remove to begin with: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1870976 + if (isToolbarAtBottom) { + binding.root.removeView(binding.toolbarLayout) } val menuButton = MenuButton(requireContext()) @@ -458,8 +458,9 @@ class HomeFragment : Fragment() { BottomToolbarContainerView( context = requireContext(), container = binding.homeLayout, - androidToolbarView = toolbarView, + androidToolbarView = if (isToolbarAtBottom) binding.toolbarLayout else null, menuButton = menuButton, + browsingModeManager = browsingModeManager, ) }