Fix bad behavior with archive swipe.

This commit is contained in:
Alex Hart
2026-09-10 17:10:14 -04:00
committed by Cody Henthorne
parent 86b2819ba6
commit c5de3a4139
3 changed files with 33 additions and 9 deletions
@@ -2,8 +2,10 @@ package org.thoughtcrime.securesms.conversationlist
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.os.SystemClock
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlin.time.Duration.Companion.seconds
/**
* When an item is removed, the gap is held by the items below the space being translated down, OR the items above the space being translated up, OR both.
@@ -15,19 +17,28 @@ import androidx.recyclerview.widget.RecyclerView
*/
class ConversationListArchiveItemDecoration(val background: Drawable) : RecyclerView.ItemDecoration() {
private var archiveTriggered: Boolean = false
companion object {
/** Upper bound on how long after a swipe we're willing to fill a gap, so a missed animation can't leave us armed indefinitely. */
private val ARCHIVE_WINDOW = 1.seconds.inWholeMilliseconds
}
private var archiveTriggeredAt: Long = 0
private var archiveAnimationStarted: Boolean = false
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
if (!archiveTriggered) {
if (archiveTriggeredAt == 0L) {
return
}
if (SystemClock.elapsedRealtime() - archiveTriggeredAt > ARCHIVE_WINDOW) {
clearArchiveTrigger()
return
}
if (parent.isAnimating) {
archiveAnimationStarted = true
} else if (archiveAnimationStarted) {
archiveTriggered = false
archiveAnimationStarted = false
clearArchiveTrigger()
return
}
@@ -72,8 +83,7 @@ class ConversationListArchiveItemDecoration(val background: Drawable) : Recycler
// A bit unscientific, but this gives us the behavior we want around archiving things in the pinned chat section
if (gapHeight > singleItemHeight * 2) {
archiveTriggered = false
archiveAnimationStarted = false
clearArchiveTrigger()
return
}
@@ -82,6 +92,12 @@ class ConversationListArchiveItemDecoration(val background: Drawable) : Recycler
}
fun onArchiveStarted() {
archiveTriggered = true
archiveTriggeredAt = SystemClock.elapsedRealtime()
archiveAnimationStarted = false
}
private fun clearArchiveTrigger() {
archiveTriggeredAt = 0
archiveAnimationStarted = false
}
}
@@ -1873,8 +1873,15 @@ public class ConversationListFragment extends MainFragment implements Conversati
float absoluteDx = Math.abs(dX);
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
View itemView = viewHolder.itemView;
if (!itemView.isAttachedToWindow()) {
itemView.setTranslationX(0);
ViewCompat.setElevation(itemView, 0);
return;
}
Resources resources = getResources();
View itemView = viewHolder.itemView;
float percentDx = absoluteDx / viewHolder.itemView.getWidth();
int color = ArgbEvaluatorCompat.getInstance().evaluate(Math.min(1f, percentDx * (1 / 0.25f)), archiveColorStart, archiveColorEnd);
float scaleStartPoint = DimensionUnit.DP.toPixels(48f);
@@ -3,7 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true"
android:layout_width="match_parent"
android:layout_height="70dp">
android:layout_height="70dp"
android:background="@color/signal_background_primary">
<TextView
android:id="@+id/description"