Fix #8651 - Add new menu actions for a history item
We'll now also support: - Copy url - Share to another FXA device - Open in new tab - Open in private tabmaster
parent
b77f92f9d1
commit
a1cdd31f0c
|
@ -6,25 +6,40 @@
|
|||
|
||||
package org.mozilla.fenix.library.history
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.res.Resources
|
||||
import androidx.navigation.NavController
|
||||
import mozilla.components.concept.engine.prompt.ShareData
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
|
||||
interface HistoryController {
|
||||
fun handleOpen(item: HistoryItem)
|
||||
fun handleOpen(item: HistoryItem, mode: BrowsingMode? = null)
|
||||
fun handleSelect(item: HistoryItem)
|
||||
fun handleDeselect(item: HistoryItem)
|
||||
fun handleBackPressed(): Boolean
|
||||
fun handleModeSwitched()
|
||||
fun handleDeleteAll()
|
||||
fun handleDeleteSome(items: Set<HistoryItem>)
|
||||
fun handleCopyUrl(item: HistoryItem)
|
||||
fun handleShare(item: HistoryItem)
|
||||
}
|
||||
|
||||
class DefaultHistoryController(
|
||||
private val store: HistoryFragmentStore,
|
||||
private val openToBrowser: (item: HistoryItem) -> Unit,
|
||||
private val navController: NavController,
|
||||
private val resources: Resources,
|
||||
private val snackbar: FenixSnackbar,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
private val openToBrowser: (item: HistoryItem, mode: BrowsingMode?) -> Unit,
|
||||
private val displayDeleteAll: () -> Unit,
|
||||
private val invalidateOptionsMenu: () -> Unit,
|
||||
private val deleteHistoryItems: (Set<HistoryItem>) -> Unit
|
||||
) : HistoryController {
|
||||
override fun handleOpen(item: HistoryItem) {
|
||||
openToBrowser(item)
|
||||
override fun handleOpen(item: HistoryItem, mode: BrowsingMode?) {
|
||||
openToBrowser(item, mode)
|
||||
}
|
||||
|
||||
override fun handleSelect(item: HistoryItem) {
|
||||
|
@ -55,4 +70,21 @@ class DefaultHistoryController(
|
|||
override fun handleDeleteSome(items: Set<HistoryItem>) {
|
||||
deleteHistoryItems.invoke(items)
|
||||
}
|
||||
|
||||
override fun handleCopyUrl(item: HistoryItem) {
|
||||
val urlClipData = ClipData.newPlainText(item.url, item.url)
|
||||
clipboardManager.primaryClip = urlClipData
|
||||
with(snackbar) {
|
||||
setText(resources.getString(R.string.url_copied))
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleShare(item: HistoryItem) {
|
||||
navController.navigate(
|
||||
HistoryFragmentDirections.actionHistoryFragmentToShareFragment(
|
||||
data = arrayOf(ShareData(url = item.url, title = item.title))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package org.mozilla.fenix.library.history
|
||||
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context.CLIPBOARD_SERVICE
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
|
@ -15,6 +17,7 @@ import android.view.ViewGroup
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import kotlinx.android.synthetic.main.fragment_history.view.*
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
@ -27,6 +30,7 @@ import org.mozilla.fenix.HomeActivity
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.mozilla.fenix.components.Components
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.components.StoreProvider
|
||||
import org.mozilla.fenix.components.history.createSynchronousPagedHistoryProvider
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
|
@ -58,6 +62,10 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
}
|
||||
val historyController: HistoryController = DefaultHistoryController(
|
||||
historyStore,
|
||||
findNavController(),
|
||||
resources,
|
||||
FenixSnackbar.make(view, FenixSnackbar.LENGTH_LONG),
|
||||
activity?.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager,
|
||||
::openItem,
|
||||
::displayDeleteAllDialog,
|
||||
::invalidateOptionsMenu,
|
||||
|
@ -183,8 +191,11 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
|||
|
||||
override fun onBackPressed(): Boolean = historyView.onBackPressed()
|
||||
|
||||
private fun openItem(item: HistoryItem) {
|
||||
private fun openItem(item: HistoryItem, mode: BrowsingMode? = null) {
|
||||
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
||||
|
||||
mode?.let { (activity as HomeActivity).browsingModeManager.mode = it }
|
||||
|
||||
(activity as HomeActivity).openToBrowserAndLoad(
|
||||
searchTermOrURL = item.url,
|
||||
newTab = true,
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
|
||||
package org.mozilla.fenix.library.history
|
||||
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
|
||||
/**
|
||||
* Interactor for the history screen
|
||||
* Provides implementations for the HistoryViewInteractor
|
||||
*/
|
||||
@SuppressWarnings("TooManyFunctions")
|
||||
class HistoryInteractor(
|
||||
private val historyController: HistoryController
|
||||
) : HistoryViewInteractor {
|
||||
|
@ -31,6 +34,22 @@ class HistoryInteractor(
|
|||
historyController.handleModeSwitched()
|
||||
}
|
||||
|
||||
override fun onCopyPressed(item: HistoryItem) {
|
||||
historyController.handleCopyUrl(item)
|
||||
}
|
||||
|
||||
override fun onSharePressed(item: HistoryItem) {
|
||||
historyController.handleShare(item)
|
||||
}
|
||||
|
||||
override fun onOpenInNormalTab(item: HistoryItem) {
|
||||
historyController.handleOpen(item, BrowsingMode.Normal)
|
||||
}
|
||||
|
||||
override fun onOpenInPrivateTab(item: HistoryItem) {
|
||||
historyController.handleOpen(item, BrowsingMode.Private)
|
||||
}
|
||||
|
||||
override fun onDeleteAll() {
|
||||
historyController.handleDeleteAll()
|
||||
}
|
||||
|
|
|
@ -16,13 +16,29 @@ class HistoryItemMenu(
|
|||
private val onItemTapped: (Item) -> Unit = {}
|
||||
) : LibraryItemMenu {
|
||||
sealed class Item {
|
||||
object Copy : Item()
|
||||
object Share : Item()
|
||||
object OpenInNewTab : Item()
|
||||
object OpenInPrivateTab : Item()
|
||||
object Delete : Item()
|
||||
}
|
||||
|
||||
override val menuBuilder by lazy { BrowserMenuBuilder(menuItems) }
|
||||
|
||||
private val menuItems by lazy {
|
||||
listOf(
|
||||
listOfNotNull(
|
||||
SimpleBrowserMenuItem(context.getString(R.string.history_menu_copy_button)) {
|
||||
onItemTapped.invoke(Item.Copy)
|
||||
},
|
||||
SimpleBrowserMenuItem(context.getString(R.string.history_menu_share_button)) {
|
||||
onItemTapped.invoke(Item.Share)
|
||||
},
|
||||
SimpleBrowserMenuItem(context.getString(R.string.history_menu_open_in_new_tab_button)) {
|
||||
onItemTapped.invoke(Item.OpenInNewTab)
|
||||
},
|
||||
SimpleBrowserMenuItem(context.getString(R.string.history_menu_open_in_private_tab_button)) {
|
||||
onItemTapped.invoke(Item.OpenInPrivateTab)
|
||||
},
|
||||
SimpleBrowserMenuItem(
|
||||
context.getString(R.string.history_delete_item),
|
||||
textColorResource = ThemeManager.resolveAttribute(R.attr.destructive, context)
|
||||
|
|
|
@ -33,6 +33,34 @@ interface HistoryViewInteractor : SelectionInteractor<HistoryItem> {
|
|||
*/
|
||||
fun onModeSwitched()
|
||||
|
||||
/**
|
||||
* Copies the URL of a history item to the copy-paste buffer.
|
||||
*
|
||||
* @param item the history item to copy the URL from
|
||||
*/
|
||||
fun onCopyPressed(item: HistoryItem)
|
||||
|
||||
/**
|
||||
* Opens the share sheet for a history item.
|
||||
*
|
||||
* @param item the history item to share
|
||||
*/
|
||||
fun onSharePressed(item: HistoryItem)
|
||||
|
||||
/**
|
||||
* Opens a history item in a new tab.
|
||||
*
|
||||
* @param item the history item to open in a new tab
|
||||
*/
|
||||
fun onOpenInNormalTab(item: HistoryItem)
|
||||
|
||||
/**
|
||||
* Opens a history item in a private tab.
|
||||
*
|
||||
* @param item the history item to open in a private tab
|
||||
*/
|
||||
fun onOpenInPrivateTab(item: HistoryItem)
|
||||
|
||||
/**
|
||||
* Called when delete all is tapped
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,7 @@ import kotlinx.android.synthetic.main.library_site_item.view.*
|
|||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.hideAndDisable
|
||||
import org.mozilla.fenix.ext.showAndEnable
|
||||
import org.mozilla.fenix.lib.Do
|
||||
import org.mozilla.fenix.library.SelectionHolder
|
||||
import org.mozilla.fenix.library.history.HistoryFragmentState
|
||||
import org.mozilla.fenix.library.history.HistoryInteractor
|
||||
|
@ -98,7 +99,12 @@ class HistoryListItemViewHolder(
|
|||
private fun setupMenu() {
|
||||
val historyMenu = HistoryItemMenu(itemView.context) {
|
||||
val item = this.item ?: return@HistoryItemMenu
|
||||
when (it) {
|
||||
|
||||
Do exhaustive when (it) {
|
||||
HistoryItemMenu.Item.Copy -> historyInteractor.onCopyPressed(item)
|
||||
HistoryItemMenu.Item.Share -> historyInteractor.onSharePressed(item)
|
||||
HistoryItemMenu.Item.OpenInNewTab -> historyInteractor.onOpenInNormalTab(item)
|
||||
HistoryItemMenu.Item.OpenInPrivateTab -> historyInteractor.onOpenInPrivateTab(item)
|
||||
HistoryItemMenu.Item.Delete -> historyInteractor.onDeleteSome(setOf(item))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -454,6 +454,14 @@
|
|||
<string name="history_delete_all_dialog">Are you sure you want to clear your history?</string>
|
||||
<!-- Text for positive action to delete history in deleting history dialog -->
|
||||
<string name="history_clear_dialog">Clear</string>
|
||||
<!-- History overflow menu copy button -->
|
||||
<string name="history_menu_copy_button">Copy</string>
|
||||
<!-- History overflow menu share button -->
|
||||
<string name="history_menu_share_button">Share</string>
|
||||
<!-- History overflow menu open in new tab button -->
|
||||
<string name="history_menu_open_in_new_tab_button">Open in new tab</string>
|
||||
<!-- History overflow menu open in private tab button -->
|
||||
<string name="history_menu_open_in_private_tab_button">Open in private tab</string>
|
||||
<!-- Text for the button to delete a single history item -->
|
||||
<string name="history_delete_item">Delete</string>
|
||||
<!-- History multi select title in app bar
|
||||
|
|
Loading…
Reference in New Issue