From b78d9fc9f6b50af52ebef173260750cf231d5c77 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Thu, 9 Mar 2023 01:06:49 -0500 Subject: [PATCH] Swipe to reply --- .../com/cheogram/android/SwipeDetector.java | 100 ++++++++++++++++++ .../ui/ConversationFragment.java | 4 + .../ui/adapter/MessageAdapter.java | 16 +++ 3 files changed, 120 insertions(+) create mode 100644 src/cheogram/java/com/cheogram/android/SwipeDetector.java diff --git a/src/cheogram/java/com/cheogram/android/SwipeDetector.java b/src/cheogram/java/com/cheogram/android/SwipeDetector.java new file mode 100644 index 0000000000000000000000000000000000000000..943bfe2f0d92eabd4ccae17e2ecc5c95c6a851db --- /dev/null +++ b/src/cheogram/java/com/cheogram/android/SwipeDetector.java @@ -0,0 +1,100 @@ +package com.cheogram.android; + +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +import eu.siacs.conversations.utils.Consumer; + +// https://stackoverflow.com/a/41766670/8611 +/** + * Created by hoshyar on 1/19/17. + */ + +public class SwipeDetector implements View.OnTouchListener { + + protected Consumer cb; + public SwipeDetector(Consumer cb) { + this.cb = cb; + } + + public static enum Action { + LR, // Left to Right + RL, // Right to Left + TB, // Top to bottom + BT, // Bottom to Top + None // when no action was detected + } + + private static final String logTag = "Swipe"; + private static final int MIN_DISTANCE = 39; + private float downX, downY, upX, upY; + private Action mSwipeDetected = Action.None; + + public boolean swipeDetected() { + return mSwipeDetected != Action.None; + } + + public Action getAction() { + return mSwipeDetected; + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + downX = event.getX(); + downY = event.getY(); + mSwipeDetected = Action.None; + return false; + + case MotionEvent.ACTION_MOVE: + upX = event.getX(); + upY = event.getY(); + + float deltaX = downX - upX; + float deltaY = downY - upY; + Log.i(logTag,String.valueOf(deltaX)); + Log.i(logTag,String.valueOf(deltaY)); + + if (deltaY>0 && deltaY<10 && deltaX<0 || deltaY==0 && deltaX>-15 && deltaX<0){ + Log.i(logTag,"to right"); + }if (deltaY>=0 && deltaY<10 && deltaX>0 || deltaY<0 && deltaX>15 && deltaX<40){ + Log.i(logTag,"to left"); + } + + + + + + if (Math.abs(deltaX) > MIN_DISTANCE) { + // left or right + if (deltaX < 0) { + cb.accept(mSwipeDetected = Action.LR); + return false; + } + if (deltaX > 0) { + + + cb.accept(mSwipeDetected = Action.RL); + return false; + } + } else if (Math.abs(deltaY) > MIN_DISTANCE) { + + + if (deltaY < 0) { + Log.i(logTag,"to bottom"); + cb.accept(mSwipeDetected = Action.TB); + return false; + } + if (deltaY > 0) { + Log.i(logTag,"to up"); + cb.accept(mSwipeDetected = Action.BT); + return false; + } + } + return true; + } + return false; + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index e3c3d4ad3f942a6a806a0fe6886c4871f158460c..60944b61164a2978928a157d882bb9aba0eb516a 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1303,6 +1303,10 @@ public class ConversationFragment extends XmppFragment conversation.setUserSelectedThread(true); }); + messageListAdapter.setOnMessageBoxSwiped(message -> { + setupReply(message); + }); + binding.threadIdenticonLayout.setOnClickListener(v -> { boolean wasLocked = conversation.getLockThread(); conversation.setLockThread(false); 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 0e995696e0493b3dd1c9e69a189195604da8f524..1a5ebb6136858517f1c0754d651a28712cc39623 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -41,6 +41,7 @@ import androidx.core.content.ContextCompat; import androidx.core.content.res.ResourcesCompat; import com.cheogram.android.BobTransfer; +import com.cheogram.android.SwipeDetector; import com.google.common.base.Strings; @@ -112,6 +113,7 @@ public class MessageAdapter extends ArrayAdapter { private final DisplayMetrics metrics; private OnContactPictureClicked mOnContactPictureClickedListener; private OnContactPictureClicked mOnMessageBoxClickedListener; + private OnContactPictureClicked mOnMessageBoxSwipedListener; private OnContactPictureLongClicked mOnContactPictureLongClickedListener; private OnInlineImageLongClicked mOnInlineImageLongClickedListener; private boolean mUseGreenBackground = false; @@ -156,6 +158,10 @@ public class MessageAdapter extends ArrayAdapter { this.mOnMessageBoxClickedListener = listener; } + public void setOnMessageBoxSwiped(OnContactPictureClicked listener) { + this.mOnMessageBoxSwipedListener = listener; + } + public Activity getActivity() { return activity; } @@ -927,6 +933,16 @@ public class MessageAdapter extends ArrayAdapter { .onContactPictureClicked(message); } }); + viewHolder.message_box.setOnTouchListener(new SwipeDetector((action) -> { + if (action == SwipeDetector.Action.LR && MessageAdapter.this.mOnMessageBoxSwipedListener != null) { + MessageAdapter.this.mOnMessageBoxSwipedListener.onContactPictureClicked(message); + } + })); + viewHolder.messageBody.setOnTouchListener(new SwipeDetector((action) -> { + if (action == SwipeDetector.Action.LR && MessageAdapter.this.mOnMessageBoxSwipedListener != null) { + MessageAdapter.this.mOnMessageBoxSwipedListener.onContactPictureClicked(message); + } + })); viewHolder.messageBody.setOnClickListener(v -> { if (MessageAdapter.this.mOnMessageBoxClickedListener != null) { MessageAdapter.this.mOnMessageBoxClickedListener