[fenix] For https://github.com/mozilla-mobile/fenix/issues/1571: Make bookmark deletion undoable

pull/600/head
Colin Lee 6 years ago
parent 8982e69f43
commit 1be065e488

@ -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 - #1539 - Added bookmarks multi-select related features
- #1603 - Remove deprecated success path for Firefox Accounts login - #1603 - Remove deprecated success path for Firefox Accounts login
- #619 - Sets toolbar behavior based on accessibility and if session is loading - #619 - Sets toolbar behavior based on accessibility and if session is loading
- #1571 - Added a snackbar for undoing bookmark deletion
### Changed ### Changed
- #1429 - Updated site permissions ui for MVP - #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 package org.mozilla.fenix.ext
import java.net.MalformedURLException
import java.net.URL
/** /**
* Replaces the keys with the values with the map provided. * 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) } pairs.forEach { (l, r) -> result = result.replace(l, r) }
return result 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.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot import mozilla.appservices.places.BookmarkRoot
import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNode
@ -45,9 +44,11 @@ import org.mozilla.fenix.BrowsingModeManager
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.allowUndo
import org.mozilla.fenix.ext.getColorFromAttr import org.mozilla.fenix.ext.getColorFromAttr
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.share import org.mozilla.fenix.ext.share
import org.mozilla.fenix.ext.urlToHost
import org.mozilla.fenix.mvi.ActionBusFactory import org.mozilla.fenix.mvi.ActionBusFactory
import org.mozilla.fenix.mvi.getAutoDisposeObservable import org.mozilla.fenix.mvi.getAutoDisposeObservable
import org.mozilla.fenix.mvi.getManagedEmitter import org.mozilla.fenix.mvi.getManagedEmitter
@ -216,7 +217,10 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
} }
} }
is BookmarkAction.Delete -> { 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) requireComponents.core.bookmarksStorage.deleteNode(it.item.guid)
refreshBookmarks() refreshBookmarks()
} }
@ -277,16 +281,13 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
true true
} }
R.id.delete_bookmarks_multi_select -> { R.id.delete_bookmarks_multi_select -> {
val deleteJob = launch(IO) { allowUndo(
delay(bookmarkDeletionDelay) view!!, getString(R.string.bookmark_deletion_multiple_snackbar_message),
getString(R.string.bookmark_undo_deletion)
) {
deleteSelectedBookmarks() deleteSelectedBookmarks()
refreshBookmarks() 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 true
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
@ -344,8 +345,4 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
val uri = Uri.parse(url) val uri = Uri.parse(url)
clipBoard.primaryClip = ClipData.newRawUri("Uri", uri) 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> <string name="bookmark_invalid_url_error">Invalid URL</string>
<!-- Bookmark screen message for empty bookmarks folder --> <!-- Bookmark screen message for empty bookmarks folder -->
<string name="bookmarks_empty_message">No bookmarks here</string> <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> <string name="bookmark_deletion_snackbar_message">Deleted %1$s</string>
<!-- Bookmark snackbar message on deleting multiple bookmarks --> <!-- Bookmark snackbar message on deleting multiple bookmarks -->
<string name="bookmark_deletion_multiple_snackbar_message">Deleting selected bookmarks</string> <string name="bookmark_deletion_multiple_snackbar_message">Deleting selected bookmarks</string>

Loading…
Cancel
Save