mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Fix issue with RTL
Still a pb when Mic is on, margins are not correct
This commit is contained in:
parent
30bb91892d
commit
6caa2b9ae0
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
|
<integer name="rtl_x_multiplier">-1</integer>
|
||||||
<integer name="rtl_mirror_flip">180</integer>
|
<integer name="rtl_mirror_flip">180</integer>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<integer name="default_animation_offset">200</integer>
|
<integer name="default_animation_offset">200</integer>
|
||||||
|
|
||||||
|
<integer name="rtl_x_multiplier">1</integer>
|
||||||
<integer name="rtl_mirror_flip">0</integer>
|
<integer name="rtl_mirror_flip">0</integer>
|
||||||
|
|
||||||
<integer name="splash_animation_velocity">750</integer>
|
<integer name="splash_animation_velocity">750</integer>
|
||||||
|
@ -22,6 +22,7 @@ import android.util.AttributeSet
|
|||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.hardware.vibrate
|
import im.vector.app.core.hardware.vibrate
|
||||||
@ -75,6 +76,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
private val minimumMove = dimensionConverter.dpToPx(10)
|
private val minimumMove = dimensionConverter.dpToPx(10)
|
||||||
private val distanceToLock = dimensionConverter.dpToPx(34).toFloat()
|
private val distanceToLock = dimensionConverter.dpToPx(34).toFloat()
|
||||||
private val distanceToCancel = dimensionConverter.dpToPx(120).toFloat()
|
private val distanceToCancel = dimensionConverter.dpToPx(120).toFloat()
|
||||||
|
private val rtlXMultiplier = context.resources.getInteger(R.integer.rtl_x_multiplier)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
inflate(context, R.layout.view_voice_message_recorder, this)
|
inflate(context, R.layout.view_voice_message_recorder, this)
|
||||||
@ -85,7 +87,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun initVoiceRecordingViews() {
|
fun initVoiceRecordingViews() {
|
||||||
hideRecordingViews(animationDuration = 0)
|
hideRecordingViews()
|
||||||
stopRecordingTicker()
|
stopRecordingTicker()
|
||||||
|
|
||||||
views.voiceMessageMicButton.isVisible = true
|
views.voiceMessageMicButton.isVisible = true
|
||||||
@ -95,7 +97,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
private fun initListeners() {
|
private fun initListeners() {
|
||||||
views.voiceMessageSendButton.setOnClickListener {
|
views.voiceMessageSendButton.setOnClickListener {
|
||||||
stopRecordingTicker()
|
stopRecordingTicker()
|
||||||
hideRecordingViews(animationDuration = 0)
|
hideRecordingViews()
|
||||||
views.voiceMessageSendButton.isVisible = false
|
views.voiceMessageSendButton.isVisible = false
|
||||||
recordingState = RecordingState.NONE
|
recordingState = RecordingState.NONE
|
||||||
callback?.onVoiceRecordingEnded(isCancelled = false)
|
callback?.onVoiceRecordingEnded(isCancelled = false)
|
||||||
@ -103,7 +105,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
|
|
||||||
views.voiceMessageDeletePlayback.setOnClickListener {
|
views.voiceMessageDeletePlayback.setOnClickListener {
|
||||||
stopRecordingTicker()
|
stopRecordingTicker()
|
||||||
hideRecordingViews(animationDuration = 0)
|
hideRecordingViews()
|
||||||
views.voiceMessageSendButton.isVisible = false
|
views.voiceMessageSendButton.isVisible = false
|
||||||
recordingState = RecordingState.NONE
|
recordingState = RecordingState.NONE
|
||||||
callback?.onVoiceRecordingEnded(isCancelled = true)
|
callback?.onVoiceRecordingEnded(isCancelled = true)
|
||||||
@ -178,19 +180,25 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
|
|
||||||
when (recordingState) {
|
when (recordingState) {
|
||||||
RecordingState.CANCELLING -> {
|
RecordingState.CANCELLING -> {
|
||||||
val translationAmount = -distanceX.coerceAtMost(distanceToCancel)
|
val translationAmount = distanceX.coerceAtMost(distanceToCancel)
|
||||||
views.voiceMessageMicButton.translationX = translationAmount
|
views.voiceMessageMicButton.translationX = -translationAmount * rtlXMultiplier
|
||||||
views.voiceMessageSlideToCancel.translationX = translationAmount
|
views.voiceMessageSlideToCancel.translationX = -translationAmount / 2 * rtlXMultiplier
|
||||||
views.voiceMessageSlideToCancel.alpha = 1 - abs(translationAmount) / ((firstX - views.voiceMessageTimer.x) / 3)
|
views.voiceMessageSlideToCancel.alpha = 1 - translationAmount / distanceToCancel / 3
|
||||||
views.voiceMessageLockBackground.isVisible = false
|
views.voiceMessageLockBackground.isVisible = false
|
||||||
views.voiceMessageLockImage.isVisible = false
|
views.voiceMessageLockImage.isVisible = false
|
||||||
views.voiceMessageLockArrow.isVisible = false
|
views.voiceMessageLockArrow.isVisible = false
|
||||||
|
// Reset Y translations
|
||||||
|
views.voiceMessageMicButton.translationY = 0F
|
||||||
|
views.voiceMessageLockArrow.translationY = 0F
|
||||||
}
|
}
|
||||||
RecordingState.LOCKING -> {
|
RecordingState.LOCKING -> {
|
||||||
views.voiceMessageLockImage.setImageResource(R.drawable.ic_voice_message_unlocked)
|
views.voiceMessageLockImage.setImageResource(R.drawable.ic_voice_message_unlocked)
|
||||||
val translationAmount = -distanceY.coerceIn(0F, distanceToLock)
|
val translationAmount = -distanceY.coerceIn(0F, distanceToLock)
|
||||||
views.voiceMessageMicButton.translationY = translationAmount
|
views.voiceMessageMicButton.translationY = translationAmount
|
||||||
views.voiceMessageLockArrow.translationY = translationAmount
|
views.voiceMessageLockArrow.translationY = translationAmount
|
||||||
|
// Reset X translations
|
||||||
|
views.voiceMessageMicButton.translationX = 0F
|
||||||
|
views.voiceMessageSlideToCancel.translationX = 0F
|
||||||
}
|
}
|
||||||
RecordingState.CANCELLED -> {
|
RecordingState.CANCELLED -> {
|
||||||
callback?.onVoiceRecordingEnded(true)
|
callback?.onVoiceRecordingEnded(true)
|
||||||
@ -218,19 +226,23 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
|
|
||||||
private fun updateRecordingState(currentX: Float, currentY: Float, distanceX: Float, distanceY: Float): Boolean {
|
private fun updateRecordingState(currentX: Float, currentY: Float, distanceX: Float, distanceY: Float): Boolean {
|
||||||
val previousRecordingState = recordingState
|
val previousRecordingState = recordingState
|
||||||
if (recordingState == RecordingState.STARTED) { // Determine if cancelling or locking for the first move action.
|
if (recordingState == RecordingState.STARTED) {
|
||||||
if (currentX < firstX && distanceX > distanceY) {
|
// Determine if cancelling or locking for the first move action.
|
||||||
|
if (((currentX < firstX && rtlXMultiplier == 1) || (currentX > firstX && rtlXMultiplier == -1))
|
||||||
|
&& distanceX > distanceY) {
|
||||||
recordingState = RecordingState.CANCELLING
|
recordingState = RecordingState.CANCELLING
|
||||||
} else if (currentY < firstY && distanceY > distanceX) {
|
} else if (currentY < firstY && distanceY > distanceX) {
|
||||||
recordingState = RecordingState.LOCKING
|
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) {
|
if (distanceX < minimumMove && distanceX < lastDistanceX) {
|
||||||
recordingState = RecordingState.STARTED
|
recordingState = RecordingState.STARTED
|
||||||
} else if (shouldCancelRecording(distanceX)) {
|
} else if (shouldCancelRecording(distanceX)) {
|
||||||
recordingState = RecordingState.CANCELLED
|
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) {
|
if (distanceY < minimumMove && distanceY < lastDistanceY) {
|
||||||
recordingState = RecordingState.STARTED
|
recordingState = RecordingState.STARTED
|
||||||
} else if (shouldLockRecording(distanceY)) {
|
} else if (shouldLockRecording(distanceY)) {
|
||||||
@ -323,7 +335,9 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
|
|
||||||
private fun showRecordingViews() {
|
private fun showRecordingViews() {
|
||||||
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic_recording)
|
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic_recording)
|
||||||
(views.voiceMessageMicButton.layoutParams as MarginLayoutParams).apply { setMargins(0, 0, 0, 0) }
|
views.voiceMessageMicButton.updateLayoutParams<MarginLayoutParams> {
|
||||||
|
setMargins(0, 0, 0, 0)
|
||||||
|
}
|
||||||
views.voiceMessageLockBackground.isVisible = true
|
views.voiceMessageLockBackground.isVisible = true
|
||||||
views.voiceMessageLockBackground.animate().setDuration(300).translationY(-dimensionConverter.dpToPx(148).toFloat()).start()
|
views.voiceMessageLockBackground.animate().setDuration(300).translationY(-dimensionConverter.dpToPx(148).toFloat()).start()
|
||||||
views.voiceMessageLockImage.isVisible = true
|
views.voiceMessageLockImage.isVisible = true
|
||||||
@ -337,11 +351,16 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
views.voiceMessageSendButton.isVisible = false
|
views.voiceMessageSendButton.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideRecordingViews(animationDuration: Int = 300) {
|
private fun hideRecordingViews() {
|
||||||
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic)
|
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic)
|
||||||
views.voiceMessageMicButton.animate().translationX(0f).translationY(0f).setDuration(animationDuration.toLong()).setDuration(0).start()
|
views.voiceMessageMicButton.animate().translationX(0f).translationY(0f).setDuration(0).start()
|
||||||
(views.voiceMessageMicButton.layoutParams as MarginLayoutParams).apply {
|
views.voiceMessageMicButton.updateLayoutParams<MarginLayoutParams> {
|
||||||
setMargins(0, 0, dimensionConverter.dpToPx(12), dimensionConverter.dpToPx(12))
|
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.isVisible = false
|
||||||
views.voiceMessageLockBackground.animate().translationY(0f).start()
|
views.voiceMessageLockBackground.animate().translationY(0f).start()
|
||||||
@ -357,7 +376,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showRecordingLockedViews() {
|
private fun showRecordingLockedViews() {
|
||||||
hideRecordingViews(animationDuration = 0)
|
hideRecordingViews()
|
||||||
views.voiceMessagePlaybackLayout.isVisible = true
|
views.voiceMessagePlaybackLayout.isVisible = true
|
||||||
views.voiceMessagePlaybackTimerIndicator.isVisible = true
|
views.voiceMessagePlaybackTimerIndicator.isVisible = true
|
||||||
views.voicePlaybackControlButton.isVisible = false
|
views.voicePlaybackControlButton.isVisible = false
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
android:id="@+id/voiceMessageMicButton"
|
android:id="@+id/voiceMessageMicButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:contentDescription="@string/a11y_start_voice_message"
|
android:contentDescription="@string/a11y_start_voice_message"
|
||||||
|
Loading…
Reference in New Issue
Block a user