Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
For #26026 - Refactor the FenixTabCounterMenu creation from HomeFragm…
Browse files Browse the repository at this point in the history
…ent to TabCounterBuilder
  • Loading branch information
gabrielluong authored and mergify[bot] committed Jul 26, 2022
1 parent ac51c34 commit 8f51a99
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 43 deletions.
49 changes: 6 additions & 43 deletions app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,9 @@ import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.android.content.res.resolveAttribute
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.components.ui.tabcounter.TabCounterMenu
import org.mozilla.fenix.Config
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.StartOnHome
import org.mozilla.fenix.GleanMetrics.Wallpapers
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
Expand All @@ -84,7 +82,6 @@ import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu
import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.databinding.FragmentHomeBinding
import org.mozilla.fenix.ext.components
Expand Down Expand Up @@ -510,7 +507,12 @@ class HomeFragment : Fragment() {
hideOnboardingIfNeeded = ::hideOnboardingIfNeeded,
).build()

createTabCounterMenu()
TabCounterBuilder(
context = requireContext(),
browsingModeManager = browsingModeManager,
navController = findNavController(),
tabCounter = binding.tabButton,
).build()

binding.toolbar.compoundDrawablePadding =
view.resources.getDimensionPixelSize(R.dimen.search_bar_search_engine_icon_padding)
Expand All @@ -528,11 +530,6 @@ class HomeFragment : Fragment() {
true
}

binding.tabButton.setOnClickListener {
StartOnHome.openTabsTray.record(NoExtras())
openTabsTray()
}

PrivateBrowsingButtonView(binding.privateBrowsingButton, browsingModeManager) { newMode ->
sessionControlInteractor.onPrivateModeButtonClicked(
newMode,
Expand Down Expand Up @@ -627,40 +624,6 @@ class HomeFragment : Fragment() {
}
}

private fun createTabCounterMenu() {
val browsingModeManager = (activity as HomeActivity).browsingModeManager
val mode = browsingModeManager.mode

val onItemTapped: (TabCounterMenu.Item) -> Unit = {
if (it is TabCounterMenu.Item.NewTab) {
browsingModeManager.mode = BrowsingMode.Normal
} else if (it is TabCounterMenu.Item.NewPrivateTab) {
browsingModeManager.mode = BrowsingMode.Private
}
}

val tabCounterMenu = FenixTabCounterMenu(
requireContext(),
onItemTapped,
iconColor = if (mode == BrowsingMode.Private) {
ContextCompat.getColor(requireContext(), R.color.fx_mobile_private_text_color_primary)
} else {
null
}
)

val inverseBrowsingMode = when (mode) {
BrowsingMode.Normal -> BrowsingMode.Private
BrowsingMode.Private -> BrowsingMode.Normal
}

tabCounterMenu.updateMenu(showOnly = inverseBrowsingMode)
binding.tabButton.setOnLongClickListener {
tabCounterMenu.menuController.show(anchor = it)
true
}
}

private fun removeAllTabsAndShowSnackbar(sessionCode: String) {
if (sessionCode == ALL_PRIVATE_TABS) {
requireComponents.useCases.tabsUseCases.removePrivateTabs()
Expand Down
81 changes: 81 additions & 0 deletions app/src/main/java/org/mozilla/fenix/home/TabCounterBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.fenix.home

import android.content.Context
import androidx.core.content.ContextCompat
import androidx.navigation.NavController
import mozilla.components.ui.tabcounter.TabCounter
import mozilla.components.ui.tabcounter.TabCounterMenu
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.StartOnHome
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu
import org.mozilla.fenix.ext.nav

/**
* Helper class for building the [FenixTabCounterMenu].
*
* @property context An Android [Context].
* @property browsingModeManager [BrowsingModeManager] used for fetching the current browsing mode.
* @property navController [NavController] used for navigation.
* @property tabCounter The [TabCounter] that will be setup with event handlers.
*/
class TabCounterBuilder(
private val context: Context,
private val browsingModeManager: BrowsingModeManager,
private val navController: NavController,
private val tabCounter: TabCounter,
) {

/**
* Builds the [FenixTabCounterMenu].
*/
fun build() {
val tabCounterMenu = FenixTabCounterMenu(
context = context,
onItemTapped = ::onItemTapped,
iconColor = if (browsingModeManager.mode == BrowsingMode.Private) {
ContextCompat.getColor(context, R.color.fx_mobile_private_text_color_primary)
} else {
null
}
)

tabCounterMenu.updateMenu(
showOnly = when (browsingModeManager.mode) {
BrowsingMode.Normal -> BrowsingMode.Private
BrowsingMode.Private -> BrowsingMode.Normal
}
)

tabCounter.setOnLongClickListener {
tabCounterMenu.menuController.show(anchor = it)
true
}

tabCounter.setOnClickListener {
StartOnHome.openTabsTray.record(NoExtras())

navController.nav(
R.id.homeFragment,
HomeFragmentDirections.actionGlobalTabsTrayFragment()
)
}
}

/**
* Callback invoked when a menu item is tapped on.
*/
internal fun onItemTapped(item: TabCounterMenu.Item) {
if (item is TabCounterMenu.Item.NewTab) {
browsingModeManager.mode = BrowsingMode.Normal
} else if (item is TabCounterMenu.Item.NewPrivateTab) {
browsingModeManager.mode = BrowsingMode.Private
}
}
}
96 changes: 96 additions & 0 deletions app/src/test/java/org/mozilla/fenix/home/TabCounterBuilderTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.fenix.home

import androidx.navigation.NavController
import io.mockk.mockk
import io.mockk.verify
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.ui.tabcounter.TabCounter
import mozilla.components.ui.tabcounter.TabCounterMenu
import mozilla.telemetry.glean.testing.GleanTestRule
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.GleanMetrics.StartOnHome
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.utils.Settings

@RunWith(FenixRobolectricTestRunner::class)
class TabCounterBuilderTest {

@get:Rule
val gleanTestRule = GleanTestRule(testContext)

private lateinit var navController: NavController
private lateinit var browsingModeManager: BrowsingModeManager
private lateinit var settings: Settings
private lateinit var modeDidChange: (BrowsingMode) -> Unit
private lateinit var tabCounterBuilder: TabCounterBuilder
private lateinit var tabCounter: TabCounter

@Before
fun setup() {
navController = mockk(relaxed = true)
settings = mockk(relaxed = true)
modeDidChange = mockk(relaxed = true)

tabCounter = TabCounter(testContext)

browsingModeManager = DefaultBrowsingModeManager(
_mode = BrowsingMode.Normal,
settings = settings,
modeDidChange = modeDidChange,
)

tabCounterBuilder = TabCounterBuilder(
context = testContext,
browsingModeManager = browsingModeManager,
navController = navController,
tabCounter = tabCounter,
)
}

@Test
fun `WHEN tab counter is clicked THEN navigate to tabs tray and record metrics`() {
tabCounterBuilder.build()

assertNull(StartOnHome.openTabsTray.testGetValue())

tabCounter.performClick()

assertNotNull(StartOnHome.openTabsTray.testGetValue())

verify {
navController.nav(
R.id.homeFragment,
HomeFragmentDirections.actionGlobalTabsTrayFragment()
)
}
}

@Test
fun `WHEN New tab menu item is tapped THEN set browsing mode to normal`() {
tabCounterBuilder.onItemTapped(TabCounterMenu.Item.NewTab)

assertEquals(BrowsingMode.Normal, browsingModeManager.mode)
}

@Test
fun `WHEN New private tab menu item is tapped THEN set browsing mode to private`() {
tabCounterBuilder.onItemTapped(TabCounterMenu.Item.NewPrivateTab)

assertEquals(BrowsingMode.Private, browsingModeManager.mode)
}
}

0 comments on commit 8f51a99

Please sign in to comment.