From 79c7a3748c74e98445d208524f9d6b05a1eb7313 Mon Sep 17 00:00:00 2001 From: kosyak Date: Wed, 28 Feb 2024 22:44:24 +0100 Subject: [PATCH] improve swipe gesture --- .../ui/ConversationFragment.java | 30 +++++++++++++------ .../conversations/ui/DraggableListView.kt | 2 +- .../ui/adapter/MessageAdapter.java | 30 +++++++++++++++---- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 901049330..6497172be 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1482,11 +1482,27 @@ public class ConversationFragment extends XmppFragment }; messageListAdapter.setMessageEmptyPartLongClickListener(messageClickListener); messageListAdapter.setSelectionStatusProvider(provider); - messageListAdapter.setOnMessageBoxSwiped(message -> { - if (selectionActionMode == null) { - quoteMessage(message); - } - }); + messageListAdapter.setOnMessageBoxSwiped( + new MessageAdapter.MessageBoxSwipedListener() { + @Override + public void onMessageBoxReleasedAfterSwipe(Message message) { + if (selectionActionMode == null) { + quoteMessage(message); + } + } + + @Override + public void onMessageBoxSwipedEnough() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + vibrator.vibrate(VibrationEffect.createOneShot(10L, 127)); + } else { + vibrator.vibrate(10L); + } + } + } + ); messageListAdapter.setReplyClickListener(this::scrollToReply); binding.messagesView.setAdapter(messageListAdapter); @@ -1568,10 +1584,6 @@ public class ConversationFragment extends XmppFragment showKeyboard(binding.textinput); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)); - } } private void scrollToReply(Message message) { diff --git a/src/main/java/eu/siacs/conversations/ui/DraggableListView.kt b/src/main/java/eu/siacs/conversations/ui/DraggableListView.kt index 353974475..c904bc192 100644 --- a/src/main/java/eu/siacs/conversations/ui/DraggableListView.kt +++ b/src/main/java/eu/siacs/conversations/ui/DraggableListView.kt @@ -31,7 +31,7 @@ class DraggableListView : ListView { } dragHelper = if (dragHelperCallback != null) { - ViewDragHelper.create(this, dragHelperCallback) + ViewDragHelper.create(this, 0.8f, dragHelperCallback) } else { null } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 3225f623f..71d432e41 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -45,7 +45,6 @@ import com.google.common.base.Strings; import java.lang.ref.WeakReference; import java.net.URI; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; @@ -117,11 +116,21 @@ public class MessageAdapter extends ArrayAdapter implements DraggableLi private ViewDragHelper dragHelper = null; private final ViewDragHelper.Callback dragCallback = new ViewDragHelper.Callback() { + private int horizontalOffset = 0; + private boolean swipedEnoughFirstTime = true; + @Override public boolean tryCaptureView(@NonNull View child, int pointerId) { return child.getTag(R.id.TAG_DRAGGABLE) != null; } + @Override + public void onViewCaptured(@NonNull View capturedChild, int activePointerId) { + horizontalOffset = 0; + swipedEnoughFirstTime = true; + super.onViewCaptured(capturedChild, activePointerId); + } + @Override public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) { if (dragHelper != null) { @@ -129,19 +138,29 @@ public class MessageAdapter extends ArrayAdapter implements DraggableLi ViewCompat.postOnAnimation(releasedChild, new SettleRunnable(releasedChild)); ViewHolder viewHolder = (ViewHolder) releasedChild.getTag(); - if (viewHolder != null && viewHolder.position >= 0 && viewHolder.position < getCount()) { + if (viewHolder != null && viewHolder.position >= 0 && viewHolder.position < getCount() && horizontalOffset < -releasedChild.getWidth()/6) { Message m = getItem(viewHolder.position); if (messageBoxSwipedListener != null) { - messageBoxSwipedListener.onMessageBoxSwiped(m); + messageBoxSwipedListener.onMessageBoxReleasedAfterSwipe(m); } } } + horizontalOffset = 0; + swipedEnoughFirstTime = true; super.onViewReleased(releasedChild, xvel, yvel); } @Override public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) { - return Math.max(-child.getWidth()/4, Math.min(left, 0)); + int fixedLeft = Math.min(left, 0); + horizontalOffset = fixedLeft; + + if (horizontalOffset < -child.getWidth()/6 && swipedEnoughFirstTime) { + swipedEnoughFirstTime = false; + messageBoxSwipedListener.onMessageBoxSwipedEnough(); + } + + return Math.max(-child.getWidth()/4, fixedLeft); } @@ -1234,7 +1253,8 @@ public class MessageAdapter extends ArrayAdapter implements DraggableLi } public interface MessageBoxSwipedListener { - void onMessageBoxSwiped(Message message); + void onMessageBoxReleasedAfterSwipe(Message message); + void onMessageBoxSwipedEnough(); } public interface ReplyClickListener {