diff --git a/res/layout/camera_controls_landscape.xml b/res/layout/camera_controls_landscape.xml
index b0783f7c1df..bb044eb7222 100644
--- a/res/layout/camera_controls_landscape.xml
+++ b/res/layout/camera_controls_landscape.xml
@@ -6,12 +6,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
@@ -25,6 +26,7 @@
android:src="@drawable/ic_switch_camera_32"
android:scaleType="fitCenter"
android:background="?selectableItemBackgroundBorderless"
+ android:contentDescription="@string/CameraXFragment_change_camera_description"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -35,6 +37,7 @@
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginBottom="42dp"
+ android:contentDescription="@string/CameraXFragment_open_gallery_description"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="@id/camera_capture_button"
app:layout_constraintStart_toStartOf="@id/camera_capture_button"
diff --git a/res/layout/camera_controls_portrait.xml b/res/layout/camera_controls_portrait.xml
index 69b607372f5..e49f3b1a153 100644
--- a/res/layout/camera_controls_portrait.xml
+++ b/res/layout/camera_controls_portrait.xml
@@ -6,12 +6,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
@@ -25,6 +26,7 @@
android:src="@drawable/ic_switch_camera_32"
android:scaleType="fitCenter"
android:background="?selectableItemBackgroundBorderless"
+ android:contentDescription="@string/CameraXFragment_change_camera_description"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -35,6 +37,7 @@
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="32dp"
+ android:contentDescription="@string/CameraXFragment_open_gallery_description"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="@id/camera_capture_button"
app:layout_constraintBottom_toBottomOf="@id/camera_capture_button"
diff --git a/res/layout/conversation_list_fragment.xml b/res/layout/conversation_list_fragment.xml
index 01692dfc57f..26b4bf0891c 100644
--- a/res/layout/conversation_list_fragment.xml
+++ b/res/layout/conversation_list_fragment.xml
@@ -75,6 +75,7 @@
android:layout_gravity="bottom|end"
android:layout_marginEnd="16dp"
android:layout_marginBottom="88dp"
+ android:contentDescription="@string/conversation_list_fragment__open_camera_description"
android:src="@drawable/ic_camera_filled_24"
android:tint="?conversation_list_camera_icon_tint"
android:focusable="true"
diff --git a/res/layout/mediasend_activity.xml b/res/layout/mediasend_activity.xml
index df5b5e67b63..85e03539050 100644
--- a/res/layout/mediasend_activity.xml
+++ b/res/layout/mediasend_activity.xml
@@ -142,6 +142,7 @@
android:layout_gravity="bottom|end"
android:padding="6dp"
android:background="@drawable/media_continue_button_background"
+ android:contentDescription="@string/MediaSendActivity_select_recipients_description"
android:visibility="gone"
app:srcCompat="@drawable/ic_continue_24"
tools:visibility="visible"/>
diff --git a/res/menu/camera_contacts.xml b/res/menu/camera_contacts.xml
index 447cc3d3c78..44bcfd2ca42 100644
--- a/res/menu/camera_contacts.xml
+++ b/res/menu/camera_contacts.xml
@@ -4,7 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
Failed to save image.
+
+ Capture
+ Change camera
+ Open gallery
+
Recent contacts
Signal contacts
@@ -102,6 +107,7 @@
You can only use the camera button to send photos to Signal contacts.
Can\'t find who you\'re looking for?
Invite a contact to join Signal
+ Search
Remove
@@ -484,6 +490,7 @@
Send to %s
+ Open camera
Tap to select
@@ -501,6 +508,7 @@
- You can\'t share more than %d item.
- You can\'t share more than %d items.
+ Select recipients
All media
@@ -1423,6 +1431,7 @@
New conversation
+ Open Camera
Give your inbox something to write home about. Get started by messaging a friend.
diff --git a/src/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java b/src/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java
index 9816f18a61f..fa66852bc80 100644
--- a/src/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java
+++ b/src/org/thoughtcrime/securesms/mediasend/Camera1Fragment.java
@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.mediasend;
import android.annotation.SuppressLint;
-import androidx.lifecycle.ViewModelProviders;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Matrix;
@@ -10,9 +9,6 @@
import android.graphics.SurfaceTexture;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
import android.view.Display;
import android.view.GestureDetector;
import android.view.LayoutInflater;
@@ -22,14 +18,17 @@
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
-import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProviders;
+
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.Transformation;
@@ -61,7 +60,7 @@ public class Camera1Fragment extends Fragment implements CameraFragment,
private TextureView cameraPreview;
private ViewGroup controlsContainer;
private ImageButton flipButton;
- private Button captureButton;
+ private View captureButton;
private Camera1Controller camera;
private Controller controller;
private OrderEnforcer orderEnforcer;
@@ -218,7 +217,6 @@ private void presentHud(@Nullable MediaSendViewModel.HudState state) {
}
}
- @SuppressLint("ClickableViewAccessibility")
private void initControls() {
flipButton = requireView().findViewById(R.id.camera_flip_button);
captureButton = requireView().findViewById(R.id.camera_capture_button);
@@ -226,26 +224,9 @@ private void initControls() {
View galleryButton = requireView().findViewById(R.id.camera_gallery_button);
View countButton = requireView().findViewById(R.id.camera_count_button);
- captureButton.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Animation shrinkAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.camera_capture_button_shrink);
- shrinkAnimation.setFillAfter(true);
- shrinkAnimation.setFillEnabled(true);
- captureButton.startAnimation(shrinkAnimation);
- onCaptureClicked();
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_OUTSIDE:
- Animation growAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.camera_capture_button_grow);
- growAnimation.setFillAfter(true);
- growAnimation.setFillEnabled(true);
- captureButton.startAnimation(growAnimation);
- captureButton.setEnabled(false);
- break;
- }
- return true;
+ captureButton.setOnClickListener(v -> {
+ captureButton.setEnabled(false);
+ onCaptureClicked();
});
orderEnforcer.run(Stage.CAMERA_PROPERTIES_AVAILABLE, () -> {
diff --git a/src/org/thoughtcrime/securesms/mediasend/CameraButtonView.java b/src/org/thoughtcrime/securesms/mediasend/CameraButtonView.java
new file mode 100644
index 00000000000..568047c6c9b
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/mediasend/CameraButtonView.java
@@ -0,0 +1,64 @@
+package org.thoughtcrime.securesms.mediasend;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import androidx.appcompat.widget.AppCompatButton;
+
+import org.thoughtcrime.securesms.R;
+
+public final class CameraButtonView extends AppCompatButton {
+
+ private Animation shrinkAnimation;
+ private Animation growAnimation;
+
+ public CameraButtonView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public CameraButtonView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public CameraButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ public void init(Context context) {
+ shrinkAnimation = AnimationUtils.loadAnimation(context, R.anim.camera_capture_button_shrink);
+ growAnimation = AnimationUtils.loadAnimation(context, R.anim.camera_capture_button_grow);
+
+ shrinkAnimation.setFillAfter(true);
+ shrinkAnimation.setFillEnabled(true);
+
+ growAnimation.setFillAfter(true);
+ growAnimation.setFillEnabled(true);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ if (isEnabled()) {
+ startAnimation(shrinkAnimation);
+ performClick();
+ }
+ return true;
+ case MotionEvent.ACTION_UP:
+ startAnimation(growAnimation);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean performClick() {
+ return super.performClick();
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/mediasend/CameraXFragment.java b/src/org/thoughtcrime/securesms/mediasend/CameraXFragment.java
index 169da06bf3e..129d7951c07 100644
--- a/src/org/thoughtcrime/securesms/mediasend/CameraXFragment.java
+++ b/src/org/thoughtcrime/securesms/mediasend/CameraXFragment.java
@@ -11,7 +11,6 @@
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
@@ -166,26 +165,10 @@ private void initControls() {
View galleryButton = requireView().findViewById(R.id.camera_gallery_button);
View countButton = requireView().findViewById(R.id.camera_count_button);
- captureButton.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Animation shrinkAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.camera_capture_button_shrink);
- shrinkAnimation.setFillAfter(true);
- shrinkAnimation.setFillEnabled(true);
- captureButton.startAnimation(shrinkAnimation);
- onCaptureClicked();
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_OUTSIDE:
- Animation growAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.camera_capture_button_grow);
- growAnimation.setFillAfter(true);
- growAnimation.setFillEnabled(true);
- captureButton.startAnimation(growAnimation);
- captureButton.setEnabled(false);
- break;
- }
- return true;
+ captureButton.setOnClickListener(v -> {
+ captureButton.setEnabled(false);
+ flipButton.setEnabled(false);
+ onCaptureClicked();
});
if (camera.hasCameraWithLensFacing(CameraX.LensFacing.FRONT) && camera.hasCameraWithLensFacing(CameraX.LensFacing.BACK)) {
@@ -203,14 +186,15 @@ private void initControls() {
GestureDetector gestureDetector = new GestureDetector(requireContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
- flipButton.performClick();
+ if (flipButton.isEnabled()) {
+ flipButton.performClick();
+ }
return true;
}
});
camera.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event));
-
} else {
flipButton.setVisibility(View.GONE);
}