For #1571: Make bookmark deletion undoable
parent
4ba7527655
commit
9b1c1b5f4d
|
@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- #1539 - Added bookmarks multi-select related features
|
||||
- #1603 - Remove deprecated success path for Firefox Accounts login
|
||||
- #619 - Sets toolbar behavior based on accessibility and if session is loading
|
||||
- #1571 - Added a snackbar for undoing bookmark deletion
|
||||
|
||||
### Changed
|
||||
- #1429 - Updated site permissions ui for MVP
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
package org.mozilla.fenix.ext
|
||||
|
||||
import android.view.View
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
|
||||
fun CoroutineScope.allowUndo(view: View, message: String, undoActionTitle: String, operation: suspend () -> Unit) {
|
||||
val undoJob = launch(Dispatchers.IO) {
|
||||
delay(UNDO_DELAY)
|
||||
operation.invoke()
|
||||
}
|
||||
FenixSnackbar.make(view, FenixSnackbar.LENGTH_LONG)
|
||||
.setText(message)
|
||||
.setAction(undoActionTitle) {
|
||||
undoJob.cancel()
|
||||
}.show()
|
||||
}
|
||||
|
||||
internal const val UNDO_DELAY = 3000L
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
package org.mozilla.fenix.ext
|
||||
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
|
||||
/**
|
||||
* Replaces the keys with the values with the map provided.
|
||||
*/
|
||||
|
@ -14,3 +17,12 @@ fun String.replace(pairs: Map<String, String>): String {
|
|||
pairs.forEach { (l, r) -> result = result.replace(l, r) }
|
||||
return result
|
||||
}
|
||||
|
||||
fun String?.urlToHost(): String {
|
||||
return try {
|
||||
val url = URL(this)
|
||||
url.host
|
||||
} catch (e: MalformedURLException) {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.appservices.places.BookmarkRoot
|
||||
import mozilla.components.concept.storage.BookmarkNode
|
||||
|
@ -45,9 +44,11 @@ import org.mozilla.fenix.BrowsingModeManager
|
|||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.ext.allowUndo
|
||||
import org.mozilla.fenix.ext.getColorFromAttr
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.share
|
||||
import org.mozilla.fenix.ext.urlToHost
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||
|
@ -216,7 +217,10 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
|||
}
|
||||
}
|
||||
is BookmarkAction.Delete -> {
|
||||
launch(IO) {
|
||||
allowUndo(
|
||||
view!!, getString(R.string.bookmark_deletion_snackbar_message, it.item.url.urlToHost()),
|
||||
getString(R.string.bookmark_undo_deletion)
|
||||
) {
|
||||
requireComponents.core.bookmarksStorage.deleteNode(it.item.guid)
|
||||
refreshBookmarks()
|
||||
}
|
||||
|
@ -277,16 +281,13 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
|||
true
|
||||
}
|
||||
R.id.delete_bookmarks_multi_select -> {
|
||||
val deleteJob = launch(IO) {
|
||||
delay(bookmarkDeletionDelay)
|
||||
allowUndo(
|
||||
view!!, getString(R.string.bookmark_deletion_multiple_snackbar_message),
|
||||
getString(R.string.bookmark_undo_deletion)
|
||||
) {
|
||||
deleteSelectedBookmarks()
|
||||
refreshBookmarks()
|
||||
}
|
||||
FenixSnackbar.make(view!!, FenixSnackbar.LENGTH_LONG)
|
||||
.setText(getString(R.string.bookmark_deletion_multiple_snackbar_message))
|
||||
.setAction(getString(R.string.bookmark_undo_deletion)) {
|
||||
deleteJob.cancel()
|
||||
}.show()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
|
@ -344,8 +345,4 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
|
|||
val uri = Uri.parse(url)
|
||||
clipBoard.primaryClip = ClipData.newRawUri("Uri", uri)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val bookmarkDeletionDelay = 3000L
|
||||
}
|
||||
}
|
||||
|
|
|
@ -327,7 +327,8 @@
|
|||
<string name="bookmark_invalid_url_error">Invalid URL</string>
|
||||
<!-- Bookmark screen message for empty bookmarks folder -->
|
||||
<string name="bookmarks_empty_message">No bookmarks here</string>
|
||||
<!-- Bookmark snackbar message on deletion -->
|
||||
<!-- Bookmark snackbar message on deletion
|
||||
The first parameter is the host part of the URL of the bookmark deleted, if any -->
|
||||
<string name="bookmark_deletion_snackbar_message">Deleted %1$s</string>
|
||||
<!-- Bookmark snackbar message on deleting multiple bookmarks -->
|
||||
<string name="bookmark_deletion_multiple_snackbar_message">Deleting selected bookmarks</string>
|
||||
|
|
Loading…
Reference in New Issue