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