1
0
Fork 0

For #12906 - Fix swipe-to-delete bookmark folder.

master
Kainalu Hagiwara 2020-07-28 16:06:23 -07:00
parent add147ba38
commit 5318d64911
3 changed files with 72 additions and 5 deletions

View File

@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.content.getDrawableWithTint
import mozilla.components.support.ktx.android.util.dpToPx
@ -21,8 +22,9 @@ import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkSeparatorViewHold
class BookmarkTouchHelper(interactor: BookmarkViewInteractor) :
ItemTouchHelper(BookmarkTouchCallback(interactor))
class BookmarkTouchCallback(private val interactor: BookmarkViewInteractor) :
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
class BookmarkTouchCallback(
private val interactor: BookmarkViewInteractor
) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
override fun getSwipeDirs(
recyclerView: RecyclerView,
@ -41,7 +43,14 @@ class BookmarkTouchCallback(private val interactor: BookmarkViewInteractor) :
*/
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val item = (viewHolder as BookmarkNodeViewHolder).item
item?.let { interactor.onDelete(setOf(it)) }
item?.let {
interactor.onDelete(setOf(it))
// We need to notify the adapter of a change if we swipe a folder to prevent
// visual bugs when cancelling deletion of a folder
if (item.type == BookmarkNodeType.FOLDER) {
viewHolder.bindingAdapter?.notifyItemChanged(viewHolder.bindingAdapterPosition)
}
}
}
override fun onChildDraw(

View File

@ -112,11 +112,10 @@ class BookmarkView(
private var mode: BookmarkFragmentState.Mode = BookmarkFragmentState.Mode.Normal()
private var tree: BookmarkNode? = null
private val bookmarkAdapter: BookmarkAdapter
private val bookmarkAdapter = BookmarkAdapter(view.bookmarks_empty_view, interactor)
init {
view.bookmark_list.apply {
bookmarkAdapter = BookmarkAdapter(view.bookmarks_empty_view, interactor)
adapter = bookmarkAdapter
}
view.bookmark_folders_sign_in.setOnClickListener {

View File

@ -0,0 +1,59 @@
/* 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.library.bookmarks
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.mockk
import io.mockk.verify
import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType
import org.junit.Before
import org.junit.Test
import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkNodeViewHolder
class BookmarkTouchHelperTest {
@RelaxedMockK private lateinit var interactor: BookmarkViewInteractor
@RelaxedMockK private lateinit var viewHolder: BookmarkNodeViewHolder
@RelaxedMockK private lateinit var item: BookmarkNode
private lateinit var touchCallback: BookmarkTouchCallback
@Before
fun setup() {
MockKAnnotations.init(this)
touchCallback = BookmarkTouchCallback(interactor)
every { viewHolder.item } returns item
}
@Test
fun `swiping an item calls onDelete`() {
touchCallback.onSwiped(viewHolder, ItemTouchHelper.LEFT)
verify {
interactor.onDelete(setOf(item))
}
}
@Test
fun `swiping a folder calls onDelete and notifies the adapter of the change`() {
val adapter: RecyclerView.Adapter<BookmarkNodeViewHolder> = mockk(relaxed = true)
every { item.type } returns BookmarkNodeType.FOLDER
every { viewHolder.bindingAdapter } returns adapter
every { viewHolder.bindingAdapterPosition } returns 0
touchCallback.onSwiped(viewHolder, ItemTouchHelper.LEFT)
verify {
interactor.onDelete(setOf(item))
adapter.notifyItemChanged(0)
}
}
}