Swipe to reply icon

This commit is contained in:
Niels Andriesse 2021-06-09 15:12:48 +10:00
parent 7a44c27936
commit e61c3288fa
3 changed files with 31 additions and 2 deletions

View File

@ -26,7 +26,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity() {
// TODO: Selected message background color // TODO: Selected message background color
// TODO: Overflow menu background + text color // TODO: Overflow menu background + text color
// TODO: Make swipe to reply better. The current implementation is mediocre.
private val adapter by lazy { private val adapter by lazy {
val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID) val cursor = DatabaseFactory.getMmsSmsDatabase(this).getConversation(threadID)

View File

@ -1,13 +1,17 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log
import android.view.* import android.view.*
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.view_visible_message.view.* import kotlinx.android.synthetic.main.view_visible_message.view.*
import network.loki.messenger.R import network.loki.messenger.R
@ -15,15 +19,20 @@ import org.session.libsession.messaging.contacts.Contact.ContactContext
import org.session.libsession.utilities.ViewUtil import org.session.libsession.utilities.ViewUtil
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.loki.utilities.disableClipping
import org.thoughtcrime.securesms.loki.utilities.getColorWithID import org.thoughtcrime.securesms.loki.utilities.getColorWithID
import org.thoughtcrime.securesms.loki.utilities.toDp import org.thoughtcrime.securesms.loki.utilities.toDp
import org.thoughtcrime.securesms.loki.utilities.toPx
import org.thoughtcrime.securesms.util.DateUtils import org.thoughtcrime.securesms.util.DateUtils
import java.util.* import java.util.*
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.min
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.sqrt import kotlin.math.sqrt
class VisibleMessageView : LinearLayout { class VisibleMessageView : LinearLayout {
private val swipeToReplyIcon = ContextCompat.getDrawable(context, R.drawable.ic_baseline_reply_24)!!
private val swipeToReplyIconRect = Rect()
private var dx = 0.0f private var dx = 0.0f
private var previousTranslationX = 0.0f private var previousTranslationX = 0.0f
private val gestureHandler = Handler(Looper.getMainLooper()) private val gestureHandler = Handler(Looper.getMainLooper())
@ -58,6 +67,7 @@ class VisibleMessageView : LinearLayout {
LayoutInflater.from(context).inflate(R.layout.view_visible_message, this) LayoutInflater.from(context).inflate(R.layout.view_visible_message, this)
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
isHapticFeedbackEnabled = true isHapticFeedbackEnabled = true
setWillNotDraw(false)
} }
// endregion // endregion
@ -147,6 +157,25 @@ class VisibleMessageView : LinearLayout {
} }
} }
override fun onDraw(canvas: Canvas) {
if (translationX < 0) {
val spacing = context.resources.getDimensionPixelSize(R.dimen.small_spacing)
val threshold = VisibleMessageView.swipeToReplyThreshold
val iconSize = toPx(24, context.resources)
val bottomVOffset = paddingBottom + messageTimestampTextView.height + (messageContentView.height - iconSize) / 2
swipeToReplyIconRect.left = messageContentContainer.right + spacing
swipeToReplyIconRect.top = height - bottomVOffset - iconSize
swipeToReplyIconRect.right = messageContentContainer.right + iconSize + spacing
swipeToReplyIconRect.bottom = height - bottomVOffset
swipeToReplyIcon.bounds = swipeToReplyIconRect
swipeToReplyIcon.alpha = (255.0f * (min(abs(translationX), threshold) / threshold)).roundToInt()
swipeToReplyIcon.draw(canvas)
} else {
swipeToReplyIcon.alpha = 0
}
super.onDraw(canvas)
}
fun recycle() { fun recycle() {
profilePictureView.recycle() profilePictureView.recycle()
messageContentView.recycle() messageContentView.recycle()
@ -184,6 +213,7 @@ class VisibleMessageView : LinearLayout {
val sign = -1.0f val sign = -1.0f
val x = (damping * (sqrt(abs(translationX)) / sqrt(damping))) * sign val x = (damping * (sqrt(abs(translationX)) / sqrt(damping))) * sign
this.translationX = x this.translationX = x
postInvalidate() // Ensure onDraw(canvas:) is called
if (abs(x) > VisibleMessageView.swipeToReplyThreshold && abs(previousTranslationX) < VisibleMessageView.swipeToReplyThreshold) { if (abs(x) > VisibleMessageView.swipeToReplyThreshold && abs(previousTranslationX) < VisibleMessageView.swipeToReplyThreshold) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK) performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)

View File

@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" > android:orientation="vertical">
<TextView <TextView
android:id="@+id/dateBreakTextView" android:id="@+id/dateBreakTextView"