Bug 1882196 - Adding a nav bar view

fenix/125.0
mike a 5 months ago committed by mergify[bot]
parent f04a3fd90d
commit 0724939144

@ -22,6 +22,7 @@ import androidx.annotation.CallSuper
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment 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.ScreenOrientationFeature
import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SessionFeature
import mozilla.components.feature.session.SwipeRefreshFeature import mozilla.components.feature.session.SwipeRefreshFeature
import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior
import mozilla.components.feature.sitepermissions.SitePermissionsFeature import mozilla.components.feature.sitepermissions.SitePermissionsFeature
import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.feature.webauthn.WebAuthnFeature
import mozilla.components.lib.state.ext.consumeFlow import mozilla.components.lib.state.ext.consumeFlow
@ -454,27 +454,38 @@ abstract class BaseBrowserFragment :
interactor = browserToolbarInteractor, interactor = browserToolbarInteractor,
customTabSession = customTabSessionId?.let { store.state.findCustomTab(it) }, customTabSession = customTabSessionId?.let { store.state.findCustomTab(it) },
lifecycleOwner = viewLifecycleOwner, lifecycleOwner = viewLifecycleOwner,
) ).also {
browserToolbar = it.view
browserToolbar = browserToolbarView.view }
if (IncompleteRedesignToolbarFeature(context.settings()).isEnabled) { if (IncompleteRedesignToolbarFeature(context.settings()).isEnabled) {
val toolbarView = if (context.components.settings.toolbarPosition == ToolbarPosition.BOTTOM) { val isToolbarAtBottom = 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 // The toolbar view has already been added directly to the container.
binding.browserLayout.removeView(browserToolbarView.view) // We should remove it and add the view to the navigation bar container.
browserToolbarView.view // Should refactor this so there is no added view to remove to begin with:
} else { // https://bugzilla.mozilla.org/show_bug.cgi?id=1870976
null 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( BottomToolbarContainerView(
context = context, context = context,
container = binding.browserLayout, container = binding.browserLayout,
androidToolbarView = toolbarView, androidToolbarView = if (isToolbarAtBottom) browserToolbar else null,
menuButton = MenuButton(requireContext()).apply { menuButton = menuButton,
menuBuilder = browserToolbarView.menuToolbar.menuBuilder browsingModeManager = activity.browsingModeManager,
},
) )
} }

@ -13,7 +13,13 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import mozilla.components.browser.menu.view.MenuButton 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.compose.Divider
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.theme.FirefoxTheme 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 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 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 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. * Defaults to [NavigationItems.defaultItems] which provides a standard set of navigation items.
*/ */
@ -33,11 +40,21 @@ class BottomToolbarContainerView(
navigationItems: List<ActionItem> = NavigationItems.defaultItems, navigationItems: List<ActionItem> = NavigationItems.defaultItems,
androidToolbarView: View? = null, androidToolbarView: View? = null,
menuButton: MenuButton, menuButton: MenuButton,
browsingModeManager: BrowsingModeManager,
) { ) {
init { init {
val composeView = ComposeView(context).apply { val composeView = ComposeView(context).apply {
setContent { 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 { FirefoxTheme {
Column { Column {
if (androidToolbarView != null) { if (androidToolbarView != null) {
@ -48,6 +65,7 @@ class BottomToolbarContainerView(
NavigationBar( NavigationBar(
actionItems = navigationItems, actionItems = navigationItems,
tabCount = tabCount,
menuButton = menuButton, menuButton = menuButton,
) )
} }

@ -11,23 +11,24 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding 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.Icon
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.Text import androidx.compose.material.LocalContentColor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource 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.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import mozilla.components.browser.menu.view.MenuButton import mozilla.components.browser.menu.view.MenuButton
import org.mozilla.fenix.R 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.compose.annotation.LightDarkPreview
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme import org.mozilla.fenix.theme.Theme
@ -36,11 +37,13 @@ import org.mozilla.fenix.theme.Theme
* Top-level UI for displaying the navigation bar. * Top-level UI for displaying the navigation bar.
* *
* @param actionItems A list of [ActionItem] used to populate the 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 @Composable
fun NavigationBar( fun NavigationBar(
actionItems: List<ActionItem>, actionItems: List<ActionItem>,
tabCount: Int,
menuButton: MenuButton? = null, menuButton: MenuButton? = null,
) { ) {
Box( Box(
@ -68,21 +71,20 @@ fun NavigationBar(
} }
} }
ItemType.TAB_COUNTER -> { ItemType.TAB_COUNTER -> {
IconButton(onClick = {}) { CompositionLocalProvider(LocalContentColor provides FirefoxTheme.colors.iconPrimary) {
TabsIcon(item = it, tabsCount = 0) IconButton(onClick = {}) {
TabCounter(tabCount = tabCount)
}
} }
} }
ItemType.MENU -> { ItemType.MENU -> {
// Probably, [ActionItem] will be refactored in future to incorporate // [ActionItem] will be refactored here:
// the [MenuButton] as well, so this check won't be necessary; // https://bugzilla.mozilla.org/show_bug.cgi?id=1878827
// will revisit it when doing tab counter and navigation buttons.
if (menuButton != null) { if (menuButton != null) {
AndroidView( AndroidView(
modifier = Modifier.height(48.dp).width(48.dp), modifier = Modifier.size(48.dp),
factory = { _ -> factory = { _ -> menuButton },
menuButton
},
) )
} else { } else {
IconButton(onClick = {}) { 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. * Represents a navigation bar element.
* *
@ -180,7 +163,10 @@ object NavigationItems {
@Composable @Composable
private fun NavigationBarPreview() { private fun NavigationBarPreview() {
FirefoxTheme { FirefoxTheme {
NavigationBar(NavigationItems.defaultItems) NavigationBar(
actionItems = NavigationItems.defaultItems,
tabCount = 0,
)
} }
} }
@ -188,6 +174,9 @@ private fun NavigationBarPreview() {
@Composable @Composable
private fun NavigationBarPrivatePreview() { private fun NavigationBarPrivatePreview() {
FirefoxTheme(theme = Theme.Private) { FirefoxTheme(theme = Theme.Private) {
NavigationBar(NavigationItems.defaultItems) NavigationBar(
actionItems = NavigationItems.defaultItems,
tabCount = 0,
)
} }
} }

@ -435,14 +435,14 @@ class HomeFragment : Fragment() {
) )
if (IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled) { if (IncompleteRedesignToolbarFeature(requireContext().settings()).isEnabled) {
val toolbarView = if (requireContext().components.settings.toolbarPosition == ToolbarPosition.BOTTOM) { val isToolbarAtBottom = requireContext().components.settings.toolbarPosition == ToolbarPosition.BOTTOM
val toolbar = binding.toolbarLayout
// Should refactor this so there is no added view to remove to begin with // The toolbar view has already been added directly to the container.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1870976 // We should remove it and add the view to the navigation bar container.
binding.root.removeView(toolbar) // Should refactor this so there is no added view to remove to begin with:
toolbar // https://bugzilla.mozilla.org/show_bug.cgi?id=1870976
} else { if (isToolbarAtBottom) {
null binding.root.removeView(binding.toolbarLayout)
} }
val menuButton = MenuButton(requireContext()) val menuButton = MenuButton(requireContext())
@ -458,8 +458,9 @@ class HomeFragment : Fragment() {
BottomToolbarContainerView( BottomToolbarContainerView(
context = requireContext(), context = requireContext(),
container = binding.homeLayout, container = binding.homeLayout,
androidToolbarView = toolbarView, androidToolbarView = if (isToolbarAtBottom) binding.toolbarLayout else null,
menuButton = menuButton, menuButton = menuButton,
browsingModeManager = browsingModeManager,
) )
} }

Loading…
Cancel
Save