From 37a0263670d550248d620fcaa40315b4eece00f5 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 4 Jun 2021 13:15:43 +1000 Subject: [PATCH] Implement swipe to reply gesture --- .../conversation/v2/ConversationActivityV2.kt | 9 +++++ .../v2/ConversationTouchHelperCallback.kt | 39 +++++++++++++++++++ .../loki/utilities/GeneralUtilities.kt | 17 +++++++- .../res/layout/activity_conversation_v2.xml | 2 +- 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTouchHelperCallback.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index bb322aab1f..d29a8b2864 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -2,8 +2,10 @@ package org.thoughtcrime.securesms.conversation.v2 import android.database.Cursor import android.os.Bundle +import android.util.Log import androidx.loader.app.LoaderManager import androidx.loader.content.Loader +import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.activity_conversation_v2.* import network.loki.messenger.R @@ -63,6 +65,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity() { adapter.changeCursor(null) } }) + val touchHelperCallback = ConversationTouchHelperCallback(adapter, this) { reply(it) } + val touchHelper = ItemTouchHelper(touchHelperCallback) + touchHelper.attachToRecyclerView(conversationRecyclerView) } private fun setUpToolbar() { @@ -77,5 +82,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity() { private fun showConversationSettings() { // TODO: Implement } + + private fun reply(messagePosition: Int) { + Log.d("Loki", "Reply to message at position: $messagePosition.") + } // endregion } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTouchHelperCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTouchHelperCallback.kt new file mode 100644 index 0000000000..c1f6f8650c --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationTouchHelperCallback.kt @@ -0,0 +1,39 @@ +package org.thoughtcrime.securesms.conversation.v2 + +import android.content.Context +import android.graphics.Canvas +import android.view.HapticFeedbackConstants +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import org.thoughtcrime.securesms.loki.utilities.toDp +import kotlin.math.abs + +class ConversationTouchHelperCallback(private val adapter: ConversationAdapter, private val context: Context, + private val onSwipe: (Int) -> Unit) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { + private var previousX: Float = 0.0f + + companion object { + const val swipeToReplyThreshold = 200.0f // dp + } + + override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { + return false + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + adapter.notifyItemChanged(viewHolder.adapterPosition) + } + + override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { + super.onChildDraw(c, recyclerView, viewHolder, dX / 4 , dY, actionState, isCurrentlyActive) + val x = abs(toDp(dX, context.resources)) + val threshold = ConversationTouchHelperCallback.swipeToReplyThreshold + if (x > threshold && previousX < threshold) { + val view = viewHolder.itemView + view.isHapticFeedbackEnabled = true + view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) + onSwipe(viewHolder.adapterPosition) + } + previousX = x + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/GeneralUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/GeneralUtilities.kt index 6bb7a7a9e0..798f937d9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/GeneralUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/GeneralUtilities.kt @@ -14,6 +14,19 @@ fun Resources.getColorWithID(@ColorRes id: Int, theme: Resources.Theme?): Int { } fun toPx(dp: Int, resources: Resources): Int { - val scale = resources.displayMetrics.density - return (dp * scale).roundToInt() + return toPx(dp.toFloat(), resources).roundToInt() +} + +fun toPx(dp: Float, resources: Resources): Float { + val scale = resources.displayMetrics.density + return (dp * scale) +} + +fun toDp(px: Int, resources: Resources): Int { + return toDp(px.toFloat(), resources).roundToInt() +} + +fun toDp(px: Float, resources: Resources): Float { + val scale = resources.displayMetrics.density + return (px / scale) } diff --git a/app/src/main/res/layout/activity_conversation_v2.xml b/app/src/main/res/layout/activity_conversation_v2.xml index aad8fb4c39..b64360acaa 100644 --- a/app/src/main/res/layout/activity_conversation_v2.xml +++ b/app/src/main/res/layout/activity_conversation_v2.xml @@ -50,7 +50,7 @@ android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" - android:layout_marginLeft="66dp" + android:layout_marginLeft="67dp" android:text="Elon" android:textColor="@color/text" android:textStyle="bold"