diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java b/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java index f0b42bfbc3..17bc16083d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java @@ -101,6 +101,7 @@ public class InputPanel extends ConstraintLayout private AnimatingToggle buttonToggle; private SendButton sendButton; private View recordingContainer; + private final int[] recordingContainerLocation = new int[2]; private View recordLockCancel; private View composeContainer; private View editMessageCancel; @@ -651,7 +652,9 @@ public class InputPanel extends ConstraintLayout public void onRecordMoved(float offsetX, float absoluteX) { slideToCancel.moveTo(offsetX); - float position = absoluteX / recordingContainer.getWidth(); + recordingContainer.getLocationOnScreen(recordingContainerLocation); + + float position = (absoluteX - recordingContainerLocation[0]) / recordingContainer.getWidth(); if (ViewUtil.isLtr(this) && position <= 0.5 || ViewUtil.isRtl(this) && position >= 0.6) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/MicrophoneRecorderView.java b/app/src/main/java/org/thoughtcrime/securesms/components/MicrophoneRecorderView.java index f1c215c04f..5ddeb3488c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/MicrophoneRecorderView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/MicrophoneRecorderView.java @@ -265,6 +265,7 @@ public final class MicrophoneRecorderView extends FrameLayout implements View.On } void display() { + lockDropTarget.animate().cancel(); lockDropTarget.setScaleX(1); lockDropTarget.setScaleY(1); lockDropTarget.setAlpha(0); @@ -280,11 +281,15 @@ public final class MicrophoneRecorderView extends FrameLayout implements View.On } void hide() { + if (lockDropTarget.getVisibility() != VISIBLE) return; + + lockDropTarget.animate().cancel(); lockDropTarget.animate() .setStartDelay(0) .setDuration(ANIMATION_DURATION) .setInterpolator(new LinearInterpolator()) .scaleX(0).scaleY(0) + .withEndAction(() -> lockDropTarget.setVisibility(GONE)) .start(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index b6b79be896..692fc931c5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -2702,6 +2702,14 @@ class ConversationFragment : } } + /** + * True from the moment a recording is pressed until its session finishes writing out, which outlasts the recorder + * itself: the draft is snapshotted once per second while recording, so the draft can be non-null while the panel + * still needs to present as "recording" rather than "reviewing a voice draft". + */ + private val isVoiceRecordingInFlight: Boolean + get() = inputPanel.isRecordingInProgress || (this::voiceMessageRecordingDelegate.isInitialized && voiceMessageRecordingDelegate.hasActiveSession()) + private fun updateToggleButtonState() { val buttonToggle: AnimatingToggle = binding.conversationInputPanel.buttonToggle val quickAttachment: HidingLinearLayout = binding.conversationInputPanel.quickAttachmentToggle @@ -2720,8 +2728,7 @@ class ConversationFragment : inlineAttachment.hide(false) } - // An in-progress recording snapshots itself into the draft, but its UI lives in quickAttachment and must stay visible. - draftViewModel.voiceNoteDraft != null && !inputPanel.isRecordingInProgress -> { + draftViewModel.voiceNoteDraft != null && !isVoiceRecordingInFlight -> { buttonToggle.display(sendButton) quickAttachment.hide(true) inlineAttachment.hide(true)