call: hide preview feature
Change-Id: I8f22a67840d5f7ec4649a248894e86562af89f17
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
index 02008e0..d9272c2 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
@@ -46,6 +46,7 @@
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Rational;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -60,6 +61,7 @@
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
@@ -93,7 +95,6 @@
import cx.ring.client.ConversationSelectionActivity;
import cx.ring.client.HomeActivity;
import cx.ring.databinding.FragCallBinding;
-import cx.ring.dependencyinjection.JamiInjectionComponent;
import cx.ring.model.CallContact;
import cx.ring.model.SipCall;
import cx.ring.mvp.BaseSupportFragment;
@@ -152,6 +153,9 @@
private PointF previewDrag = null;
private final ValueAnimator previewSnapAnimation = new ValueAnimator();
private final int[] previewMargins = new int[4];
+ private float previewHiddenState = 0;
+ private enum PreviewPosition {LEFT, RIGHT}
+ private PreviewPosition previewPosition = PreviewPosition.RIGHT;
@Inject
DeviceRuntimeService mDeviceRuntimeService;
@@ -215,8 +219,7 @@
if (action != null) {
if (action.equals(ACTION_PLACE_CALL)) {
prepareCall(false);
- }
- else if (action.equals(ACTION_GET_CALL) || action.equals(CallActivity.ACTION_CALL_ACCEPT)) {
+ } else if (action.equals(ACTION_GET_CALL) || action.equals(CallActivity.ACTION_CALL_ACCEPT)) {
presenter.initIncomingCall(getArguments().getString(KEY_CONF_ID), action.equals(ACTION_GET_CALL));
}
}
@@ -320,6 +323,14 @@
}
};
+ /**
+ * @param hiddenState 0.f if fully shown, 1.f if fully hidden.
+ */
+ private void setPreviewDragHiddenState(float hiddenState) {
+ binding.previewSurface.setAlpha(1.f - (3 * hiddenState / 4));
+ binding.previewHandle.setAlpha(hiddenState);
+ }
+
@SuppressLint("ClickableViewAccessibility")
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
@@ -405,59 +416,88 @@
previewSnapAnimation.setInterpolator(new DecelerateInterpolator());
previewSnapAnimation.addUpdateListener(animation -> {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) binding.previewContainer.getLayoutParams();
- float f = margin * animation.getAnimatedFraction();
float r = 1.f - animation.getAnimatedFraction();
+ float hideMargin = 0.f;
+ float targetHiddenState = 0.f;
+ if (previewHiddenState != 0.f) {
+ targetHiddenState = 1.f;
+ float v = binding.previewContainer.getWidth() * 0.85f * animation.getAnimatedFraction();
+ hideMargin = previewPosition == PreviewPosition.RIGHT ? v : -v;
+ }
+ setPreviewDragHiddenState(previewHiddenState * r + targetHiddenState * animation.getAnimatedFraction());
+
+ float f = margin * animation.getAnimatedFraction();
params.setMargins(
- (int)(previewMargins[0] * r + f),
+ (int)(previewMargins[0] * r + f + hideMargin),
(int)(previewMargins[1] * r + f),
- (int)(previewMargins[2] * r + f),
+ (int)(previewMargins[2] * r + f - hideMargin),
(int)(previewMargins[3] * r + f));
binding.previewContainer.setLayoutParams(params);
});
binding.previewContainer.setOnTouchListener((v, event) -> {
int action = event.getActionMasked();
+ RelativeLayout parent = (RelativeLayout) v.getParent();
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams();
+
if (action == MotionEvent.ACTION_DOWN) {
previewSnapAnimation.cancel();
previewDrag = new PointF(event.getX(), event.getY());
v.setElevation(v.getContext().getResources().getDimension(R.dimen.call_preview_elevation_dragged));
- RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams();
params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
- params.setMargins((int)v.getX(), (int)v.getY(), 0, 0);
+ params.setMargins((int) v.getX(), (int) v.getY(), parent.getWidth() - ((int) v.getX() + v.getWidth()), parent.getHeight() - ((int) v.getY() + v.getHeight()));
v.setLayoutParams(params);
return true;
} else if (action == MotionEvent.ACTION_MOVE) {
if (previewDrag != null) {
- RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams();
- RelativeLayout parent = (RelativeLayout) v.getParent();
+ int currentXPosition = params.leftMargin + (int) (event.getX() - previewDrag.x);
+ int currentYPosition = params.topMargin + (int) (event.getY() - previewDrag.y);
params.setMargins(
- Math.min(params.leftMargin + (int) (event.getX() - previewDrag.x), parent.getWidth() - v.getWidth() - (int)margin),
- Math.min(params.topMargin + (int) (event.getY() - previewDrag.y), parent.getHeight() - v.getHeight() - (int)margin),
- 0, 0);
+ currentXPosition,
+ currentYPosition,
+ -((currentXPosition + v.getWidth()) - (int) event.getX()),
+ -((currentYPosition + v.getHeight()) - (int) event.getY()));
v.setLayoutParams(params);
+
+ float outPosition = binding.previewContainer.getWidth() * 0.85f;
+ float drapOut = 0.f;
+ if (currentXPosition < 0) {
+ drapOut = Math.min(1.f, -currentXPosition / outPosition);
+ } else if (currentXPosition + v.getWidth() > parent.getWidth()) {
+ drapOut = Math.min(1.f, (currentXPosition + v.getWidth() - parent.getWidth()) / outPosition);
+ }
+ setPreviewDragHiddenState(drapOut);
return true;
}
return false;
} else if (action == MotionEvent.ACTION_UP) {
if (previewDrag != null) {
+ int currentXPosition = params.leftMargin + (int) (event.getX() - previewDrag.x);
+
previewSnapAnimation.cancel();
previewDrag = null;
v.setElevation(v.getContext().getResources().getDimension(R.dimen.call_preview_elevation));
- RelativeLayout parent = (RelativeLayout) v.getParent();
- RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams();
int ml = 0, mr = 0, mt = 0, mb = 0;
+
+ FrameLayout.LayoutParams hp = (FrameLayout.LayoutParams) binding.previewHandle.getLayoutParams();
if (params.leftMargin + (v.getWidth() / 2) > parent.getWidth() / 2) {
params.removeRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
mr = (int) (parent.getWidth() - v.getWidth() - v.getX());
+ previewPosition = PreviewPosition.RIGHT;
+ hp.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT;
} else {
params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
ml = (int) v.getX();
+ previewPosition = PreviewPosition.LEFT;
+ hp.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
}
+ binding.previewHandle.setLayoutParams(hp);
+
if (params.topMargin + (v.getHeight() / 2) > parent.getHeight() / 2) {
params.removeRule(RelativeLayout.ALIGN_PARENT_TOP);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
@@ -473,6 +513,15 @@
previewMargins[3] = mb;
params.setMargins(ml, mt, mr, mb);
v.setLayoutParams(params);
+
+ float outPosition = binding.previewContainer.getWidth() * 0.85f;
+ previewHiddenState = currentXPosition < 0
+ ? Math.min(1.f, -currentXPosition / outPosition)
+ : ((currentXPosition + v.getWidth() > parent.getWidth())
+ ? Math.min(1.f, (currentXPosition + v.getWidth() - parent.getWidth()) / outPosition)
+ : 0.f);
+ setPreviewDragHiddenState(previewHiddenState);
+
previewSnapAnimation.start();
return true;
}
@@ -676,7 +725,7 @@
@Override
public void updateTime(final long duration) {
- if (binding.callStatusTxt != null) {
+ if (binding != null) {
if (duration == 0)
binding.callStatusTxt.setText(null);
else
@@ -767,7 +816,7 @@
@Override
public void initMenu(boolean isSpeakerOn, boolean displayFlip, boolean canDial, boolean onGoingCall) {
- if (binding.callCameraFlipBtn != null) {
+ if (binding != null) {
binding.callCameraFlipBtn.setVisibility(displayFlip ? View.VISIBLE : View.GONE);
}
if (dialPadBtn != null) {
diff --git a/ring-android/app/src/main/java/cx/ring/views/AutoFitTextureView.java b/ring-android/app/src/main/java/cx/ring/views/AutoFitTextureView.java
index de46975..be505d2 100644
--- a/ring-android/app/src/main/java/cx/ring/views/AutoFitTextureView.java
+++ b/ring-android/app/src/main/java/cx/ring/views/AutoFitTextureView.java
@@ -1,11 +1,16 @@
package cx.ring.views;
import android.content.Context;
+import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.TypedValue;
import android.view.TextureView;
+import androidx.core.view.ViewCompat;
+
+import java.util.Collections;
+import java.util.List;
+
/**
* A {@link TextureView} that can be adjusted to a specified aspect ratio.
*/
@@ -14,6 +19,7 @@
private int mRatioWidth = 720;
private int mRatioHeight = 1280;
private final int mSize;
+ private final List<Rect> mBounds = Collections.singletonList(new Rect());
public AutoFitTextureView(Context context) {
this(context, null);
@@ -28,6 +34,13 @@
mSize = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 192, context.getResources().getDisplayMetrics()));
}
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ mBounds.get(0).set(left, top, right, bottom);
+ ViewCompat.setSystemGestureExclusionRects(this, mBounds);
+ }
+
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
diff --git a/ring-android/app/src/main/res/drawable/ic_chevron_left_24px.xml b/ring-android/app/src/main/res/drawable/ic_chevron_left_24px.xml
new file mode 100644
index 0000000..272e1fb
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_chevron_left_24px.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/drawable/ic_chevron_right_24px.xml b/ring-android/app/src/main/res/drawable/ic_chevron_right_24px.xml
new file mode 100644
index 0000000..70a53ea
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_chevron_right_24px.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
+</vector>
diff --git a/ring-android/app/src/main/res/drawable/ic_preview_handle.xml b/ring-android/app/src/main/res/drawable/ic_preview_handle.xml
new file mode 100644
index 0000000..d6a5af0
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_preview_handle.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="3dp"
+ android:height="60dp"
+ android:viewportWidth="1.5272485"
+ android:viewportHeight="48.024227">
+ <path
+ android:pathData="M0.7636,-0L0.7636,-0A0.8484,0.7636 90,0 1,1.5272 0.8484L1.5272,47.1759A0.8484,0.7636 90,0 1,0.7636 48.0242L0.7636,48.0242A0.8484,0.7636 90,0 1,0 47.1759L0,0.8484A0.8484,0.7636 90,0 1,0.7636 -0z"
+ android:strokeWidth="0.0746897"
+ android:fillColor="#80ffffff"/>
+</vector>
diff --git a/ring-android/app/src/main/res/drawable/show_preview.xml b/ring-android/app/src/main/res/drawable/show_preview.xml
new file mode 100644
index 0000000..db8a3be
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/show_preview.xml
@@ -0,0 +1,18 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="35dp"
+ android:height="207dp"
+ android:viewportWidth="35"
+ android:viewportHeight="207">
+ <path
+ android:pathData="M4.082,0.001L30.917,0.001A4.783,4.083 90,0 1,34.999 4.783L34.999,202.216A4.783,4.083 90,0 1,30.917 206.999L4.082,206.999A4.783,4.083 90,0 1,-0.001 202.216L-0.001,4.783A4.783,4.083 90,0 1,4.082 0.001z"
+ android:strokeWidth="0.210926"
+ android:fillColor="#c8beb7"/>
+ <path
+ android:pathData="M5.329,79.488L5.329,79.488A0.848,0.764 90,0 1,6.092 80.336L6.092,126.664A0.848,0.764 90,0 1,5.329 127.512L5.329,127.512A0.848,0.764 90,0 1,4.565 126.664L4.565,80.336A0.848,0.764 90,0 1,5.329 79.488z"
+ android:strokeWidth="0.0746897"
+ android:fillColor="#241c1c"/>
+ <path
+ android:pathData="M29.738,79.488L29.738,79.488A0.905,0.764 90,0 1,30.501 80.393L30.501,126.606A0.905,0.764 90,0 1,29.738 127.512L29.738,127.512A0.905,0.764 90,0 1,28.974 126.606L28.974,80.393A0.905,0.764 90,0 1,29.738 79.488z"
+ android:strokeWidth="0.0746894"
+ android:fillColor="#241c1c"/>
+</vector>
diff --git a/ring-android/app/src/main/res/drawable/transparent_round_grey.xml b/ring-android/app/src/main/res/drawable/transparent_round_grey.xml
new file mode 100644
index 0000000..0a557ee
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/transparent_round_grey.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#D84F4F4F" />
+</shape>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/frag_call.xml b/ring-android/app/src/main/res/layout/frag_call.xml
index d738c9e..dff201d 100644
--- a/ring-android/app/src/main/res/layout/frag_call.xml
+++ b/ring-android/app/src/main/res/layout/frag_call.xml
@@ -60,14 +60,25 @@
android:visibility="gone"
app:cardCornerRadius="16dp"
app:cardPreventCornerOverlap="false"
- tools:visibility="visible">
+ tools:visibility="visible"
+ app:cardBackgroundColor="@color/black">
<cx.ring.views.AutoFitTextureView
android:id="@+id/preview_surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:visibility="visible"/>
+
+ <ImageView
+ android:id="@+id/preview_handle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|center_vertical"
+ android:layout_marginHorizontal="@dimen/call_preview_margin_handle"
android:visibility="visible"
- tools:visibility="visible" />
+ android:alpha="0"
+ app:srcCompat="@drawable/ic_preview_handle" />
+
</androidx.cardview.widget.CardView>
</RelativeLayout>
@@ -85,7 +96,7 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
- android:visibility="visible"
+ android:visibility="gone"
app:flexDirection="column"
app:flexWrap="wrap"
tools:visibility="visible">
@@ -158,8 +169,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- tools:visibility="visible">
+ android:orientation="horizontal">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/call_refuse_btn"
@@ -169,14 +179,15 @@
android:contentDescription="@string/action_call_decline"
android:onClick="@{() -> presenter.refuseClicked()}"
android:tint="@color/white"
- tools:visibility="visible"
+ android:visibility="gone"
app:backgroundTint="@color/colorError"
app:elevation="6dp"
app:fabSize="normal"
app:pressedTranslationZ="12dp"
app:rippleColor="@android:color/white"
app:srcCompat="@drawable/baseline_call_end_24"
- app:useCompatPadding="true" />
+ app:useCompatPadding="true"
+ tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/call_accept_btn"
@@ -185,14 +196,15 @@
android:layout_margin="16dp"
android:contentDescription="@string/action_call_accept"
android:onClick="@{() -> presenter.acceptClicked()}"
- android:visibility="visible"
+ android:visibility="gone"
app:backgroundTint="@color/green_500"
app:elevation="6dp"
app:fabSize="normal"
app:pressedTranslationZ="12dp"
app:rippleColor="@android:color/white"
app:srcCompat="@drawable/baseline_call_24"
- app:useCompatPadding="true" />
+ app:useCompatPadding="true"
+ tools:visibility="visible" />
</LinearLayout>
</LinearLayout>
@@ -276,14 +288,14 @@
</com.google.android.flexbox.FlexboxLayout>
<androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/conf_control_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:id="@+id/conf_control_group"
- android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
+ android:layout_alignParentEnd="true"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
- tools:listitem="@layout/item_conference_participant"
- tools:itemCount="4" />
+ tools:itemCount="4"
+ tools:listitem="@layout/item_conference_participant" />
<EditText
android:id="@+id/dialpad_edit_text"
@@ -313,5 +325,6 @@
app:useCompatPadding="true" />
</RelativeLayout>
+
</FrameLayout>
</layout>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values/dimens.xml b/ring-android/app/src/main/res/values/dimens.xml
index 275788b..2866f91 100644
--- a/ring-android/app/src/main/res/values/dimens.xml
+++ b/ring-android/app/src/main/res/values/dimens.xml
@@ -72,6 +72,8 @@
<dimen name="call_preview_elevation">8dp</dimen>
<dimen name="call_preview_elevation_dragged">16dp</dimen>
<dimen name="call_preview_margin">12dp</dimen>
+ <dimen name="call_preview_margin_big">65dp</dimen>
+ <dimen name="call_preview_margin_handle">12dp</dimen>
<dimen name="wizard_button_width">340dp</dimen>
<dimen name="wizard_button_corner_radius">12dp</dimen>
diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml
index 68c0be4..5fb04f3 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -154,6 +154,7 @@
<string name="write_a_message">Write a message</string>
<string name="scan_qr">Scan QR Code</string>
<string name="ab_action_flipcamera">Flip camera</string>
+ <string name="ab_action_hidepreview">Hide preview</string>
<!-- Text messages -->
<string name="send_message">Send message</string>