|
|
@ -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)
|
|
|
|