diff --git a/library/ui-styles/src/main/res/values-ldrtl/integers.xml b/library/ui-styles/src/main/res/values-ldrtl/integers.xml
index e8a746b687..88b587c96f 100644
--- a/library/ui-styles/src/main/res/values-ldrtl/integers.xml
+++ b/library/ui-styles/src/main/res/values-ldrtl/integers.xml
@@ -1,6 +1,7 @@
+ -1
180
\ No newline at end of file
diff --git a/library/ui-styles/src/main/res/values/integers.xml b/library/ui-styles/src/main/res/values/integers.xml
index 75e8bb6f9a..2f6a1b0bc4 100644
--- a/library/ui-styles/src/main/res/values/integers.xml
+++ b/library/ui-styles/src/main/res/values/integers.xml
@@ -7,6 +7,7 @@
200
+ 1
0
750
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt
index e473ddf3cf..c59c039abf 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt
@@ -22,6 +22,7 @@ import android.util.AttributeSet
import android.view.MotionEvent
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
+import androidx.core.view.updateLayoutParams
import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.core.hardware.vibrate
@@ -75,6 +76,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
private val minimumMove = dimensionConverter.dpToPx(10)
private val distanceToLock = dimensionConverter.dpToPx(34).toFloat()
private val distanceToCancel = dimensionConverter.dpToPx(120).toFloat()
+ private val rtlXMultiplier = context.resources.getInteger(R.integer.rtl_x_multiplier)
init {
inflate(context, R.layout.view_voice_message_recorder, this)
@@ -85,7 +87,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
}
fun initVoiceRecordingViews() {
- hideRecordingViews(animationDuration = 0)
+ hideRecordingViews()
stopRecordingTicker()
views.voiceMessageMicButton.isVisible = true
@@ -95,7 +97,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
private fun initListeners() {
views.voiceMessageSendButton.setOnClickListener {
stopRecordingTicker()
- hideRecordingViews(animationDuration = 0)
+ hideRecordingViews()
views.voiceMessageSendButton.isVisible = false
recordingState = RecordingState.NONE
callback?.onVoiceRecordingEnded(isCancelled = false)
@@ -103,7 +105,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
views.voiceMessageDeletePlayback.setOnClickListener {
stopRecordingTicker()
- hideRecordingViews(animationDuration = 0)
+ hideRecordingViews()
views.voiceMessageSendButton.isVisible = false
recordingState = RecordingState.NONE
callback?.onVoiceRecordingEnded(isCancelled = true)
@@ -178,19 +180,25 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
when (recordingState) {
RecordingState.CANCELLING -> {
- val translationAmount = -distanceX.coerceAtMost(distanceToCancel)
- views.voiceMessageMicButton.translationX = translationAmount
- views.voiceMessageSlideToCancel.translationX = translationAmount
- views.voiceMessageSlideToCancel.alpha = 1 - abs(translationAmount) / ((firstX - views.voiceMessageTimer.x) / 3)
+ val translationAmount = distanceX.coerceAtMost(distanceToCancel)
+ views.voiceMessageMicButton.translationX = -translationAmount * rtlXMultiplier
+ views.voiceMessageSlideToCancel.translationX = -translationAmount / 2 * rtlXMultiplier
+ views.voiceMessageSlideToCancel.alpha = 1 - translationAmount / distanceToCancel / 3
views.voiceMessageLockBackground.isVisible = false
views.voiceMessageLockImage.isVisible = false
views.voiceMessageLockArrow.isVisible = false
+ // Reset Y translations
+ views.voiceMessageMicButton.translationY = 0F
+ views.voiceMessageLockArrow.translationY = 0F
}
RecordingState.LOCKING -> {
views.voiceMessageLockImage.setImageResource(R.drawable.ic_voice_message_unlocked)
val translationAmount = -distanceY.coerceIn(0F, distanceToLock)
views.voiceMessageMicButton.translationY = translationAmount
views.voiceMessageLockArrow.translationY = translationAmount
+ // Reset X translations
+ views.voiceMessageMicButton.translationX = 0F
+ views.voiceMessageSlideToCancel.translationX = 0F
}
RecordingState.CANCELLED -> {
callback?.onVoiceRecordingEnded(true)
@@ -218,19 +226,23 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
private fun updateRecordingState(currentX: Float, currentY: Float, distanceX: Float, distanceY: Float): Boolean {
val previousRecordingState = recordingState
- if (recordingState == RecordingState.STARTED) { // Determine if cancelling or locking for the first move action.
- if (currentX < firstX && distanceX > distanceY) {
+ if (recordingState == RecordingState.STARTED) {
+ // Determine if cancelling or locking for the first move action.
+ if (((currentX < firstX && rtlXMultiplier == 1) || (currentX > firstX && rtlXMultiplier == -1))
+ && distanceX > distanceY) {
recordingState = RecordingState.CANCELLING
} else if (currentY < firstY && distanceY > distanceX) {
recordingState = RecordingState.LOCKING
}
- } else if (recordingState == RecordingState.CANCELLING) { // Check if cancelling conditions met, also check if it should be initial state
+ } else if (recordingState == RecordingState.CANCELLING) {
+ // Check if cancelling conditions met, also check if it should be initial state
if (distanceX < minimumMove && distanceX < lastDistanceX) {
recordingState = RecordingState.STARTED
} else if (shouldCancelRecording(distanceX)) {
recordingState = RecordingState.CANCELLED
}
- } else if (recordingState == RecordingState.LOCKING) { // Check if locking conditions met, also check if it should be initial state
+ } else if (recordingState == RecordingState.LOCKING) {
+ // Check if locking conditions met, also check if it should be initial state
if (distanceY < minimumMove && distanceY < lastDistanceY) {
recordingState = RecordingState.STARTED
} else if (shouldLockRecording(distanceY)) {
@@ -323,7 +335,9 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
private fun showRecordingViews() {
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic_recording)
- (views.voiceMessageMicButton.layoutParams as MarginLayoutParams).apply { setMargins(0, 0, 0, 0) }
+ views.voiceMessageMicButton.updateLayoutParams {
+ setMargins(0, 0, 0, 0)
+ }
views.voiceMessageLockBackground.isVisible = true
views.voiceMessageLockBackground.animate().setDuration(300).translationY(-dimensionConverter.dpToPx(148).toFloat()).start()
views.voiceMessageLockImage.isVisible = true
@@ -337,11 +351,16 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
views.voiceMessageSendButton.isVisible = false
}
- private fun hideRecordingViews(animationDuration: Int = 300) {
+ private fun hideRecordingViews() {
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic)
- views.voiceMessageMicButton.animate().translationX(0f).translationY(0f).setDuration(animationDuration.toLong()).setDuration(0).start()
- (views.voiceMessageMicButton.layoutParams as MarginLayoutParams).apply {
- setMargins(0, 0, dimensionConverter.dpToPx(12), dimensionConverter.dpToPx(12))
+ views.voiceMessageMicButton.animate().translationX(0f).translationY(0f).setDuration(0).start()
+ views.voiceMessageMicButton.updateLayoutParams {
+ if (rtlXMultiplier == -1) {
+ // RTL
+ setMargins(dimensionConverter.dpToPx(10), 0, 0, dimensionConverter.dpToPx(12))
+ } else {
+ setMargins(0, 0, dimensionConverter.dpToPx(12), dimensionConverter.dpToPx(10))
+ }
}
views.voiceMessageLockBackground.isVisible = false
views.voiceMessageLockBackground.animate().translationY(0f).start()
@@ -357,7 +376,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
}
private fun showRecordingLockedViews() {
- hideRecordingViews(animationDuration = 0)
+ hideRecordingViews()
views.voiceMessagePlaybackLayout.isVisible = true
views.voiceMessagePlaybackTimerIndicator.isVisible = true
views.voicePlaybackControlButton.isVisible = false
diff --git a/vector/src/main/res/layout/view_voice_message_recorder.xml b/vector/src/main/res/layout/view_voice_message_recorder.xml
index 7736d76b0e..7aaa0bd05f 100644
--- a/vector/src/main/res/layout/view_voice_message_recorder.xml
+++ b/vector/src/main/res/layout/view_voice_message_recorder.xml
@@ -23,7 +23,7 @@
android:id="@+id/voiceMessageMicButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="12dp"
+ android:layout_marginEnd="10dp"
android:layout_marginBottom="12dp"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/a11y_start_voice_message"