2019-04-04 22:40:39 +02:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
2019-07-12 20:38:15 +02:00
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2019-04-04 22:40:39 +02:00
|
|
|
|
|
|
|
package org.mozilla.fenix.library.bookmarks.edit
|
|
|
|
|
2019-06-04 22:00:49 +02:00
|
|
|
import android.content.DialogInterface
|
2019-04-04 22:40:39 +02:00
|
|
|
import android.os.Bundle
|
|
|
|
import android.view.Menu
|
|
|
|
import android.view.MenuInflater
|
|
|
|
import android.view.MenuItem
|
|
|
|
import android.view.View
|
2019-06-04 22:00:49 +02:00
|
|
|
import androidx.appcompat.app.AlertDialog
|
2019-04-04 22:40:39 +02:00
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
2019-10-26 06:41:48 +02:00
|
|
|
import androidx.appcompat.widget.Toolbar
|
2019-04-04 22:40:39 +02:00
|
|
|
import androidx.fragment.app.Fragment
|
2019-06-13 02:14:46 +02:00
|
|
|
import androidx.fragment.app.activityViewModels
|
2019-09-12 18:27:33 +02:00
|
|
|
import androidx.lifecycle.ViewModelProvider
|
2019-06-13 02:14:46 +02:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
2019-04-04 22:40:39 +02:00
|
|
|
import androidx.navigation.Navigation
|
2020-01-11 13:15:04 +01:00
|
|
|
import androidx.navigation.fragment.findNavController
|
2020-02-06 00:33:11 +01:00
|
|
|
import androidx.navigation.fragment.navArgs
|
2020-01-03 23:37:12 +01:00
|
|
|
import kotlinx.android.synthetic.main.fragment_edit_bookmark.bookmarkNameEdit
|
|
|
|
import kotlinx.android.synthetic.main.fragment_edit_bookmark.bookmarkParentFolderSelector
|
|
|
|
import kotlinx.android.synthetic.main.fragment_edit_bookmark.bookmarkUrlEdit
|
|
|
|
import kotlinx.android.synthetic.main.fragment_edit_bookmark.bookmarkUrlLabel
|
2020-01-11 13:15:04 +01:00
|
|
|
import kotlinx.android.synthetic.main.fragment_edit_bookmark.progress_bar_bookmark
|
2019-04-04 22:40:39 +02:00
|
|
|
import kotlinx.coroutines.Dispatchers.IO
|
|
|
|
import kotlinx.coroutines.Dispatchers.Main
|
|
|
|
import kotlinx.coroutines.launch
|
2019-09-27 17:57:39 +02:00
|
|
|
import kotlinx.coroutines.withContext
|
2019-04-04 22:40:39 +02:00
|
|
|
import mozilla.appservices.places.UrlParseFailed
|
|
|
|
import mozilla.components.concept.storage.BookmarkInfo
|
|
|
|
import mozilla.components.concept.storage.BookmarkNode
|
|
|
|
import mozilla.components.concept.storage.BookmarkNodeType
|
2019-10-26 06:41:48 +02:00
|
|
|
import mozilla.components.support.ktx.android.content.getColorFromAttr
|
2019-07-17 02:02:48 +02:00
|
|
|
import mozilla.components.support.ktx.android.view.hideKeyboard
|
2020-01-16 19:03:18 +01:00
|
|
|
import org.mozilla.fenix.HomeActivity
|
2019-04-04 22:40:39 +02:00
|
|
|
import org.mozilla.fenix.R
|
2020-01-02 23:31:52 +01:00
|
|
|
import org.mozilla.fenix.components.FenixSnackbar
|
2019-04-17 19:37:36 +02:00
|
|
|
import org.mozilla.fenix.components.metrics.Event
|
2019-09-24 18:17:29 +02:00
|
|
|
import org.mozilla.fenix.ext.components
|
2019-09-12 18:27:33 +02:00
|
|
|
import org.mozilla.fenix.ext.getRootView
|
2019-06-06 21:40:10 +02:00
|
|
|
import org.mozilla.fenix.ext.nav
|
2019-04-04 22:40:39 +02:00
|
|
|
import org.mozilla.fenix.ext.requireComponents
|
2019-10-26 06:41:48 +02:00
|
|
|
import org.mozilla.fenix.ext.setToolbarColors
|
2019-11-15 23:25:50 +01:00
|
|
|
import org.mozilla.fenix.ext.toShortUrl
|
2019-04-04 22:40:39 +02:00
|
|
|
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
|
2019-09-24 18:17:29 +02:00
|
|
|
import org.mozilla.fenix.library.bookmarks.DesktopFolders
|
2019-04-04 22:40:39 +02:00
|
|
|
|
2019-10-06 19:57:41 +02:00
|
|
|
/**
|
|
|
|
* Menu to edit the name, URL, and location of a bookmark item.
|
|
|
|
*/
|
|
|
|
class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
|
2019-04-04 22:40:39 +02:00
|
|
|
|
2020-02-06 00:33:11 +01:00
|
|
|
private val args by navArgs<EditBookmarkFragmentArgs>()
|
2019-09-01 00:41:50 +02:00
|
|
|
private val sharedViewModel: BookmarksSharedViewModel by activityViewModels {
|
|
|
|
ViewModelProvider.NewInstanceFactory() // this is a workaround for #4652
|
|
|
|
}
|
2019-04-04 22:40:39 +02:00
|
|
|
private var bookmarkNode: BookmarkNode? = null
|
|
|
|
private var bookmarkParent: BookmarkNode? = null
|
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
setHasOptionsMenu(true)
|
|
|
|
}
|
|
|
|
|
2020-01-11 13:15:04 +01:00
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
|
|
super.onViewCreated(view, savedInstanceState)
|
2019-10-26 06:41:48 +02:00
|
|
|
initToolbar()
|
2019-04-04 22:40:39 +02:00
|
|
|
|
2019-09-27 17:57:39 +02:00
|
|
|
lifecycleScope.launch(Main) {
|
2019-09-24 18:17:29 +02:00
|
|
|
val context = requireContext()
|
2019-09-27 17:57:39 +02:00
|
|
|
|
|
|
|
withContext(IO) {
|
|
|
|
val bookmarksStorage = context.components.core.bookmarksStorage
|
2020-02-06 00:33:11 +01:00
|
|
|
bookmarkNode = bookmarksStorage.getTree(args.guidToEdit)
|
2019-09-27 17:57:39 +02:00
|
|
|
bookmarkParent = sharedViewModel.selectedFolder
|
|
|
|
?: bookmarkNode?.parentGuid
|
|
|
|
?.let { bookmarksStorage.getTree(it) }
|
|
|
|
?.let { DesktopFolders(context, showMobileRoot = true).withRootTitle(it) }
|
|
|
|
}
|
|
|
|
|
|
|
|
when (bookmarkNode?.type) {
|
|
|
|
BookmarkNodeType.FOLDER -> {
|
|
|
|
activity?.title = getString(R.string.edit_bookmark_folder_fragment_title)
|
|
|
|
bookmarkUrlEdit.visibility = View.GONE
|
|
|
|
bookmarkUrlLabel.visibility = View.GONE
|
|
|
|
}
|
|
|
|
BookmarkNodeType.ITEM -> {
|
|
|
|
activity?.title = getString(R.string.edit_bookmark_fragment_title)
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
2019-09-27 17:57:39 +02:00
|
|
|
else -> throw IllegalArgumentException()
|
|
|
|
}
|
2019-04-17 19:37:36 +02:00
|
|
|
|
2019-09-27 17:57:39 +02:00
|
|
|
bookmarkNode?.let { bookmarkNode ->
|
|
|
|
bookmarkNameEdit.setText(bookmarkNode.title)
|
|
|
|
bookmarkUrlEdit.setText(bookmarkNode.url)
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bookmarkParent?.let { node ->
|
2020-01-11 13:15:04 +01:00
|
|
|
bookmarkParentFolderSelector.text = node.title
|
|
|
|
bookmarkParentFolderSelector.setOnClickListener {
|
|
|
|
sharedViewModel.selectedFolder = null
|
|
|
|
nav(
|
|
|
|
R.id.bookmarkEditFragment,
|
|
|
|
EditBookmarkFragmentDirections
|
|
|
|
.actionBookmarkEditFragmentToBookmarkSelectFolderFragment(null)
|
|
|
|
)
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
|
|
|
}
|
2020-01-11 13:15:04 +01:00
|
|
|
}
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
|
|
|
|
2019-10-26 06:41:48 +02:00
|
|
|
private fun initToolbar() {
|
|
|
|
val activity = activity as? AppCompatActivity
|
2020-01-16 19:03:18 +01:00
|
|
|
val actionBar = (activity as HomeActivity).getSupportActionBarAndInflateIfNecessary()
|
|
|
|
val toolbar = activity.findViewById<Toolbar>(R.id.navigationToolbar)
|
2019-10-26 06:41:48 +02:00
|
|
|
context?.let {
|
|
|
|
toolbar?.setToolbarColors(
|
|
|
|
foreground = it.getColorFromAttr(R.attr.primaryText),
|
|
|
|
background = it.getColorFromAttr(R.attr.foundation)
|
|
|
|
)
|
|
|
|
}
|
2020-01-16 19:03:18 +01:00
|
|
|
actionBar.show()
|
2019-10-26 06:41:48 +02:00
|
|
|
}
|
|
|
|
|
2019-07-17 02:02:48 +02:00
|
|
|
override fun onPause() {
|
|
|
|
super.onPause()
|
2019-08-03 10:14:35 +02:00
|
|
|
bookmarkNameEdit.hideKeyboard()
|
|
|
|
bookmarkUrlEdit.hideKeyboard()
|
2020-01-11 13:15:04 +01:00
|
|
|
progress_bar_bookmark.visibility = View.GONE
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
|
|
inflater.inflate(R.menu.bookmarks_edit, menu)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
|
|
return when (item.itemId) {
|
|
|
|
R.id.delete_bookmark_button -> {
|
2019-06-04 22:00:49 +02:00
|
|
|
displayDeleteBookmarkDialog()
|
2019-04-04 22:40:39 +02:00
|
|
|
true
|
|
|
|
}
|
2020-01-11 13:15:04 +01:00
|
|
|
R.id.save_bookmark_button -> {
|
|
|
|
updateBookmarkFromTextChanges()
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2019-04-04 22:40:39 +02:00
|
|
|
else -> super.onOptionsItemSelected(item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-04 22:00:49 +02:00
|
|
|
private fun displayDeleteBookmarkDialog() {
|
|
|
|
activity?.let { activity ->
|
|
|
|
AlertDialog.Builder(activity).apply {
|
|
|
|
setMessage(R.string.bookmark_deletion_confirmation)
|
|
|
|
setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, _ ->
|
|
|
|
dialog.cancel()
|
|
|
|
}
|
|
|
|
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
|
2019-06-13 02:14:46 +02:00
|
|
|
lifecycleScope.launch(IO) {
|
2020-02-06 00:33:11 +01:00
|
|
|
requireComponents.core.bookmarksStorage.deleteNode(args.guidToEdit)
|
2019-06-04 22:00:49 +02:00
|
|
|
requireComponents.analytics.metrics.track(Event.RemoveBookmark)
|
2019-08-28 19:12:39 +02:00
|
|
|
|
2019-06-04 22:00:49 +02:00
|
|
|
launch(Main) {
|
2019-10-26 06:41:48 +02:00
|
|
|
Navigation.findNavController(requireActivity(), R.id.container)
|
|
|
|
.popBackStack()
|
2019-12-30 23:43:15 +01:00
|
|
|
|
|
|
|
bookmarkNode?.let { bookmark ->
|
2020-01-02 23:31:52 +01:00
|
|
|
FenixSnackbar.makeWithToolbarPadding(activity.getRootView()!!)
|
|
|
|
.setText(
|
2020-01-11 13:15:04 +01:00
|
|
|
getString(
|
|
|
|
R.string.bookmark_deletion_snackbar_message,
|
2020-01-02 23:31:52 +01:00
|
|
|
bookmark.url?.toShortUrl(context.components.publicSuffixList)
|
|
|
|
?: bookmark.title
|
|
|
|
)
|
2019-12-30 23:43:15 +01:00
|
|
|
)
|
2020-01-02 23:31:52 +01:00
|
|
|
.show()
|
2019-08-28 19:12:39 +02:00
|
|
|
}
|
2019-06-04 22:00:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
dialog.dismiss()
|
|
|
|
}
|
|
|
|
create()
|
|
|
|
}.show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-11 13:15:04 +01:00
|
|
|
private fun updateBookmarkFromTextChanges() {
|
|
|
|
progress_bar_bookmark.visibility = View.VISIBLE
|
|
|
|
val nameText = bookmarkNameEdit.text.toString()
|
|
|
|
val urlText = bookmarkUrlEdit.text.toString()
|
|
|
|
updateBookmarkNode(nameText, urlText)
|
|
|
|
}
|
|
|
|
|
2019-10-21 19:06:08 +02:00
|
|
|
private fun updateBookmarkNode(title: String?, url: String?) {
|
2019-06-13 02:14:46 +02:00
|
|
|
lifecycleScope.launch(IO) {
|
2019-04-17 19:37:36 +02:00
|
|
|
try {
|
2019-10-21 19:06:08 +02:00
|
|
|
requireComponents.let { components ->
|
|
|
|
if (title != bookmarkNode?.title || url != bookmarkNode?.url) {
|
|
|
|
components.analytics.metrics.track(Event.EditedBookmark)
|
2019-04-17 19:37:36 +02:00
|
|
|
}
|
|
|
|
if (sharedViewModel.selectedFolder != null) {
|
2019-10-21 19:06:08 +02:00
|
|
|
components.analytics.metrics.track(Event.MovedBookmark)
|
2019-04-17 19:37:36 +02:00
|
|
|
}
|
2019-10-21 19:06:08 +02:00
|
|
|
components.core.bookmarksStorage.updateNode(
|
2020-02-06 00:33:11 +01:00
|
|
|
args.guidToEdit,
|
2019-04-17 19:37:36 +02:00
|
|
|
BookmarkInfo(
|
|
|
|
sharedViewModel.selectedFolder?.guid ?: bookmarkNode!!.parentGuid,
|
|
|
|
bookmarkNode?.position,
|
2019-10-21 19:06:08 +02:00
|
|
|
title,
|
|
|
|
if (bookmarkNode?.type == BookmarkNodeType.ITEM) url else null
|
2019-04-17 19:37:36 +02:00
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
} catch (e: UrlParseFailed) {
|
2019-10-21 19:06:08 +02:00
|
|
|
withContext(Main) {
|
2019-08-03 10:14:35 +02:00
|
|
|
bookmarkUrlEdit.error = getString(R.string.bookmark_invalid_url_error)
|
2019-04-14 05:25:58 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
2020-01-11 13:15:04 +01:00
|
|
|
progress_bar_bookmark.visibility = View.INVISIBLE
|
|
|
|
findNavController().popBackStack()
|
2019-04-04 22:40:39 +02:00
|
|
|
}
|
|
|
|
}
|