* Create new menu order for new tab * Add new tab menu navigation. Dynamically update menu when sync auth is needed. Make new tab menu and browser menu consistent. * Lint Lint and refactoring tests * Tests for default toolbar menu * Feature flag for request desktop site Add todos for UI test issue 17979 Add todos for UI tests
This commit is contained in:
parent
35de7056b3
commit
ca33aef036
|
@ -49,6 +49,7 @@ class NavigationToolbarTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun goBackTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
@ -66,8 +67,8 @@ class NavigationToolbarTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Test failures: https://github.com/mozilla-mobile/fenix/issues/18720")
|
||||
@Test
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun goForwardTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
@ -95,8 +96,8 @@ class NavigationToolbarTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Test failures: https://github.com/mozilla-mobile/fenix/issues/18720")
|
||||
@Test
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun refreshPageTest() {
|
||||
val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer)
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@ class NoNetworkAccessStartupTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Ignore("Test failures: https://github.com/mozilla-mobile/fenix/issues/18720")
|
||||
@Test
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun testPageReloadAfterNetworkInterrupted() {
|
||||
val url = "example.com"
|
||||
|
||||
|
@ -80,7 +80,11 @@ class NoNetworkAccessStartupTests {
|
|||
|
||||
browserScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.refreshPage {}
|
||||
verifyRefreshButton()
|
||||
}
|
||||
|
||||
// we verify that the share button exists, but this fails when trying to click
|
||||
// .refreshPage {}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -44,8 +44,8 @@ class ShareButtonTest {
|
|||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
@Ignore("Test failures: https://github.com/mozilla-mobile/fenix/issues/18720")
|
||||
@Test
|
||||
@Ignore("To be re-implemented with the three dot menu changes https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun ShareButtonAppearanceTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.junit.Before
|
|||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
|
@ -41,7 +42,7 @@ import org.mozilla.fenix.ui.util.STRING_ONBOARDING_TRACKING_PROTECTION_HEADER
|
|||
* Test Suite that contains tests defined as part of the Smoke and Sanity check defined in Test rail.
|
||||
* These tests will verify different functionalities of the app as a way to quickly detect regressions in main areas
|
||||
*/
|
||||
|
||||
@Suppress("ForbiddenComment")
|
||||
class SmokeTest {
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
@ -316,35 +317,41 @@ class SmokeTest {
|
|||
|
||||
@Test
|
||||
// Verifies the Bookmark button in a tab's 3 dot menu
|
||||
@Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
// TODO: To be removed in https://github.com/mozilla-mobile/fenix/issues/17979 since the bookmark button is no longer in the nav bar.
|
||||
fun mainMenuBookmarkButtonTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
if (!FeatureFlags.toolbarMenuFeature) {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.openThreeDotMenu {
|
||||
}.bookmarkPage {
|
||||
verifySnackBarText("Bookmark saved!")
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.openThreeDotMenu {
|
||||
}.bookmarkPage {
|
||||
verifySnackBarText("Bookmark saved!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Test failures: https://github.com/mozilla-mobile/fenix/issues/18720")
|
||||
@Test
|
||||
// Verifies the Share button in a tab's 3 dot menu
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun mainMenuShareButtonTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
}.openThreeDotMenu {
|
||||
}.sharePage {
|
||||
verifyShareAppsLayout()
|
||||
verifyShareButton()
|
||||
}
|
||||
|
||||
// we verify that the share button exists, but this fails when trying to click
|
||||
// .sharePage {
|
||||
// verifyShareAppsLayout()
|
||||
// }
|
||||
}
|
||||
|
||||
@Ignore("Test failures: https://github.com/mozilla-mobile/fenix/issues/18720")
|
||||
@Test
|
||||
// Verifies the refresh button in a tab's 3 dot menu
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun mainMenuRefreshButtonTest() {
|
||||
val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer)
|
||||
|
||||
|
@ -354,14 +361,17 @@ class SmokeTest {
|
|||
}.openThreeDotMenu {
|
||||
verifyThreeDotMenuExists()
|
||||
verifyRefreshButton()
|
||||
}.refreshPage {
|
||||
verifyPageContent("REFRESHED")
|
||||
}
|
||||
|
||||
// we verify that the refresh button exists, but this fails when trying to click
|
||||
// .refreshPage {
|
||||
// verifyPageContent("REFRESHED")
|
||||
// }
|
||||
}
|
||||
|
||||
@Test
|
||||
// Turns ETP toggle off from Settings and verifies the ETP shield is not displayed in the nav bar
|
||||
@Ignore("To be re-implemented with the three dot menu changes https://github.com/mozilla-mobile/fenix/issues/17870")
|
||||
@Ignore("To be fixed in https://github.com/mozilla-mobile/fenix/issues/17979")
|
||||
fun verifyETPShieldNotDisplayedIfOFFGlobally() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
|
|
|
@ -109,8 +109,7 @@ class NavigationToolbarRobot {
|
|||
withResourceName("onboarding_message"), // Req ETP dialog
|
||||
withResourceName("download_button")
|
||||
)
|
||||
)
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
BrowserRobot().interact()
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.mozilla.fenix.share.ShareFragment
|
|||
/**
|
||||
* Implementation of Robot Pattern for the three dot (main) menu.
|
||||
*/
|
||||
@Suppress("ForbiddenComment")
|
||||
class ThreeDotMenuMainRobot {
|
||||
fun verifyTabSettingsButton() = assertTabSettingsButton()
|
||||
fun verifyRecentlyClosedTabsButton() = assertRecentlyClosedTabsButton()
|
||||
|
@ -166,7 +167,7 @@ class ThreeDotMenuMainRobot {
|
|||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun openSettings(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(ViewActions.swipeDown())
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(swipeDown())
|
||||
onView(allOf(withResourceName("text"), withText(R.string.browser_menu_settings)))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
|
@ -185,7 +186,7 @@ class ThreeDotMenuMainRobot {
|
|||
}
|
||||
|
||||
fun openSyncedTabs(interact: SyncedTabsRobot.() -> Unit): SyncedTabsRobot.Transition {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(ViewActions.swipeDown())
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(swipeDown())
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Synced tabs")), waitingTime)
|
||||
syncedTabsButton().click()
|
||||
|
||||
|
@ -205,7 +206,7 @@ class ThreeDotMenuMainRobot {
|
|||
}
|
||||
|
||||
fun openHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(ViewActions.swipeDown())
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(swipeDown())
|
||||
mDevice.waitNotNull(Until.findObject(By.text("History")), waitingTime)
|
||||
historyButton().click()
|
||||
|
||||
|
@ -273,6 +274,7 @@ class ThreeDotMenuMainRobot {
|
|||
}
|
||||
|
||||
fun refreshPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
// TODO: this is not finding the button correctly
|
||||
mDevice.waitNotNull(Until.findObject(By.desc("Refresh")), waitingTime)
|
||||
refreshButton().click()
|
||||
|
||||
|
@ -303,7 +305,7 @@ class ThreeDotMenuMainRobot {
|
|||
}
|
||||
|
||||
fun openFindInPage(interact: FindInPageRobot.() -> Unit): FindInPageRobot.Transition {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(ViewActions.swipeDown())
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(swipeDown())
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Find in page")), waitingTime)
|
||||
findInPageButton().click()
|
||||
|
||||
|
@ -463,12 +465,12 @@ private fun assertShareTabButton() = shareTabButton()
|
|||
|
||||
private fun shareButton() = onView(ViewMatchers.withContentDescription("Share"))
|
||||
private fun assertShareButton() = shareButton()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun browserViewSaveCollectionButton() = onView(
|
||||
allOf(
|
||||
withText("Save to collection"),
|
||||
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)
|
||||
withEffectiveVisibility(Visibility.VISIBLE)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -493,9 +495,11 @@ private fun assertCollectionNameTextField() = collectionNameTextField()
|
|||
private fun reportSiteIssueButton() = onView(withText("Report Site Issue…"))
|
||||
|
||||
private fun findInPageButton() = onView(allOf(withText("Find in page")))
|
||||
|
||||
private fun assertFindInPageButton() = findInPageButton()
|
||||
|
||||
private fun shareScrim() = onView(withResourceName("closeSharingScrim"))
|
||||
|
||||
private fun assertShareScrim() =
|
||||
shareScrim().check(matches(ViewMatchers.withAlpha(ShareFragment.SHOW_PAGE_ALPHA)))
|
||||
|
||||
|
@ -544,6 +548,7 @@ private fun assertAddToFirefoxHome() {
|
|||
|
||||
private fun addToMobileHomeButton() =
|
||||
onView(allOf(withText(R.string.browser_menu_add_to_homescreen)))
|
||||
|
||||
private fun assertAddToMobileHome() {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView))
|
||||
.perform(
|
||||
|
|
|
@ -128,6 +128,18 @@ class DefaultBrowserToolbarMenuController(
|
|||
activity.finishAndRemoveTask()
|
||||
}
|
||||
}
|
||||
// todo === End ===
|
||||
is ToolbarMenu.Item.OpenInApp -> {
|
||||
settings.openInAppOpened = true
|
||||
|
||||
val appLinksUseCases = activity.components.useCases.appLinksUseCases
|
||||
val getRedirect = appLinksUseCases.appLinkRedirect
|
||||
currentSession?.let {
|
||||
val redirect = getRedirect.invoke(it.content.url)
|
||||
redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
appLinksUseCases.openAppLink.invoke(redirect.appIntent)
|
||||
}
|
||||
}
|
||||
is ToolbarMenu.Item.Quit -> {
|
||||
// We need to show the snackbar while the browsing data is deleting (if "Delete
|
||||
// browsing data on quit" is activated). After the deletion is over, the snackbar
|
||||
|
@ -147,19 +159,6 @@ class DefaultBrowserToolbarMenuController(
|
|||
readerModeController.showControls()
|
||||
metrics.track(Event.ReaderModeAppearanceOpened)
|
||||
}
|
||||
is ToolbarMenu.Item.OpenInApp -> {
|
||||
settings.openInAppOpened = true
|
||||
|
||||
val appLinksUseCases = activity.components.useCases.appLinksUseCases
|
||||
val getRedirect = appLinksUseCases.appLinkRedirect
|
||||
currentSession?.let {
|
||||
val redirect = getRedirect.invoke(it.content.url)
|
||||
redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
appLinksUseCases.openAppLink.invoke(redirect.appIntent)
|
||||
}
|
||||
}
|
||||
// todo === End ===
|
||||
|
||||
is ToolbarMenu.Item.Back -> {
|
||||
if (item.viewHistory) {
|
||||
navController.navigate(
|
||||
|
|
|
@ -163,14 +163,13 @@ class BrowserToolbarView(
|
|||
} else {
|
||||
menuToolbar = DefaultToolbarMenu(
|
||||
context = this,
|
||||
store = components.core.store,
|
||||
hasAccountProblem = components.backgroundServices.accountManager.accountNeedsReauth(),
|
||||
shouldReverseItems = toolbarPosition == ToolbarPosition.TOP,
|
||||
onItemTapped = {
|
||||
it.performHapticIfNeeded(view)
|
||||
interactor.onBrowserToolbarMenuItemTapped(it)
|
||||
},
|
||||
lifecycleOwner = lifecycleOwner,
|
||||
store = components.core.store,
|
||||
bookmarksStorage = bookmarkStorage,
|
||||
isPinningSupported = isPinningSupported
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.components.toolbar
|
|||
import android.content.Context
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.VisibleForTesting.PRIVATE
|
||||
import androidx.core.content.ContextCompat.getColor
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
@ -53,11 +54,10 @@ import org.mozilla.fenix.theme.ThemeManager
|
|||
*/
|
||||
@Suppress("LargeClass", "LongParameterList")
|
||||
@ExperimentalCoroutinesApi
|
||||
class DefaultToolbarMenu(
|
||||
open class DefaultToolbarMenu(
|
||||
private val context: Context,
|
||||
private val store: BrowserStore,
|
||||
hasAccountProblem: Boolean = false,
|
||||
shouldReverseItems: Boolean,
|
||||
private val onItemTapped: (ToolbarMenu.Item) -> Unit = {},
|
||||
private val lifecycleOwner: LifecycleOwner,
|
||||
private val bookmarksStorage: BookmarksStorage,
|
||||
|
@ -66,10 +66,15 @@ class DefaultToolbarMenu(
|
|||
|
||||
private var isCurrentUrlBookmarked = false
|
||||
private var isBookmarkedJob: Job? = null
|
||||
private val isTopToolbarSelected = shouldReverseItems
|
||||
|
||||
private val shouldUseBottomToolbar = context.settings().shouldUseBottomToolbar
|
||||
|
||||
private val selectedSession: TabSessionState?
|
||||
get() = store.state.selectedTab
|
||||
|
||||
private val primaryTextColor =
|
||||
ThemeManager.resolveAttribute(R.attr.primaryText, context)
|
||||
|
||||
override val menuBuilder by lazy {
|
||||
WebExtensionBrowserMenuBuilder(
|
||||
items =
|
||||
|
@ -78,13 +83,13 @@ class DefaultToolbarMenu(
|
|||
} else {
|
||||
oldCoreMenuItems
|
||||
},
|
||||
endOfMenuAlwaysVisible = !shouldReverseItems,
|
||||
endOfMenuAlwaysVisible = !shouldUseBottomToolbar,
|
||||
store = store,
|
||||
webExtIconTintColorResource = primaryTextColor(),
|
||||
webExtIconTintColorResource = primaryTextColor,
|
||||
onAddonsManagerTapped = {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.AddonsManager)
|
||||
},
|
||||
appendExtensionSubMenuAtStart = !shouldReverseItems
|
||||
appendExtensionSubMenuAtStart = !shouldUseBottomToolbar
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -92,7 +97,7 @@ class DefaultToolbarMenu(
|
|||
val back = BrowserMenuItemToolbar.TwoStateButton(
|
||||
primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_back,
|
||||
primaryContentDescription = context.getString(R.string.browser_menu_back),
|
||||
primaryImageTintResource = primaryTextColor(),
|
||||
primaryImageTintResource = primaryTextColor,
|
||||
isInPrimaryState = {
|
||||
selectedSession?.content?.canGoBack ?: true
|
||||
},
|
||||
|
@ -106,7 +111,7 @@ class DefaultToolbarMenu(
|
|||
val forward = BrowserMenuItemToolbar.TwoStateButton(
|
||||
primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_forward,
|
||||
primaryContentDescription = context.getString(R.string.browser_menu_forward),
|
||||
primaryImageTintResource = primaryTextColor(),
|
||||
primaryImageTintResource = primaryTextColor,
|
||||
isInPrimaryState = {
|
||||
selectedSession?.content?.canGoForward ?: true
|
||||
},
|
||||
|
@ -120,13 +125,13 @@ class DefaultToolbarMenu(
|
|||
val refresh = BrowserMenuItemToolbar.TwoStateButton(
|
||||
primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_refresh,
|
||||
primaryContentDescription = context.getString(R.string.browser_menu_refresh),
|
||||
primaryImageTintResource = primaryTextColor(),
|
||||
primaryImageTintResource = primaryTextColor,
|
||||
isInPrimaryState = {
|
||||
selectedSession?.content?.loading == false
|
||||
},
|
||||
secondaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_stop,
|
||||
secondaryContentDescription = context.getString(R.string.browser_menu_stop),
|
||||
secondaryImageTintResource = primaryTextColor(),
|
||||
secondaryImageTintResource = primaryTextColor,
|
||||
disableInSecondaryState = false,
|
||||
longClickListener = { onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = true)) }
|
||||
) {
|
||||
|
@ -140,7 +145,7 @@ class DefaultToolbarMenu(
|
|||
val share = BrowserMenuItemToolbar.Button(
|
||||
imageResource = R.drawable.ic_share_filled,
|
||||
contentDescription = context.getString(R.string.browser_menu_share),
|
||||
iconTintColorResource = primaryTextColor(),
|
||||
iconTintColorResource = primaryTextColor,
|
||||
listener = {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Share)
|
||||
}
|
||||
|
@ -154,14 +159,14 @@ class DefaultToolbarMenu(
|
|||
val bookmark = BrowserMenuItemToolbar.TwoStateButton(
|
||||
primaryImageResource = R.drawable.ic_bookmark_filled,
|
||||
primaryContentDescription = context.getString(R.string.browser_menu_edit_bookmark),
|
||||
primaryImageTintResource = primaryTextColor(),
|
||||
primaryImageTintResource = primaryTextColor,
|
||||
// TwoStateButton.isInPrimaryState must be synchronous, and checking bookmark state is
|
||||
// relatively slow. The best we can do here is periodically compute and cache a new "is
|
||||
// bookmarked" state, and use that whenever the menu has been opened.
|
||||
isInPrimaryState = { isCurrentUrlBookmarked },
|
||||
secondaryImageResource = R.drawable.ic_bookmark_outline,
|
||||
secondaryContentDescription = context.getString(R.string.browser_menu_bookmark),
|
||||
secondaryImageTintResource = primaryTextColor(),
|
||||
secondaryImageTintResource = primaryTextColor,
|
||||
disableInSecondaryState = false
|
||||
) {
|
||||
handleBookmarkItemTapped()
|
||||
|
@ -172,20 +177,24 @@ class DefaultToolbarMenu(
|
|||
}
|
||||
|
||||
// Predicates that need to be repeatedly called as the session changes
|
||||
private fun canAddToHomescreen(): Boolean =
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
fun canAddToHomescreen(): Boolean =
|
||||
selectedSession != null && isPinningSupported &&
|
||||
!context.components.useCases.webAppUseCases.isInstallable()
|
||||
|
||||
private fun canInstall(): Boolean =
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
fun canInstall(): Boolean =
|
||||
selectedSession != null && isPinningSupported &&
|
||||
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
|
||||
appLink(session.content.url).hasExternalApp()
|
||||
} ?: false
|
||||
|
||||
private fun shouldShowReaderViewCustomization(): Boolean = selectedSession?.let {
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
fun shouldShowReaderViewCustomization(): Boolean = selectedSession?.let {
|
||||
store.state.findTab(it.id)?.readerState?.active
|
||||
} ?: false
|
||||
// End of predicates //
|
||||
|
@ -196,10 +205,10 @@ class DefaultToolbarMenu(
|
|||
startImageResource = R.drawable.ic_settings,
|
||||
iconTintColorResource = if (hasAccountProblem)
|
||||
ThemeManager.resolveAttribute(R.attr.syncDisconnected, context) else
|
||||
primaryTextColor(),
|
||||
primaryTextColor,
|
||||
textColorResource = if (hasAccountProblem)
|
||||
ThemeManager.resolveAttribute(R.attr.primaryText, context) else
|
||||
primaryTextColor(),
|
||||
primaryTextColor,
|
||||
highlight = BrowserMenuHighlight.HighPriority(
|
||||
endImageResource = R.drawable.ic_sync_disconnected,
|
||||
backgroundTint = context.getColorFromAttr(R.attr.syncDisconnectedBackground),
|
||||
|
@ -223,7 +232,7 @@ class DefaultToolbarMenu(
|
|||
val addToTopSites = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_add_to_top_sites),
|
||||
imageResource = R.drawable.ic_top_sites,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.AddToTopSites)
|
||||
}
|
||||
|
@ -231,7 +240,7 @@ class DefaultToolbarMenu(
|
|||
val addToHomescreen = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_add_to_homescreen),
|
||||
imageResource = R.drawable.ic_add_to_homescreen,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen)
|
||||
}
|
||||
|
@ -239,7 +248,7 @@ class DefaultToolbarMenu(
|
|||
val syncedTabs = BrowserMenuImageText(
|
||||
label = context.getString(R.string.synced_tabs),
|
||||
imageResource = R.drawable.ic_synced_tabs,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
|
||||
}
|
||||
|
@ -247,7 +256,7 @@ class DefaultToolbarMenu(
|
|||
val installToHomescreen = BrowserMenuHighlightableItem(
|
||||
label = context.getString(R.string.browser_menu_install_on_homescreen),
|
||||
startImageResource = R.drawable.ic_add_to_homescreen,
|
||||
iconTintColorResource = primaryTextColor(),
|
||||
iconTintColorResource = primaryTextColor,
|
||||
highlight = BrowserMenuHighlight.LowPriority(
|
||||
label = context.getString(R.string.browser_menu_install_on_homescreen),
|
||||
notificationTint = getColor(context, R.color.whats_new_notification_color)
|
||||
|
@ -262,7 +271,7 @@ class DefaultToolbarMenu(
|
|||
val findInPage = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_find_in_page),
|
||||
imageResource = R.drawable.mozac_ic_search,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.FindInPage)
|
||||
}
|
||||
|
@ -274,7 +283,7 @@ class DefaultToolbarMenu(
|
|||
val saveToCollection = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_save_to_collection_2),
|
||||
imageResource = R.drawable.ic_tab_collection,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.SaveToCollection)
|
||||
}
|
||||
|
@ -282,7 +291,7 @@ class DefaultToolbarMenu(
|
|||
val deleteDataOnQuit = BrowserMenuImageText(
|
||||
label = context.getString(R.string.delete_browsing_data_on_quit_action),
|
||||
imageResource = R.drawable.ic_exit,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Quit)
|
||||
}
|
||||
|
@ -290,7 +299,7 @@ class DefaultToolbarMenu(
|
|||
val readerAppearance = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_read_appearance),
|
||||
imageResource = R.drawable.ic_readermode_appearance,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
iconTintColorResource = primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.CustomizeReaderView)
|
||||
}
|
||||
|
@ -298,7 +307,7 @@ class DefaultToolbarMenu(
|
|||
val openInApp = BrowserMenuHighlightableItem(
|
||||
label = context.getString(R.string.browser_menu_open_app_link),
|
||||
startImageResource = R.drawable.ic_open_in_app,
|
||||
iconTintColorResource = primaryTextColor(),
|
||||
iconTintColorResource = primaryTextColor,
|
||||
highlight = BrowserMenuHighlight.LowPriority(
|
||||
label = context.getString(R.string.browser_menu_open_app_link),
|
||||
notificationTint = getColor(context, R.color.whats_new_notification_color)
|
||||
|
@ -311,7 +320,7 @@ class DefaultToolbarMenu(
|
|||
val historyItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_history),
|
||||
R.drawable.ic_history,
|
||||
primaryTextColor()
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.History)
|
||||
}
|
||||
|
@ -319,7 +328,7 @@ class DefaultToolbarMenu(
|
|||
val bookmarksItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_bookmarks),
|
||||
R.drawable.ic_bookmark_filled,
|
||||
primaryTextColor()
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Bookmarks)
|
||||
}
|
||||
|
@ -327,7 +336,7 @@ class DefaultToolbarMenu(
|
|||
val downloadsItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_downloads),
|
||||
R.drawable.ic_download,
|
||||
primaryTextColor()
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Downloads)
|
||||
}
|
||||
|
@ -359,154 +368,154 @@ class DefaultToolbarMenu(
|
|||
menuToolbar
|
||||
)
|
||||
|
||||
if (shouldReverseItems) {
|
||||
menuItems.reversed()
|
||||
} else {
|
||||
if (shouldUseBottomToolbar) {
|
||||
menuItems
|
||||
} else {
|
||||
menuItems.reversed()
|
||||
}
|
||||
}
|
||||
val newTabItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_new_tab),
|
||||
R.drawable.ic_new,
|
||||
primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.NewTab)
|
||||
}
|
||||
|
||||
private val newCoreMenuItems by lazy {
|
||||
val newTabItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_new_tab),
|
||||
R.drawable.ic_new,
|
||||
primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.NewTab)
|
||||
val historyItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_history),
|
||||
R.drawable.ic_history,
|
||||
primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.History)
|
||||
}
|
||||
|
||||
val downloadsItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_downloads),
|
||||
R.drawable.ic_download,
|
||||
primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Downloads)
|
||||
}
|
||||
|
||||
val extensionsItem = WebExtensionPlaceholderMenuItem(
|
||||
id = WebExtensionPlaceholderMenuItem.MAIN_EXTENSIONS_MENU_ID
|
||||
)
|
||||
|
||||
val syncedTabs = BrowserMenuImageText(
|
||||
label = context.getString(R.string.synced_tabs),
|
||||
imageResource = R.drawable.ic_synced_tabs,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
|
||||
}
|
||||
|
||||
val findInPageItem = 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 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))
|
||||
}
|
||||
|
||||
val historyItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_history),
|
||||
R.drawable.ic_history,
|
||||
primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.History)
|
||||
}
|
||||
val customizeReaderView = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_customize_reader_view),
|
||||
imageResource = R.drawable.ic_readermode_appearance,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.CustomizeReaderView)
|
||||
}
|
||||
|
||||
val downloadsItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_downloads),
|
||||
R.drawable.ic_download,
|
||||
primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Downloads)
|
||||
}
|
||||
|
||||
val extensionsItem = WebExtensionPlaceholderMenuItem(
|
||||
id = WebExtensionPlaceholderMenuItem.MAIN_EXTENSIONS_MENU_ID
|
||||
)
|
||||
|
||||
val syncedTabs = BrowserMenuImageText(
|
||||
label = context.getString(R.string.synced_tabs),
|
||||
imageResource = R.drawable.ic_synced_tabs,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs)
|
||||
}
|
||||
|
||||
val findInPageItem = 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 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))
|
||||
}
|
||||
|
||||
val customizeReaderView = BrowserMenuImageText(
|
||||
label = context.getString(R.string.browser_menu_customize_reader_view),
|
||||
imageResource = R.drawable.ic_readermode_appearance,
|
||||
iconTintColorResource = primaryTextColor()
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.CustomizeReaderView)
|
||||
}
|
||||
|
||||
val openInApp = BrowserMenuHighlightableItem(
|
||||
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),
|
||||
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)
|
||||
}
|
||||
notificationTint = getColor(context, R.color.whats_new_notification_color)
|
||||
),
|
||||
isHighlighted = { !context.settings().openInAppOpened }
|
||||
) {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.OpenInApp)
|
||||
}
|
||||
|
||||
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem(
|
||||
id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID
|
||||
)
|
||||
val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem(
|
||||
id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID
|
||||
)
|
||||
|
||||
val addToHomeScreenItem = 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 addToHomeScreenItem = 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 addToTopSitesItem = 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 addToTopSitesItem = 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 saveToCollectionItem = 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 saveToCollectionItem = 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 settingsItem = BrowserMenuHighlightableItem(
|
||||
label = context.getString(R.string.browser_menu_settings),
|
||||
startImageResource = R.drawable.ic_settings,
|
||||
iconTintColorResource = 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 settingsItem = BrowserMenuHighlightableItem(
|
||||
label = context.getString(R.string.browser_menu_settings),
|
||||
startImageResource = R.drawable.ic_settings,
|
||||
iconTintColorResource = 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 bookmarksItem = BrowserMenuImageTextCheckboxButton(
|
||||
imageResource = R.drawable.ic_bookmarks_menu,
|
||||
iconTintColorResource = primaryTextColor(),
|
||||
label = context.getString(R.string.library_bookmarks),
|
||||
labelListener = {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Bookmarks)
|
||||
},
|
||||
primaryStateIconResource = R.drawable.ic_bookmark_outline,
|
||||
secondaryStateIconResource = R.drawable.ic_bookmark_filled,
|
||||
tintColorResource = accentBrightTextColor(),
|
||||
primaryLabel = context.getString(R.string.add_label),
|
||||
secondaryLabel = context.getString(R.string.edit_label),
|
||||
isInPrimaryState = { !isCurrentUrlBookmarked }
|
||||
) {
|
||||
handleBookmarkItemTapped()
|
||||
}
|
||||
val bookmarksItem = BrowserMenuImageTextCheckboxButton(
|
||||
imageResource = R.drawable.ic_bookmarks_menu,
|
||||
iconTintColorResource = primaryTextColor(),
|
||||
label = context.getString(R.string.library_bookmarks),
|
||||
labelListener = {
|
||||
onItemTapped.invoke(ToolbarMenu.Item.Bookmarks)
|
||||
},
|
||||
primaryStateIconResource = R.drawable.ic_bookmark_outline,
|
||||
secondaryStateIconResource = R.drawable.ic_bookmark_filled,
|
||||
tintColorResource = accentBrightTextColor(),
|
||||
primaryLabel = context.getString(R.string.add_label),
|
||||
secondaryLabel = context.getString(R.string.edit_label),
|
||||
isInPrimaryState = { !isCurrentUrlBookmarked }
|
||||
) {
|
||||
handleBookmarkItemTapped()
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
val newCoreMenuItems by lazy {
|
||||
val menuItems =
|
||||
listOfNotNull(
|
||||
if (isTopToolbarSelected) menuToolbar else null,
|
||||
if (shouldUseBottomToolbar) null else menuToolbar,
|
||||
newTabItem,
|
||||
BrowserMenuDivider(),
|
||||
bookmarksItem,
|
||||
|
@ -526,8 +535,8 @@ class DefaultToolbarMenu(
|
|||
saveToCollectionItem,
|
||||
BrowserMenuDivider(),
|
||||
settingsItem,
|
||||
if (isTopToolbarSelected) null else BrowserMenuDivider(),
|
||||
if (isTopToolbarSelected) null else menuToolbar
|
||||
if (shouldUseBottomToolbar) BrowserMenuDivider() else null,
|
||||
if (shouldUseBottomToolbar) menuToolbar else null
|
||||
)
|
||||
|
||||
menuItems
|
||||
|
|
|
@ -779,7 +779,7 @@ class HomeFragment : Fragment() {
|
|||
HomeFragmentDirections.actionGlobalSettingsFragment()
|
||||
)
|
||||
}
|
||||
HomeMenu.Item.SyncedTabs -> {
|
||||
HomeMenu.Item.SyncTabs -> {
|
||||
hideOnboardingIfNeeded()
|
||||
nav(
|
||||
R.id.homeFragment,
|
||||
|
@ -842,14 +842,14 @@ class HomeFragment : Fragment() {
|
|||
}
|
||||
)
|
||||
}
|
||||
HomeMenu.Item.Sync -> {
|
||||
HomeMenu.Item.ReconnectSync -> {
|
||||
hideOnboardingIfNeeded()
|
||||
nav(
|
||||
R.id.homeFragment,
|
||||
HomeFragmentDirections.actionGlobalAccountProblemFragment()
|
||||
)
|
||||
}
|
||||
HomeMenu.Item.AddonsManager -> {
|
||||
HomeMenu.Item.Extensions -> {
|
||||
nav(
|
||||
R.id.homeFragment,
|
||||
HomeFragmentDirections.actionGlobalAddonsManagementFragment()
|
||||
|
|
|
@ -13,15 +13,18 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.browser.menu.BrowserMenuBuilder
|
||||
import mozilla.components.browser.menu.BrowserMenuHighlight
|
||||
import mozilla.components.browser.menu.BrowserMenuItem
|
||||
import mozilla.components.browser.menu.ext.getHighlight
|
||||
import mozilla.components.browser.menu.item.BrowserMenuDivider
|
||||
import mozilla.components.browser.menu.item.BrowserMenuHighlightableItem
|
||||
import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
|
||||
import mozilla.components.browser.menu.item.BrowserMenuImageText
|
||||
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
|
||||
import mozilla.components.concept.sync.AccountObserver
|
||||
import mozilla.components.concept.sync.AuthType
|
||||
import mozilla.components.concept.sync.OAuthAccount
|
||||
import mozilla.components.support.ktx.android.content.getColorFromAttr
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.experiments.ExperimentBranch
|
||||
import org.mozilla.fenix.experiments.Experiments
|
||||
|
@ -31,6 +34,7 @@ import org.mozilla.fenix.ext.withExperiment
|
|||
import org.mozilla.fenix.theme.ThemeManager
|
||||
import org.mozilla.fenix.whatsnew.WhatsNew
|
||||
|
||||
@Suppress("LargeClass", "LongMethod")
|
||||
class HomeMenu(
|
||||
private val lifecycleOwner: LifecycleOwner,
|
||||
private val context: Context,
|
||||
|
@ -39,26 +43,29 @@ class HomeMenu(
|
|||
private val onHighlightPresent: (BrowserMenuHighlight) -> Unit = {}
|
||||
) {
|
||||
sealed class Item {
|
||||
data class Back(val viewHistory: Boolean) : Item()
|
||||
data class Forward(val viewHistory: Boolean) : Item()
|
||||
|
||||
object Bookmarks : Item()
|
||||
object History : Item()
|
||||
object Downloads : Item()
|
||||
object Extensions : Item()
|
||||
object SyncTabs : Item()
|
||||
object WhatsNew : Item()
|
||||
object Help : Item()
|
||||
object AddonsManager : Item()
|
||||
object Settings : Item()
|
||||
object SyncedTabs : Item()
|
||||
object History : Item()
|
||||
object Bookmarks : Item()
|
||||
object Downloads : Item()
|
||||
object Quit : Item()
|
||||
object Sync : Item()
|
||||
object ReconnectSync : Item()
|
||||
data class DesktopMode(val checked: Boolean) : Item()
|
||||
}
|
||||
|
||||
private val primaryTextColor =
|
||||
ThemeManager.resolveAttribute(R.attr.primaryText, context)
|
||||
private val syncDisconnectedColor = ThemeManager.resolveAttribute(R.attr.syncDisconnected, context)
|
||||
private val syncDisconnectedBackgroundColor = context.getColorFromAttr(R.attr.syncDisconnectedBackground)
|
||||
private val syncDisconnectedColor =
|
||||
ThemeManager.resolveAttribute(R.attr.syncDisconnected, context)
|
||||
private val syncDisconnectedBackgroundColor =
|
||||
context.getColorFromAttr(R.attr.syncDisconnectedBackground)
|
||||
|
||||
private val menuCategoryTextColor =
|
||||
ThemeManager.resolveAttribute(R.attr.menuCategoryText, context)
|
||||
private val shouldUseBottomToolbar = context.settings().shouldUseBottomToolbar
|
||||
|
||||
// 'Reconnect' and 'Quit' items aren't needed most of the time, so we'll only create the if necessary.
|
||||
|
@ -74,7 +81,7 @@ class HomeMenu(
|
|||
),
|
||||
isHighlighted = { true }
|
||||
) {
|
||||
onItemTapped.invoke(Item.Sync)
|
||||
onItemTapped.invoke(Item.ReconnectSync)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +95,35 @@ class HomeMenu(
|
|||
}
|
||||
}
|
||||
|
||||
private val coreMenuItems by lazy {
|
||||
val menuToolbar by lazy {
|
||||
val back = BrowserMenuItemToolbar.TwoStateButton(
|
||||
primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_back,
|
||||
primaryContentDescription = context.getString(R.string.browser_menu_back),
|
||||
primaryImageTintResource = primaryTextColor,
|
||||
isInPrimaryState = { false },
|
||||
secondaryImageTintResource = ThemeManager.resolveAttribute(R.attr.disabled, context),
|
||||
disableInSecondaryState = true,
|
||||
longClickListener = { onItemTapped.invoke(Item.Back(viewHistory = true)) }
|
||||
) {
|
||||
onItemTapped.invoke(Item.Back(viewHistory = false))
|
||||
}
|
||||
|
||||
val forward = BrowserMenuItemToolbar.TwoStateButton(
|
||||
primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_forward,
|
||||
primaryContentDescription = context.getString(R.string.browser_menu_forward),
|
||||
primaryImageTintResource = primaryTextColor,
|
||||
isInPrimaryState = { false },
|
||||
secondaryImageTintResource = ThemeManager.resolveAttribute(R.attr.disabled, context),
|
||||
disableInSecondaryState = true,
|
||||
longClickListener = { onItemTapped.invoke(Item.Forward(viewHistory = true)) }
|
||||
) {
|
||||
onItemTapped.invoke(Item.Forward(viewHistory = false))
|
||||
}
|
||||
|
||||
BrowserMenuItemToolbar(listOf(back, forward))
|
||||
}
|
||||
|
||||
private val oldCoreMenuItems by lazy {
|
||||
val whatsNewItem = BrowserMenuHighlightableItem(
|
||||
context.getString(R.string.browser_menu_whats_new),
|
||||
R.drawable.ic_whats_new,
|
||||
|
@ -143,7 +178,7 @@ class HomeMenu(
|
|||
R.drawable.ic_addons_extensions,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.AddonsManager)
|
||||
onItemTapped.invoke(Item.Extensions)
|
||||
}
|
||||
|
||||
val settingsItem = BrowserMenuImageText(
|
||||
|
@ -159,7 +194,7 @@ class HomeMenu(
|
|||
R.drawable.ic_synced_tabs,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.SyncedTabs)
|
||||
onItemTapped.invoke(Item.SyncTabs)
|
||||
}
|
||||
|
||||
val helpItem = BrowserMenuImageText(
|
||||
|
@ -178,21 +213,15 @@ class HomeMenu(
|
|||
onItemTapped.invoke(Item.Downloads)
|
||||
}
|
||||
|
||||
val desktopItem = BrowserMenuImageSwitch(
|
||||
imageResource = R.drawable.ic_desktop,
|
||||
label = context.getString(R.string.browser_menu_desktop_site),
|
||||
initialState = { context.settings().openNextTabInDesktopMode }
|
||||
) { checked ->
|
||||
onItemTapped.invoke(Item.DesktopMode(checked))
|
||||
}
|
||||
|
||||
// Only query account manager if it has been initialized.
|
||||
// We don't want to cause its initialization just for this check.
|
||||
val accountAuthItem = if (context.components.backgroundServices.accountManagerAvailableQueue.isReady()) {
|
||||
if (context.components.backgroundServices.accountManager.accountNeedsReauth()) reconnectToSyncItem else null
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val accountAuthItem =
|
||||
if (context.components.backgroundServices.accountManagerAvailableQueue.isReady() &&
|
||||
context.components.backgroundServices.accountManager.accountNeedsReauth()) {
|
||||
reconnectToSyncItem
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val settings = context.components.settings
|
||||
|
||||
|
@ -203,9 +232,6 @@ class HomeMenu(
|
|||
syncedTabsItem,
|
||||
bookmarksItem,
|
||||
historyItem,
|
||||
BrowserMenuDivider(),
|
||||
desktopItem,
|
||||
BrowserMenuDivider(),
|
||||
downloadsItem,
|
||||
BrowserMenuDivider(),
|
||||
addons,
|
||||
|
@ -224,9 +250,157 @@ class HomeMenu(
|
|||
}
|
||||
}
|
||||
|
||||
val desktopItem = BrowserMenuImageSwitch(
|
||||
imageResource = R.drawable.ic_desktop,
|
||||
label = context.getString(R.string.browser_menu_desktop_site),
|
||||
initialState = { context.settings().openNextTabInDesktopMode }
|
||||
) { checked ->
|
||||
onItemTapped.invoke(Item.DesktopMode(checked))
|
||||
}
|
||||
|
||||
@Suppress("ComplexMethod")
|
||||
private fun newCoreMenuItems(): List<BrowserMenuItem> {
|
||||
val experiments = context.components.analytics.experiments
|
||||
val settings = context.components.settings
|
||||
|
||||
val bookmarksIcon = experiments.withExperiment(Experiments.BOOKMARK_ICON) {
|
||||
when (it) {
|
||||
ExperimentBranch.TREATMENT -> R.drawable.ic_bookmark_list
|
||||
else -> R.drawable.ic_bookmark_filled
|
||||
}
|
||||
}
|
||||
val bookmarksItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_bookmarks),
|
||||
bookmarksIcon,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.Bookmarks)
|
||||
}
|
||||
|
||||
// We want to validate that the Nimbus experiments library is working, from the android UI
|
||||
// all the way back to the data science backend. We're not testing the user's preference
|
||||
// or response, we're end-to-end testing the experiments platform.
|
||||
// So here, we're running multiple identical branches with the same treatment, and if the
|
||||
// user isn't targeted, then we get still get the same treatment.
|
||||
// The `let` block is degenerate here, but left here so as to document the form of how experiments
|
||||
// are implemented here.
|
||||
val historyIcon = experiments.withExperiment(Experiments.A_A_NIMBUS_VALIDATION) {
|
||||
when (it) {
|
||||
ExperimentBranch.A1 -> R.drawable.ic_history
|
||||
ExperimentBranch.A2 -> R.drawable.ic_history
|
||||
else -> R.drawable.ic_history
|
||||
}
|
||||
}
|
||||
val historyItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_history),
|
||||
historyIcon,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.History)
|
||||
}
|
||||
|
||||
val downloadsItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_downloads),
|
||||
R.drawable.ic_download,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.Downloads)
|
||||
}
|
||||
|
||||
val extensionsItem = BrowserMenuImageText(
|
||||
context.getString(R.string.browser_menu_add_ons),
|
||||
R.drawable.ic_addons_extensions,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.Extensions)
|
||||
}
|
||||
|
||||
val syncSignInItem = BrowserMenuImageText(
|
||||
context.getString(R.string.library_synced_tabs),
|
||||
R.drawable.ic_synced_tabs,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.SyncTabs)
|
||||
}
|
||||
|
||||
val whatsNewItem = BrowserMenuHighlightableItem(
|
||||
context.getString(R.string.browser_menu_whats_new),
|
||||
R.drawable.ic_whats_new,
|
||||
iconTintColorResource = primaryTextColor,
|
||||
highlight = BrowserMenuHighlight.LowPriority(
|
||||
notificationTint = getColor(context, R.color.whats_new_notification_color)
|
||||
),
|
||||
isHighlighted = { WhatsNew.shouldHighlightWhatsNew(context) }
|
||||
) {
|
||||
onItemTapped.invoke(Item.WhatsNew)
|
||||
}
|
||||
|
||||
val helpItem = BrowserMenuImageText(
|
||||
context.getString(R.string.browser_menu_help),
|
||||
R.drawable.ic_help,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.Help)
|
||||
}
|
||||
|
||||
val settingsItem = BrowserMenuImageText(
|
||||
context.getString(R.string.browser_menu_settings),
|
||||
R.drawable.ic_settings,
|
||||
primaryTextColor
|
||||
) {
|
||||
onItemTapped.invoke(Item.Settings)
|
||||
}
|
||||
|
||||
// Only query account manager if it has been initialized.
|
||||
// We don't want to cause its initialization just for this check.
|
||||
val accountAuthItem =
|
||||
if (context.components.backgroundServices.accountManagerAvailableQueue.isReady() &&
|
||||
context.components.backgroundServices.accountManager.accountNeedsReauth()) {
|
||||
reconnectToSyncItem
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val menuItems = listOfNotNull(
|
||||
if (shouldUseBottomToolbar) null else menuToolbar,
|
||||
bookmarksItem,
|
||||
historyItem,
|
||||
downloadsItem,
|
||||
extensionsItem,
|
||||
syncSignInItem,
|
||||
accountAuthItem,
|
||||
BrowserMenuDivider(),
|
||||
desktopItem,
|
||||
BrowserMenuDivider(),
|
||||
whatsNewItem,
|
||||
helpItem,
|
||||
settingsItem,
|
||||
if (settings.shouldDeleteBrowsingDataOnQuit) quitItem else null,
|
||||
if (shouldUseBottomToolbar) BrowserMenuDivider() else null,
|
||||
if (shouldUseBottomToolbar) menuToolbar else null
|
||||
).also { items ->
|
||||
items.getHighlight()?.let { onHighlightPresent(it) }
|
||||
}
|
||||
|
||||
return menuItems
|
||||
}
|
||||
|
||||
init {
|
||||
val menuItems = if (FeatureFlags.toolbarMenuFeature) {
|
||||
newCoreMenuItems()
|
||||
} else {
|
||||
oldCoreMenuItems
|
||||
}
|
||||
|
||||
// Report initial state.
|
||||
onMenuBuilderChanged(BrowserMenuBuilder(coreMenuItems))
|
||||
onMenuBuilderChanged(BrowserMenuBuilder(menuItems))
|
||||
|
||||
val menuItemsWithReconnectItem = if (FeatureFlags.toolbarMenuFeature) {
|
||||
menuItems
|
||||
} else {
|
||||
// reconnect item is manually added to the beginning of the list
|
||||
listOf(reconnectToSyncItem) + menuItems
|
||||
}
|
||||
|
||||
// Observe account state changes, and update menu item builder with a new set of items.
|
||||
context.components.backgroundServices.accountManagerAvailableQueue.runIfReadyOrQueue {
|
||||
|
@ -237,9 +411,11 @@ class HomeMenu(
|
|||
context.components.backgroundServices.accountManager.register(object : AccountObserver {
|
||||
override fun onAuthenticationProblems() {
|
||||
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
|
||||
onMenuBuilderChanged(BrowserMenuBuilder(
|
||||
listOf(reconnectToSyncItem) + coreMenuItems
|
||||
))
|
||||
onMenuBuilderChanged(
|
||||
BrowserMenuBuilder(
|
||||
menuItemsWithReconnectItem
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,7 +423,7 @@ class HomeMenu(
|
|||
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
|
||||
onMenuBuilderChanged(
|
||||
BrowserMenuBuilder(
|
||||
coreMenuItems
|
||||
menuItems
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -257,7 +433,7 @@ class HomeMenu(
|
|||
lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
|
||||
onMenuBuilderChanged(
|
||||
BrowserMenuBuilder(
|
||||
coreMenuItems
|
||||
menuItems
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -187,7 +187,6 @@ class DefaultBrowserToolbarMenuControllerTest {
|
|||
@Test
|
||||
fun `WHEN open in Fenix menu item is pressed THEN menu item is handled correctly`() = runBlockingTest {
|
||||
if (!FeatureFlags.toolbarMenuFeature) {
|
||||
|
||||
val customTab = createCustomTab("https://mozilla.org")
|
||||
browserStore.dispatch(CustomTabListAction.AddCustomTabAction(customTab)).joinBlocking()
|
||||
val controller = createController(
|
||||
|
@ -207,33 +206,7 @@ class DefaultBrowserToolbarMenuControllerTest {
|
|||
verify { activity.finishAndRemoveTask() }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN quit menu item is pressed THEN menu item is handled correctly`() = runBlockingTest {
|
||||
if (!FeatureFlags.toolbarMenuFeature) {
|
||||
val item = ToolbarMenu.Item.Quit
|
||||
val testScope = this
|
||||
|
||||
val controller = createController(scope = this, store = browserStore)
|
||||
|
||||
controller.handleToolbarItemInteraction(item)
|
||||
|
||||
verify { deleteAndQuit(activity, testScope, null) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handleToolbarOpenInAppPress() = runBlockingTest {
|
||||
if (!FeatureFlags.toolbarMenuFeature) {
|
||||
val item = ToolbarMenu.Item.OpenInApp
|
||||
|
||||
val controller = createController(scope = this, store = browserStore)
|
||||
|
||||
controller.handleToolbarItemInteraction(item)
|
||||
|
||||
verify { settings.openInAppOpened = true }
|
||||
}
|
||||
}
|
||||
// todo === End ===
|
||||
|
||||
@Test
|
||||
fun `WHEN reader mode menu item is pressed THEN handle appearance change`() = runBlockingTest {
|
||||
|
@ -246,7 +219,18 @@ class DefaultBrowserToolbarMenuControllerTest {
|
|||
verify { readerModeController.showControls() }
|
||||
verify { metrics.track(Event.ReaderModeAppearanceOpened) }
|
||||
}
|
||||
// todo === End ===
|
||||
|
||||
@Test
|
||||
fun `WHEN quit menu item is pressed THEN menu item is handled correctly`() = runBlockingTest {
|
||||
val item = ToolbarMenu.Item.Quit
|
||||
val testScope = this
|
||||
|
||||
val controller = createController(scope = this, store = browserStore)
|
||||
|
||||
controller.handleToolbarItemInteraction(item)
|
||||
|
||||
verify { deleteAndQuit(activity, testScope, null) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN backwards nav menu item is pressed THEN the session navigates back with active session`() = runBlockingTest {
|
||||
|
|
|
@ -6,38 +6,34 @@ package org.mozilla.fenix.toolbar
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.spyk
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import mozilla.components.browser.state.action.ContentAction
|
||||
import mozilla.components.browser.state.action.TabListAction
|
||||
import mozilla.components.browser.state.selector.findTab
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.createTab
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.concept.storage.BookmarksStorage
|
||||
import mozilla.components.support.test.ext.joinBlocking
|
||||
import mozilla.components.support.test.rule.MainCoroutineRule
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.components.toolbar.DefaultToolbarMenu
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class DefaultToolbarMenuTest {
|
||||
|
||||
private lateinit var store: BrowserStore
|
||||
private lateinit var lifecycleOwner: MockedLifecycleOwner
|
||||
private lateinit var lifecycleOwner: LifecycleOwner
|
||||
private lateinit var toolbarMenu: DefaultToolbarMenu
|
||||
private lateinit var context: Context
|
||||
private lateinit var bookmarksStorage: BookmarksStorage
|
||||
|
@ -52,8 +48,11 @@ class DefaultToolbarMenuTest {
|
|||
mockkStatic(Uri::class)
|
||||
every { Uri.parse(any()) } returns mockk(relaxed = true)
|
||||
|
||||
lifecycleOwner = mockk(relaxed = true)
|
||||
context = mockk(relaxed = true)
|
||||
|
||||
every { context.theme } returns mockk(relaxed = true)
|
||||
|
||||
bookmarksStorage = mockk(relaxed = true)
|
||||
store = BrowserStore(
|
||||
BrowserState(
|
||||
|
@ -63,20 +62,6 @@ class DefaultToolbarMenuTest {
|
|||
), selectedTabId = "1"
|
||||
)
|
||||
)
|
||||
lifecycleOwner = MockedLifecycleOwner(Lifecycle.State.STARTED)
|
||||
|
||||
toolbarMenu = spyk(DefaultToolbarMenu(
|
||||
context = context,
|
||||
store = store,
|
||||
hasAccountProblem = false,
|
||||
shouldReverseItems = false,
|
||||
onItemTapped = { },
|
||||
lifecycleOwner = lifecycleOwner,
|
||||
bookmarksStorage = bookmarksStorage,
|
||||
isPinningSupported = false
|
||||
))
|
||||
|
||||
every { toolbarMenu.updateCurrentUrlIsBookmarked(any()) } returns Unit
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -84,32 +69,84 @@ class DefaultToolbarMenuTest {
|
|||
unmockkStatic(Uri::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN url changes THEN bookmarked state is updated`() {
|
||||
toolbarMenu.registerForIsBookmarkedUpdates()
|
||||
private fun createMenu() {
|
||||
toolbarMenu = spyk(DefaultToolbarMenu(
|
||||
context = context,
|
||||
store = store,
|
||||
hasAccountProblem = false,
|
||||
onItemTapped = { },
|
||||
lifecycleOwner = lifecycleOwner,
|
||||
bookmarksStorage = bookmarksStorage,
|
||||
isPinningSupported = false
|
||||
))
|
||||
|
||||
val newUrl = "https://mozilla.org"
|
||||
|
||||
store.dispatch(ContentAction.UpdateUrlAction("1", newUrl)).joinBlocking()
|
||||
verify(exactly = 1) { toolbarMenu.updateCurrentUrlIsBookmarked(newUrl) }
|
||||
every { toolbarMenu.updateCurrentUrlIsBookmarked(any()) } returns mockk()
|
||||
every { toolbarMenu.shouldShowOpenInApp() } returns mockk()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN selected tab changes THEN bookmarked state is updated`() {
|
||||
toolbarMenu.registerForIsBookmarkedUpdates()
|
||||
fun `WHEN the bottom toolbar is set THEN the first item in the list is not the navigation`() {
|
||||
if (FeatureFlags.toolbarMenuFeature) {
|
||||
every { context.settings().shouldUseBottomToolbar } returns true
|
||||
createMenu()
|
||||
|
||||
val newSelectedTab = store.state.findTab("2")
|
||||
assertNotNull(newSelectedTab)
|
||||
val menuItems = toolbarMenu.newCoreMenuItems
|
||||
assertNotNull(menuItems)
|
||||
|
||||
store.dispatch(TabListAction.SelectTabAction(newSelectedTab!!.id)).joinBlocking()
|
||||
verify(exactly = 1) { toolbarMenu.updateCurrentUrlIsBookmarked(newSelectedTab.content.url) }
|
||||
}
|
||||
val firstItem = menuItems[0]
|
||||
val newTabItem = toolbarMenu.newTabItem
|
||||
|
||||
internal class MockedLifecycleOwner(initialState: Lifecycle.State) : LifecycleOwner {
|
||||
val lifecycleRegistry = LifecycleRegistry(this).apply {
|
||||
currentState = initialState
|
||||
assertEquals(newTabItem, firstItem)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLifecycle(): Lifecycle = lifecycleRegistry
|
||||
@Test
|
||||
fun `WHEN the top toolbar is set THEN the first item in the list is the navigation`() {
|
||||
if (FeatureFlags.toolbarMenuFeature) {
|
||||
every { context.settings().shouldUseBottomToolbar } returns false
|
||||
createMenu()
|
||||
|
||||
val menuItems = toolbarMenu.newCoreMenuItems
|
||||
assertNotNull(menuItems)
|
||||
|
||||
val firstItem = menuItems[0]
|
||||
val navToolbar = toolbarMenu.menuToolbar
|
||||
|
||||
assertEquals(navToolbar, firstItem)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN the bottom toolbar is set THEN the nav menu should be the last item`() {
|
||||
if (FeatureFlags.toolbarMenuFeature) {
|
||||
every { context.settings().shouldUseBottomToolbar } returns true
|
||||
|
||||
createMenu()
|
||||
|
||||
val menuItems = toolbarMenu.newCoreMenuItems
|
||||
assertNotNull(menuItems)
|
||||
|
||||
val lastItem = menuItems[menuItems.size - 1]
|
||||
val navToolbar = toolbarMenu.menuToolbar
|
||||
|
||||
assertEquals(navToolbar, lastItem)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN the top toolbar is set THEN settings should be the last item`() {
|
||||
if (FeatureFlags.toolbarMenuFeature) {
|
||||
every { context.settings().shouldUseBottomToolbar } returns false
|
||||
|
||||
createMenu()
|
||||
|
||||
val menuItems = toolbarMenu.newCoreMenuItems
|
||||
assertNotNull(menuItems)
|
||||
|
||||
val lastItem = menuItems[menuItems.size - 1]
|
||||
val settingsItem = toolbarMenu.settingsItem
|
||||
|
||||
assertEquals(settingsItem, lastItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user