mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-12 06:53:44 +00:00
More animation
This commit is contained in:
parent
4587f40128
commit
7cacee8499
@ -2,19 +2,23 @@ package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import android.animation.FloatEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.res.Resources
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.ActionMode
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.loader.app.LoaderManager
|
||||
import androidx.loader.content.Loader
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.android.synthetic.main.activity_conversation_v2.*
|
||||
import kotlinx.android.synthetic.main.activity_conversation_v2.view.*
|
||||
import kotlinx.android.synthetic.main.activity_conversation_v2_action_bar.*
|
||||
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
||||
import kotlinx.android.synthetic.main.view_input_bar_recording.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
|
||||
@ -22,8 +26,9 @@ import org.thoughtcrime.securesms.conversation.v2.menus.ConversationActionModeCa
|
||||
import org.thoughtcrime.securesms.conversation.v2.menus.ConversationMenuHelper
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.loki.views.NewConversationButtonSetView
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate {
|
||||
private var threadID: Long = -1
|
||||
@ -57,6 +62,10 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
|
||||
private val glide by lazy { GlideApp.with(this) }
|
||||
|
||||
private val screenWidth by lazy {
|
||||
Resources.getSystem().displayMetrics.widthPixels
|
||||
}
|
||||
|
||||
// region Settings
|
||||
companion object {
|
||||
const val THREAD_ID = "thread_id"
|
||||
@ -167,5 +176,45 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMicrophoneButtonMove(event: MotionEvent) {
|
||||
val rawX = event.rawX
|
||||
val chevronImageView = inputBarRecordingView.inputBarChevronImageView
|
||||
val slideToCancelTextView = inputBarRecordingView.inputBarSlideToCancelTextView
|
||||
if (rawX < screenWidth / 2) {
|
||||
val translationX = rawX - screenWidth / 2
|
||||
val sign = -1.0f
|
||||
val chevronDamping = 4.0f
|
||||
val labelDamping = 3.0f
|
||||
val chevronX = (chevronDamping * (sqrt(abs(translationX)) / sqrt(chevronDamping))) * sign
|
||||
val labelX = (labelDamping * (sqrt(abs(translationX)) / sqrt(labelDamping))) * sign
|
||||
chevronImageView.translationX = chevronX
|
||||
slideToCancelTextView.translationX = labelX
|
||||
} else {
|
||||
chevronImageView.translationX = 0.0f
|
||||
slideToCancelTextView.translationX = 0.0f
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMicrophoneButtonCancel(event: MotionEvent) {
|
||||
resetVoiceMessageUI()
|
||||
}
|
||||
|
||||
override fun onMicrophoneButtonUp(event: MotionEvent) {
|
||||
resetVoiceMessageUI()
|
||||
}
|
||||
|
||||
private fun resetVoiceMessageUI() {
|
||||
val chevronImageView = inputBarRecordingView.inputBarChevronImageView
|
||||
val slideToCancelTextView = inputBarRecordingView.inputBarSlideToCancelTextView
|
||||
listOf( chevronImageView, slideToCancelTextView ).forEach { view ->
|
||||
val animation = ValueAnimator.ofObject(FloatEvaluator(), view.translationX, 0.0f)
|
||||
animation.duration = 250L
|
||||
animation.addUpdateListener { animator ->
|
||||
view.translationX = animator.animatedValue as Float
|
||||
}
|
||||
animation.start()
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.conversation.v2.input_bar
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.isVisible
|
||||
import kotlinx.android.synthetic.main.view_input_bar.view.*
|
||||
@ -34,6 +35,9 @@ class InputBar : RelativeLayout, InputBarEditTextDelegate {
|
||||
microphoneButton.onLongPress = {
|
||||
showVoiceMessageUI()
|
||||
}
|
||||
microphoneButton.onMove = { delegate?.onMicrophoneButtonMove(it) }
|
||||
microphoneButton.onCancel = { delegate?.onMicrophoneButtonCancel(it) }
|
||||
microphoneButton.onUp = { delegate?.onMicrophoneButtonUp(it) }
|
||||
// Send button
|
||||
microphoneOrSendButtonContainer.addView(sendButton)
|
||||
sendButton.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
|
||||
@ -69,4 +73,7 @@ interface InputBarDelegate {
|
||||
|
||||
fun inputBarHeightChanged(newValue: Int)
|
||||
fun showVoiceMessageUI()
|
||||
fun onMicrophoneButtonMove(event: MotionEvent)
|
||||
fun onMicrophoneButtonCancel(event: MotionEvent)
|
||||
fun onMicrophoneButtonUp(event: MotionEvent)
|
||||
}
|
@ -32,6 +32,9 @@ class InputBarButton : RelativeLayout {
|
||||
private var onDownTimestamp = 0L
|
||||
|
||||
var onPress: (() -> Unit)? = null
|
||||
var onMove: ((MotionEvent) -> Unit)? = null
|
||||
var onCancel: ((MotionEvent) -> Unit)? = null
|
||||
var onUp: ((MotionEvent) -> Unit)? = null
|
||||
var onLongPress: (() -> Unit)? = null
|
||||
|
||||
companion object {
|
||||
@ -112,6 +115,7 @@ class InputBarButton : RelativeLayout {
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> onDown(event)
|
||||
MotionEvent.ACTION_MOVE -> onMove(event)
|
||||
MotionEvent.ACTION_UP -> onUp(event)
|
||||
MotionEvent.ACTION_CANCEL -> onCancel(event)
|
||||
}
|
||||
@ -132,12 +136,18 @@ class InputBarButton : RelativeLayout {
|
||||
onDownTimestamp = Date().time
|
||||
}
|
||||
|
||||
private fun onMove(event: MotionEvent) {
|
||||
onMove?.invoke(event)
|
||||
}
|
||||
|
||||
private fun onCancel(event: MotionEvent) {
|
||||
onCancel?.invoke(event)
|
||||
collapse()
|
||||
longPressCallback?.let { gestureHandler.removeCallbacks(it) }
|
||||
}
|
||||
|
||||
private fun onUp(event: MotionEvent) {
|
||||
onUp?.invoke(event)
|
||||
collapse()
|
||||
if ((Date().time - onDownTimestamp) < VisibleMessageView.longPressDurationThreshold) {
|
||||
longPressCallback?.let { gestureHandler.removeCallbacks(it) }
|
||||
|
@ -1,19 +1,17 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.input_bar
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.FloatEvaluator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.isVisible
|
||||
import kotlinx.android.synthetic.main.view_input_bar_recording.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.utilities.animateSizeChange
|
||||
import org.thoughtcrime.securesms.loki.utilities.disableClipping
|
||||
import org.thoughtcrime.securesms.loki.utilities.toPx
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class InputBarRecordingView : RelativeLayout {
|
||||
|
||||
@ -23,6 +21,7 @@ class InputBarRecordingView : RelativeLayout {
|
||||
|
||||
private fun initialize() {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_input_bar_recording, this)
|
||||
inputBarMiddleContentContainer.disableClipping()
|
||||
}
|
||||
|
||||
fun show() {
|
||||
|
@ -50,13 +50,16 @@
|
||||
<!-- The middle content (left arrow + slide to cancel) -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/inputBarMiddleContentContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:paddingHorizontal="40dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/inputBarChevronImageView"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:src="@drawable/ic_keyboard_arrow_left_grey600_24dp"
|
||||
@ -65,6 +68,7 @@
|
||||
android:alpha="0.6" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inputBarSlideToCancelTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user