diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt index de1cbf824..3bb573b61 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt @@ -94,6 +94,7 @@ class DefaultBrowserToolbarMenuController( override fun handleToolbarItemInteraction(item: ToolbarMenu.Item) { val sessionUseCases = activity.components.useCases.sessionUseCases val customTabUseCases = activity.components.useCases.customTabsUseCases + val tabsUseCases = activity.components.useCases.tabsUseCases trackToolbarItemInteraction(item) when (item) { @@ -254,6 +255,13 @@ class DefaultBrowserToolbarMenuController( ) } } + is ToolbarMenu.Item.OpenInRegularTab -> { + currentSession?.let { session -> + getProperUrl(session)?.let { url -> + tabsUseCases.migratePrivateTabUseCase.invoke(session.id, url) + } + } + } is ToolbarMenu.Item.AddToTopSites -> { scope.launch { val context = snackbarParent.context @@ -443,6 +451,8 @@ class DefaultBrowserToolbarMenuController( } else { Events.browserMenuAction.record(Events.BrowserMenuActionExtra("desktop_view_off")) } + is ToolbarMenu.Item.OpenInRegularTab -> + Events.browserMenuAction.record(Events.BrowserMenuActionExtra("open_in_regular_tab")) is ToolbarMenu.Item.FindInPage -> Events.browserMenuAction.record(Events.BrowserMenuActionExtra("find_in_page")) is ToolbarMenu.Item.SaveToCollection -> diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt index ac0f788e3..5085d5423 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt @@ -35,12 +35,14 @@ import mozilla.components.feature.webcompat.reporter.WebCompatReporterFeature import mozilla.components.lib.state.ext.flowScoped import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged +import org.mozilla.fenix.Config import org.mozilla.fenix.R import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.theme.ThemeManager +import org.mozilla.fenix.utils.Settings /** * Builds the toolbar object used with the 3-dot menu in the browser fragment. @@ -168,6 +170,19 @@ open class DefaultToolbarMenu( selectedSession != null && isPinningSupported && context.components.useCases.webAppUseCases.isInstallable() + /** + * Should the "Open in regular tab" menu item be visible? + */ + @VisibleForTesting(otherwise = PRIVATE) + fun shouldShowOpenInRegularTab(): Boolean = selectedSession?.let { session -> + // This feature is gated behind Nightly for the time being. + Config.channel.isNightlyOrDebug && + // This feature is explicitly for users opening links in private tabs. + context.settings().openLinksInAPrivateTab && + // and is only visible in private tabs. + session.content.private + } ?: false + @VisibleForTesting(otherwise = PRIVATE) fun shouldShowOpenInApp(): Boolean = selectedSession?.let { session -> val appLink = context.components.useCases.appLinksUseCases.appLinkRedirect @@ -243,6 +258,13 @@ open class DefaultToolbarMenu( onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) } + private val openInRegularTabItem = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_open_in_regular_tab), + imageResource = R.drawable.ic_open_in_regular_tab, + ) { + onItemTapped.invoke(ToolbarMenu.Item.OpenInRegularTab) + } + private val customizeReaderView = BrowserMenuImageText( label = context.getString(R.string.browser_menu_customize_reader_view), imageResource = R.drawable.ic_readermode_appearance, @@ -384,6 +406,7 @@ open class DefaultToolbarMenu( BrowserMenuDivider(), findInPageItem, desktopSiteItem, + openInRegularTabItem.apply { visible = ::shouldShowOpenInRegularTab }, customizeReaderView.apply { visible = ::shouldShowReaderViewCustomization }, openInApp.apply { visible = ::shouldShowOpenInApp }, reportSiteIssuePlaceholder, diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt index a4f41ccdb..120026d3c 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt @@ -12,6 +12,11 @@ interface ToolbarMenu { sealed class Item { object Settings : Item() data class RequestDesktop(val isChecked: Boolean) : Item() + + /** + * Opens the current private tabs in a regular tab. + */ + object OpenInRegularTab : Item() object FindInPage : Item() object Share : Item() data class Back(val viewHistory: Boolean) : Item() diff --git a/app/src/main/res/drawable/ic_open_in_regular_tab.xml b/app/src/main/res/drawable/ic_open_in_regular_tab.xml new file mode 100644 index 000000000..79c44fdcf --- /dev/null +++ b/app/src/main/res/drawable/ic_open_in_regular_tab.xml @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 95fa614f2..979264919 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -199,6 +199,8 @@ Library Desktop site + + Open in regular tab Add to Home screen