TP-40847 | Send message button for free text interaction (#8024)
This commit is contained in:
@@ -13,6 +13,8 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
@@ -84,6 +86,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import com.navi.design.utils.dpToPx
|
||||
|
||||
class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, ToolbarInteraction {
|
||||
|
||||
@@ -298,6 +301,50 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
|
||||
scrollChatToLatestMessageReceived()
|
||||
}
|
||||
}
|
||||
|
||||
fun getSendMessageIconWidthInDp(): Float? {
|
||||
val sendMessageIconWidthInPx = binding.ivSendFreeText.drawable?.intrinsicWidth
|
||||
return sendMessageIconWidthInPx?.div(resources.displayMetrics.density)
|
||||
}
|
||||
|
||||
etFreeText.addTextChangedListener(object : TextWatcher {
|
||||
var isSendButtonVisible = false
|
||||
var distance = getSendMessageIconWidthInDp()?.plus(MARGIN_TO_RIGHT)
|
||||
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?, start: Int, count: Int, after: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
val hasText = s?.isNotBlank() == true
|
||||
if (hasText && !isSendButtonVisible) {
|
||||
isSendButtonVisible = true
|
||||
val viewsToMove = listOf(
|
||||
Pair(
|
||||
ivSendAttachment, -dpToPx((distance ?: 0f).toInt()).toInt()
|
||||
), Pair(
|
||||
ivSendFreeText, -dpToPx((distance ?: 0f).toInt()).toInt()
|
||||
)
|
||||
)
|
||||
moveViewsTogetherWithDistance(viewsToMove, ANIMATION_DURATION)
|
||||
} else if (!hasText) {
|
||||
isSendButtonVisible = false
|
||||
val viewsToMove = listOf(
|
||||
Pair(
|
||||
ivSendFreeText, dpToPx((distance ?: 0f).toInt()).toInt()
|
||||
), Pair(
|
||||
ivSendAttachment, dpToPx(0f.toInt()).toInt()
|
||||
)
|
||||
)
|
||||
moveViewsTogetherWithDistance(viewsToMove, ANIMATION_DURATION)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,7 +809,7 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
|
||||
chatDataProvider.writeMessage(
|
||||
formPlainTextNewMessage(
|
||||
metaData = metaData,
|
||||
message = message,
|
||||
message = message.trim(),
|
||||
senderName = naviChatSystemLocalData?.currentUserName ?: EMPTY,
|
||||
senderId = naviChatSystemLocalData?.externalCustomerId ?: EMPTY
|
||||
)
|
||||
@@ -1308,6 +1355,8 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
|
||||
private const val DELAY_TO_SCROLL = 200L
|
||||
private const val RECYCLER_VIEW_BOOT_DELAY = 3000L
|
||||
private const val DELAY_TO_HIDE_TYPING = 10000L
|
||||
private const val MARGIN_TO_RIGHT = 16
|
||||
private const val ANIMATION_DURATION = 400L
|
||||
const val STORAGE_PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M13.103,17.6C12.959,17.705 12.816,17.812 12.67,17.915C11.9,18.467 11.039,18.76 10.094,18.816C8.93,18.885 7.876,18.564 6.953,17.867C5.814,17.008 5.157,15.853 5.032,14.427C4.981,13.843 5.006,13.252 5.007,12.665C5.012,9.924 5.027,7.183 5.026,4.442C5.026,3.568 5.249,2.771 5.779,2.08C6.438,1.222 7.318,0.729 8.4,0.64C9.673,0.534 10.725,0.997 11.539,1.969C12.093,2.631 12.344,3.418 12.342,4.283C12.332,7.232 12.326,10.182 12.307,13.131C12.297,14.687 11.001,15.782 9.463,15.555C8.303,15.384 7.437,14.365 7.436,13.138C7.434,11.279 7.449,9.42 7.458,7.562C7.46,7.281 7.607,7.131 7.886,7.121C8.056,7.115 8.227,7.114 8.398,7.113C8.73,7.11 8.887,7.265 8.886,7.598C8.879,9.414 8.871,11.23 8.862,13.046C8.861,13.251 8.913,13.437 9.022,13.61C9.259,13.983 9.707,14.156 10.135,14.037C10.575,13.915 10.881,13.538 10.884,13.095C10.893,12.08 10.895,11.065 10.899,10.051C10.907,8.145 10.913,6.238 10.922,4.332C10.925,3.69 10.718,3.134 10.258,2.681C9.516,1.949 8.358,1.835 7.488,2.408C6.845,2.831 6.489,3.434 6.471,4.198C6.442,5.383 6.453,6.569 6.448,7.754C6.438,9.779 6.433,11.803 6.418,13.828C6.412,14.656 6.615,15.415 7.133,16.069C7.882,17.015 8.864,17.479 10.074,17.398C11.885,17.278 13.317,15.749 13.313,13.862C13.308,11.786 13.325,9.709 13.332,7.632C13.334,7.227 13.465,7.095 13.871,7.093C14.014,7.092 14.156,7.092 14.298,7.092C14.599,7.094 14.756,7.245 14.756,7.547C14.757,8.177 14.752,8.808 14.751,9.438C14.747,10.908 14.739,12.378 14.74,13.848C14.741,14.867 14.47,15.802 13.907,16.65C13.782,16.838 13.64,17.015 13.505,17.197L13.103,17.6H13.103Z"
|
||||
android:fillColor="#1F002A"/>
|
||||
</vector>
|
||||
20
navi-chat/src/main/res/drawable/ic_send_msg_purple.xml
Normal file
20
navi-chat/src/main/res/drawable/ic_send_msg_purple.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="34dp"
|
||||
android:height="34dp"
|
||||
android:viewportWidth="36"
|
||||
android:viewportHeight="36">
|
||||
<path
|
||||
android:pathData="M18,18m-18,0a18,18 0,1 1,36 0a18,18 0,1 1,-36 0"
|
||||
android:fillColor="#1F002A"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M7,7h22v22h-22z"/>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M12.325,6l16.437,12.237l-10.325,13.868l-16.437,-12.237z"/>
|
||||
<path
|
||||
android:pathData="M15.475,17.776C14.653,17.651 13.831,17.524 13.009,17.403C12.282,17.295 11.555,17.201 10.83,17.077C9.926,16.92 9.335,16.345 9.239,15.436C9.083,13.979 8.969,12.517 8.866,11.053C8.82,10.385 9.329,9.979 9.962,10.223C11.534,10.83 13.088,11.489 14.644,12.139C19.021,13.963 23.397,15.797 27.774,17.629C27.92,17.691 28.089,17.726 28.204,17.824C28.38,17.973 28.646,18.177 28.638,18.34C28.628,18.505 28.356,18.717 28.154,18.794C27.142,19.172 26.118,19.516 25.096,19.865C20.821,21.323 16.548,22.778 12.274,24.234C11.5,24.497 10.723,24.761 9.947,25.017C8.951,25.345 8.457,24.931 8.593,23.884C8.76,22.596 8.932,21.305 9.097,20.017C9.224,19.029 9.882,18.368 10.87,18.291C12.247,18.181 13.625,18.088 15.004,17.991C15.16,17.979 15.317,17.978 15.474,17.973L15.476,17.779L15.475,17.776Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -47,7 +47,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/clFreeText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/layout_dp_56"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
@@ -57,6 +57,13 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/viewSeparator">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/verticalGuideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.77" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/etFreeText"
|
||||
android:layout_width="@dimen/layout_dp_0"
|
||||
@@ -73,7 +80,7 @@
|
||||
android:textColor="@color/title_color_two"
|
||||
android:textSize="@dimen/font_small"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/ivSendAttachment"
|
||||
app:layout_constraintEnd_toStartOf="@id/verticalGuideline"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
@@ -81,23 +88,20 @@
|
||||
android:id="@+id/ivSendAttachment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/ivSendFreeText"
|
||||
app:layout_constraintStart_toEndOf="@id/etFreeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_add_attachment" />
|
||||
app:srcCompat="@drawable/ic_add_attachment_purple" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ivSendFreeText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/dp_14"
|
||||
android:layout_marginStart="@dimen/dp_14"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/ivSendAttachment"
|
||||
app:layout_constraintStart_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_send_msg" />
|
||||
app:srcCompat="@drawable/ic_send_msg_purple" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.navi.naviwidgets.utils
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.graphics.Path
|
||||
import android.view.View
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import com.navi.naviwidgets.R
|
||||
|
||||
fun moveAnimationAsPath(
|
||||
@@ -47,4 +50,21 @@ class InAnimationAdapter(private val view: View?, private val animationEndedCall
|
||||
}
|
||||
|
||||
override fun onAnimationRepeat(animation: Animation?) {}
|
||||
}
|
||||
|
||||
fun moveViewsTogetherWithDistance(
|
||||
views: List<Pair<View, Int>>, animDuration: Long = 1000
|
||||
) {
|
||||
val animatorSet = AnimatorSet()
|
||||
val animators = mutableListOf<Animator>()
|
||||
|
||||
for ((view, distance) in views) {
|
||||
val animator = ObjectAnimator.ofFloat(view, "translationX", distance.toFloat())
|
||||
animator.duration = animDuration
|
||||
animator.interpolator = OvershootInterpolator(1.5f)
|
||||
animators.add(animator)
|
||||
}
|
||||
|
||||
animatorSet.playTogether(animators)
|
||||
animatorSet.start()
|
||||
}
|
||||
Reference in New Issue
Block a user