mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-03 23:15:31 +00:00
For #23424 - Part 2: Add context menu for contile top sites
This commit is contained in:
parent
532bb9a38a
commit
42ac6feb0c
@ -120,6 +120,16 @@ interface SessionControlController {
|
||||
*/
|
||||
fun handleSelectTopSite(topSite: TopSite)
|
||||
|
||||
/**
|
||||
* @see [TopSiteInteractor.onSettingsClicked]
|
||||
*/
|
||||
fun handleTopSiteSettingsClicked()
|
||||
|
||||
/**
|
||||
* @see [TopSiteInteractor.onSponsorPrivacyClicked]
|
||||
*/
|
||||
fun handleSponsorPrivacyClicked()
|
||||
|
||||
/**
|
||||
* @see [OnboardingInteractor.onStartBrowsingClicked]
|
||||
*/
|
||||
@ -414,6 +424,21 @@ class DefaultSessionControlController(
|
||||
activity.openToBrowser(BrowserDirection.FromHome)
|
||||
}
|
||||
|
||||
override fun handleTopSiteSettingsClicked() {
|
||||
navController.nav(
|
||||
R.id.homeFragment,
|
||||
HomeFragmentDirections.actionGlobalHomeSettingsFragment()
|
||||
)
|
||||
}
|
||||
|
||||
override fun handleSponsorPrivacyClicked() {
|
||||
activity.openToBrowserAndLoad(
|
||||
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic(SupportUtils.SumoTopic.SPONSOR_PRIVACY),
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromHome
|
||||
)
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun getAvailableSearchEngines() =
|
||||
activity.components.core.store.state.search.searchEngines +
|
||||
|
@ -213,6 +213,18 @@ interface TopSiteInteractor {
|
||||
*/
|
||||
fun onSelectTopSite(topSite: TopSite)
|
||||
|
||||
/**
|
||||
* Navigates to the Homepage Settings. Called when an user clicks on the "Settings" top site
|
||||
* menu item.
|
||||
*/
|
||||
fun onSettingsClicked()
|
||||
|
||||
/**
|
||||
* Opens the sponsor privacy support articles. Called when an user clicks on the
|
||||
* "Our sponsors & your privacy" top site menu item.
|
||||
*/
|
||||
fun onSponsorPrivacyClicked()
|
||||
|
||||
/**
|
||||
* Called when top site menu is opened.
|
||||
*/
|
||||
@ -301,6 +313,14 @@ class SessionControlInteractor(
|
||||
controller.handleSelectTopSite(topSite)
|
||||
}
|
||||
|
||||
override fun onSettingsClicked() {
|
||||
controller.handleTopSiteSettingsClicked()
|
||||
}
|
||||
|
||||
override fun onSponsorPrivacyClicked() {
|
||||
controller.handleSponsorPrivacyClicked()
|
||||
}
|
||||
|
||||
override fun onStartBrowsingClicked() {
|
||||
controller.handleStartBrowsingClicked()
|
||||
}
|
||||
|
@ -7,41 +7,80 @@ package org.mozilla.fenix.home.topsites
|
||||
import android.content.Context
|
||||
import mozilla.components.browser.menu.BrowserMenuBuilder
|
||||
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
|
||||
import mozilla.components.feature.top.sites.TopSite
|
||||
import org.mozilla.fenix.R
|
||||
|
||||
/**
|
||||
* Helper class for building a context menu for a top site item.
|
||||
*
|
||||
* @property context An Android context.
|
||||
* @property topSite The [TopSite] to show the context menu for.
|
||||
* @property onItemTapped Callback invoked when the user taps on a menu item.
|
||||
*/
|
||||
class TopSiteItemMenu(
|
||||
private val context: Context,
|
||||
private val isPinnedSite: Boolean,
|
||||
private val topSite: TopSite,
|
||||
private val onItemTapped: (Item) -> Unit = {}
|
||||
) {
|
||||
sealed class Item {
|
||||
object OpenInPrivateTab : Item()
|
||||
object RenameTopSite : Item()
|
||||
object RemoveTopSite : Item()
|
||||
object Settings : Item()
|
||||
object SponsorPrivacy : Item()
|
||||
}
|
||||
|
||||
val menuBuilder by lazy { BrowserMenuBuilder(menuItems) }
|
||||
|
||||
private val menuItems by lazy {
|
||||
val isPinnedSite = topSite is TopSite.Pinned || topSite is TopSite.Default
|
||||
val isProvidedSite = topSite is TopSite.Provided
|
||||
|
||||
listOfNotNull(
|
||||
SimpleBrowserMenuItem(
|
||||
context.getString(R.string.bookmark_menu_open_in_private_tab_button)
|
||||
) {
|
||||
onItemTapped.invoke(Item.OpenInPrivateTab)
|
||||
},
|
||||
if (isPinnedSite) SimpleBrowserMenuItem(
|
||||
context.getString(R.string.rename_top_site)
|
||||
) {
|
||||
onItemTapped.invoke(Item.RenameTopSite)
|
||||
} else null,
|
||||
SimpleBrowserMenuItem(
|
||||
if (isPinnedSite) {
|
||||
context.getString(R.string.remove_top_site)
|
||||
} else {
|
||||
context.getString(R.string.delete_from_history)
|
||||
if (isPinnedSite) {
|
||||
SimpleBrowserMenuItem(
|
||||
context.getString(R.string.rename_top_site)
|
||||
) {
|
||||
onItemTapped.invoke(Item.RenameTopSite)
|
||||
}
|
||||
) {
|
||||
onItemTapped.invoke(Item.RemoveTopSite)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
if (!isProvidedSite) {
|
||||
SimpleBrowserMenuItem(
|
||||
if (isPinnedSite) {
|
||||
context.getString(R.string.remove_top_site)
|
||||
} else {
|
||||
context.getString(R.string.delete_from_history)
|
||||
}
|
||||
) {
|
||||
onItemTapped.invoke(Item.RemoveTopSite)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
},
|
||||
if (isProvidedSite) {
|
||||
SimpleBrowserMenuItem(
|
||||
context.getString(R.string.top_sites_menu_settings)
|
||||
) {
|
||||
onItemTapped.invoke(Item.Settings)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
},
|
||||
if (isProvidedSite) {
|
||||
SimpleBrowserMenuItem(
|
||||
context.getString(R.string.top_sites_menu_sponsor_privacy)
|
||||
) {
|
||||
onItemTapped.invoke(Item.SponsorPrivacy)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class TopSiteItemViewHolder(
|
||||
|
||||
val topSiteMenu = TopSiteItemMenu(
|
||||
context = view.context,
|
||||
isPinnedSite = topSite is TopSite.Pinned || topSite is TopSite.Default
|
||||
topSite = topSite
|
||||
) { item ->
|
||||
when (item) {
|
||||
is TopSiteItemMenu.Item.OpenInPrivateTab -> interactor.onOpenInPrivateTabClicked(
|
||||
@ -55,12 +55,16 @@ class TopSiteItemViewHolder(
|
||||
is TopSiteItemMenu.Item.RemoveTopSite -> interactor.onRemoveTopSiteClicked(
|
||||
topSite
|
||||
)
|
||||
is TopSiteItemMenu.Item.Settings -> interactor.onSettingsClicked()
|
||||
is TopSiteItemMenu.Item.SponsorPrivacy -> interactor.onSponsorPrivacyClicked()
|
||||
}
|
||||
}
|
||||
val menu = topSiteMenu.menuBuilder.build(view.context).show(anchor = it)
|
||||
|
||||
it.setOnTouchListener @SuppressLint("ClickableViewAccessibility") { v, event ->
|
||||
onTouchEvent(v, event, menu)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ object SupportUtils {
|
||||
CUSTOM_SEARCH_ENGINES("custom-search-engines"),
|
||||
SYNC_SETUP("how-set-firefox-sync-firefox-android"),
|
||||
QR_CAMERA_ACCESS("qr-camera-access"),
|
||||
SMARTBLOCK("smartblock-enhanced-tracking-protection")
|
||||
SMARTBLOCK("smartblock-enhanced-tracking-protection"),
|
||||
SPONSOR_PRIVACY("sponsor-privacy")
|
||||
}
|
||||
|
||||
enum class MozillaPage(internal val path: String) {
|
||||
|
@ -1901,6 +1901,10 @@
|
||||
<string name="top_sites_rename_dialog_ok">OK</string>
|
||||
<!-- Dialog button text for canceling the rename top site prompt. -->
|
||||
<string name="top_sites_rename_dialog_cancel">Cancel</string>
|
||||
<!-- Text for the menu button to open the homepage settings. -->
|
||||
<string name="top_sites_menu_settings">Settings</string>
|
||||
<!-- Text for the menu button to navigate to sponsors and privacy support articles. '&' is replaced with the ampersand symbol: & -->
|
||||
<string name="top_sites_menu_sponsor_privacy">Our sponsors & your privacy</string>
|
||||
|
||||
<!-- Inactive tabs in the tabs tray -->
|
||||
<!-- Title text displayed in the tabs tray when a tab has been unused for 14 days. -->
|
||||
|
@ -931,6 +931,33 @@ class DefaultSessionControlControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN handleTopSiteSettingsClicked is called THEN navigate to the HomeSettingsFragment`() {
|
||||
createController().handleTopSiteSettingsClicked()
|
||||
|
||||
verify {
|
||||
navController.navigate(
|
||||
match<NavDirections> {
|
||||
it.actionId == R.id.action_global_homeSettingsFragment
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN handleSponsorPrivacyClicked is called THEN `() {
|
||||
createController().handleSponsorPrivacyClicked()
|
||||
|
||||
verify {
|
||||
activity.openToBrowserAndLoad(
|
||||
searchTermOrURL = SupportUtils.getGenericSumoURLForTopic(SupportUtils.SumoTopic.SPONSOR_PRIVACY),
|
||||
newTab = true,
|
||||
from = BrowserDirection.FromHome
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createController(
|
||||
hideOnboarding: () -> Unit = { },
|
||||
registerCollectionStorageObserver: () -> Unit = { },
|
||||
|
@ -205,6 +205,18 @@ class SessionControlInteractorTest {
|
||||
verify { controller.handlePrivateModeButtonClicked(newMode, hasBeenOnboarded) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onSettingsClicked is called THEN handleTopSiteSettingsClicked is called`() {
|
||||
interactor.onSettingsClicked()
|
||||
verify { controller.handleTopSiteSettingsClicked() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onSponsorPrivacyClicked is called THEN handleSponsorPrivacyClicked is called`() {
|
||||
interactor.onSponsorPrivacyClicked()
|
||||
verify { controller.handleSponsorPrivacyClicked() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN a PocketStoriesInteractor WHEN stories are shown THEN handle it in a PocketStoriesController`() {
|
||||
val shownStories: List<PocketRecommendedStory> = mockk()
|
||||
|
Loading…
Reference in New Issue
Block a user