diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelper.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelper.kt index 69c0186ed..1cecff4fe 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelper.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelper.kt @@ -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( diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkView.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkView.kt index 10d91822b..a64f4b6ee 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkView.kt @@ -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 { diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelperTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelperTest.kt new file mode 100644 index 000000000..5e9209d88 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkTouchHelperTest.kt @@ -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 = 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) + } + } +}