diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
index 1cec01474..497a187d7 100644
--- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
@@ -17,13 +17,16 @@ import mozilla.components.feature.media.ext.pauseIfPlaying
import mozilla.components.feature.media.ext.playIfPaused
import mozilla.components.feature.media.state.MediaStateMachine
import mozilla.components.feature.tab.collections.TabCollection
+import mozilla.components.feature.top.sites.TopSite
import mozilla.components.feature.tab.collections.Tab as ComponentTab
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
+import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.components.TabCollectionStorage
+import org.mozilla.fenix.components.TopSiteStorage
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
@@ -82,6 +85,11 @@ interface SessionControlController {
*/
fun handleDeleteCollectionTapped(collection: TabCollection)
+ /**
+ * @see [TopSiteInteractor.onOpenInPrivateTabClicked]
+ */
+ fun handleOpenInPrivateTabClicked(topSite: TopSite)
+
/**
* @see [TabSessionInteractor.onPauseMediaClicked]
*/
@@ -97,6 +105,11 @@ interface SessionControlController {
*/
fun handlePrivateBrowsingLearnMoreClicked()
+ /**
+ * @see [TopSiteInteractor.onRemoveTopSiteClicked]
+ */
+ fun handleRemoveTopSiteClicked(topSite: TopSite)
+
/**
* @see [CollectionInteractor.onRenameCollectionTapped]
*/
@@ -133,7 +146,7 @@ interface SessionControlController {
fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean)
}
-@SuppressWarnings("TooManyFunctions")
+@SuppressWarnings("TooManyFunctions", "LargeClass")
class DefaultSessionControlController(
private val activity: HomeActivity,
private val store: HomeFragmentStore,
@@ -156,6 +169,8 @@ class DefaultSessionControlController(
get() = activity.components.core.sessionManager
private val tabCollectionStorage: TabCollectionStorage
get() = activity.components.core.tabCollectionStorage
+ private val topSiteStorage: TopSiteStorage
+ get() = activity.components.core.topSiteStorage
override fun handleCloseTab(sessionId: String) {
closeTab.invoke(sessionId)
@@ -244,6 +259,17 @@ class DefaultSessionControlController(
showDeleteCollectionPrompt(collection)
}
+ override fun handleOpenInPrivateTabClicked(topSite: TopSite) {
+ with(activity) {
+ browsingModeManager.mode = BrowsingMode.Private
+ openToBrowserAndLoad(
+ searchTermOrURL = topSite.url,
+ newTab = true,
+ from = BrowserDirection.FromHome
+ )
+ }
+ }
+
override fun handlePauseMediaClicked() {
MediaStateMachine.state.pauseIfPlaying()
}
@@ -261,6 +287,12 @@ class DefaultSessionControlController(
)
}
+ override fun handleRemoveTopSiteClicked(topSite: TopSite) {
+ lifecycleScope.launch(Dispatchers.IO) {
+ topSiteStorage.removeTopSite(topSite)
+ }
+ }
+
override fun handleRenameCollectionTapped(collection: TabCollection) {
showCollectionCreationFragment(
step = SaveCollectionStep.RenameCollection,
diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
index 2fa4bf0d7..0c4581cdd 100644
--- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
@@ -7,6 +7,7 @@ package org.mozilla.fenix.home.sessioncontrol
import android.view.View
import mozilla.components.feature.tab.collections.Tab
import mozilla.components.feature.tab.collections.TabCollection
+import mozilla.components.feature.top.sites.TopSite
/**
* Interface for collection related actions in the [SessionControlInteractor].
@@ -153,6 +154,21 @@ interface TabSessionInteractor {
* Interface for top site related actions in the [SessionControlInteractor].
*/
interface TopSiteInteractor {
+ /**
+ * Opens the given top site in private mode. Called when an user clicks on the "Open in private
+ * tab" top site menu item.
+ *
+ * @param topSite The top site that will be open in private mode.
+ */
+ fun onOpenInPrivateTabClicked(topSite: TopSite)
+
+ /**
+ * Removes the given top site. Called when an user clicks on the "Remove" top site menu item.
+ *
+ * @param topSite The top site that will be removed.
+ */
+ fun onRemoveTopSiteClicked(topSite: TopSite)
+
/**
* Selects the given top site. Called when a user clicks on a top site.
*
@@ -202,6 +218,10 @@ class SessionControlInteractor(
controller.handleDeleteCollectionTapped(collection)
}
+ override fun onOpenInPrivateTabClicked(topSite: TopSite) {
+ controller.handleOpenInPrivateTabClicked(topSite)
+ }
+
override fun onPauseMediaClicked() {
controller.handlePauseMediaClicked()
}
@@ -214,6 +234,10 @@ class SessionControlInteractor(
controller.handlePrivateBrowsingLearnMoreClicked()
}
+ override fun onRemoveTopSiteClicked(topSite: TopSite) {
+ controller.handleRemoveTopSiteClicked(topSite)
+ }
+
override fun onRenameCollectionTapped(collection: TabCollection) {
controller.handleRenameCollectionTapped(collection)
}
diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt
index a668af173..2d5cefb14 100644
--- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/topsites/TopSiteItemViewHolder.kt
@@ -4,10 +4,13 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders.topsites
+import android.content.Context
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.top_site_item.view.*
import mozilla.components.feature.top.sites.TopSite
+import mozilla.components.browser.menu.BrowserMenuBuilder
+import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.loadIntoView
@@ -18,11 +21,26 @@ class TopSiteItemViewHolder(
private val interactor: TopSiteInteractor
) : RecyclerView.ViewHolder(view) {
private lateinit var topSite: TopSite
+ private var topSiteMenu: TopSiteItemMenu
init {
+ topSiteMenu = TopSiteItemMenu(view.context) {
+ when (it) {
+ is TopSiteItemMenu.Item.OpenInPrivateTab -> interactor.onOpenInPrivateTabClicked(
+ topSite
+ )
+ is TopSiteItemMenu.Item.RemoveTopSite -> interactor.onRemoveTopSiteClicked(topSite)
+ }
+ }
+
view.top_site_item.setOnClickListener {
interactor.onSelectTopSite(topSite.url)
}
+
+ view.top_site_item.setOnLongClickListener() {
+ topSiteMenu.menuBuilder.build(view.context).show(anchor = it)
+ return@setOnLongClickListener true
+ }
}
fun bind(topSite: TopSite) {
@@ -35,3 +53,31 @@ class TopSiteItemViewHolder(
const val LAYOUT_ID = R.layout.top_site_item
}
}
+
+class TopSiteItemMenu(
+ private val context: Context,
+ private val onItemTapped: (Item) -> Unit = {}
+) {
+ sealed class Item {
+ object OpenInPrivateTab : Item()
+ object RemoveTopSite : Item()
+ }
+
+ val menuBuilder by lazy { BrowserMenuBuilder(menuItems) }
+
+ private val menuItems by lazy {
+ listOf(
+ SimpleBrowserMenuItem(
+ context.getString(R.string.bookmark_menu_open_in_private_tab_button)
+ ) {
+ onItemTapped.invoke(Item.OpenInPrivateTab)
+ },
+
+ SimpleBrowserMenuItem(
+ context.getString(R.string.remove_top_site)
+ ) {
+ onItemTapped.invoke(Item.RemoveTopSite)
+ }
+ )
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b0aa7eb05..aa93f3aed 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -426,6 +426,8 @@
Rename collection
Open tabs
+
+ Remove