Update camera layout for better support across different screen sizes.
This commit is contained in:
parent
993e49db48
commit
24b7593178
20 changed files with 407 additions and 299 deletions
|
@ -554,7 +554,7 @@
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".mediasend.AvatarSelectionActivity"
|
<activity android:name=".mediasend.AvatarSelectionActivity"
|
||||||
android:theme="@style/TextSecure.FullScreenMedia"
|
android:theme="@style/TextSecure.DarkNoActionBar"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
<activity android:name=".blocked.BlockedUsersActivity"
|
<activity android:name=".blocked.BlockedUsersActivity"
|
||||||
|
@ -659,7 +659,7 @@
|
||||||
|
|
||||||
<activity android:name=".wallpaper.crop.WallpaperImageSelectionActivity"
|
<activity android:name=".wallpaper.crop.WallpaperImageSelectionActivity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
android:theme="@style/TextSecure.FullScreenMedia" />
|
android:theme="@style/TextSecure.DarkNoActionBar" />
|
||||||
|
|
||||||
<activity android:name=".wallpaper.crop.WallpaperCropActivity"
|
<activity android:name=".wallpaper.crop.WallpaperCropActivity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Intent;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -62,6 +63,11 @@ public class AvatarSelectionActivity extends AppCompatActivity implements Camera
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
getWindow().addFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
);
|
||||||
|
|
||||||
setContentView(R.layout.avatar_selection_activity);
|
setContentView(R.layout.avatar_selection_activity);
|
||||||
|
|
||||||
if (isGalleryFirst()) {
|
if (isGalleryFirst()) {
|
||||||
|
|
|
@ -27,6 +27,11 @@ import android.widget.ImageView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.Px;
|
||||||
|
import androidx.cardview.widget.CardView;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintSet;
|
||||||
|
import androidx.core.view.ViewKt;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.load.MultiTransformation;
|
import com.bumptech.glide.load.MultiTransformation;
|
||||||
|
@ -48,6 +53,7 @@ import org.thoughtcrime.securesms.stories.viewer.page.StoryDisplay;
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||||
import org.signal.core.util.Stopwatch;
|
import org.signal.core.util.Stopwatch;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
@ -125,7 +131,7 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
|
||||||
|
|
||||||
View cameraParent = view.findViewById(R.id.camera_preview_parent);
|
View cameraParent = view.findViewById(R.id.camera_preview_parent);
|
||||||
|
|
||||||
onOrientationChanged(getResources().getConfiguration().orientation);
|
onOrientationChanged();
|
||||||
|
|
||||||
cameraPreview.setSurfaceTextureListener(this);
|
cameraPreview.setSurfaceTextureListener(this);
|
||||||
|
|
||||||
|
@ -134,7 +140,7 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
|
||||||
|
|
||||||
view.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
view.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
||||||
// Let's assume portrait for now, so 9:16
|
// Let's assume portrait for now, so 9:16
|
||||||
float aspectRatio = CameraFragment.getAspectRatioForOrientation(getResources().getConfiguration().orientation);
|
float aspectRatio = CameraFragment.getAspectRatioForOrientation(Configuration.ORIENTATION_PORTRAIT);
|
||||||
float width = right - left;
|
float width = right - left;
|
||||||
float height = Math.min((1f / aspectRatio) * width, bottom - top);
|
float height = Math.min((1f / aspectRatio) * width, bottom - top);
|
||||||
|
|
||||||
|
@ -231,12 +237,6 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
onOrientationChanged(newConfig.orientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||||
Log.d(TAG, "onSurfaceTextureAvailable");
|
Log.d(TAG, "onSurfaceTextureAvailable");
|
||||||
|
@ -322,25 +322,13 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
|
||||||
|
|
||||||
View galleryButton = requireView().findViewById(R.id.camera_gallery_button);
|
View galleryButton = requireView().findViewById(R.id.camera_gallery_button);
|
||||||
View countButton = requireView().findViewById(R.id.camera_review_button);
|
View countButton = requireView().findViewById(R.id.camera_review_button);
|
||||||
View toggleSpacer = requireView().findViewById(R.id.toggle_spacer);
|
|
||||||
|
|
||||||
mostRecentItemDisposable.dispose();
|
mostRecentItemDisposable.dispose();
|
||||||
mostRecentItemDisposable = controller.getMostRecentMediaItem()
|
mostRecentItemDisposable = controller.getMostRecentMediaItem()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(item -> presentRecentItemThumbnail(item.orElse(null)));
|
.subscribe(item -> presentRecentItemThumbnail(item.orElse(null)));
|
||||||
|
|
||||||
if (toggleSpacer != null) {
|
initializeViewFinderAndControlsPositioning();
|
||||||
if (Stories.isFeatureEnabled()) {
|
|
||||||
StoryDisplay storyDisplay = StoryDisplay.Companion.getStoryDisplay(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
|
|
||||||
if (storyDisplay == StoryDisplay.SMALL) {
|
|
||||||
toggleSpacer.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
toggleSpacer.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
toggleSpacer.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
captureButton.setOnClickListener(v -> {
|
captureButton.setOnClickListener(v -> {
|
||||||
captureButton.setEnabled(false);
|
captureButton.setEnabled(false);
|
||||||
|
@ -368,6 +356,27 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
|
||||||
countButton.setOnClickListener(v -> controller.onCameraCountButtonClicked());
|
countButton.setOnClickListener(v -> controller.onCameraCountButtonClicked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeViewFinderAndControlsPositioning() {
|
||||||
|
CardView cameraCard = requireView().findViewById(R.id.camera_preview_parent);
|
||||||
|
View controls = requireView().findViewById(R.id.camera_controls_container);
|
||||||
|
CameraDisplay cameraDisplay = CameraDisplay.getDisplay(requireView());
|
||||||
|
|
||||||
|
if (!cameraDisplay.getRoundViewFinderCorners()) {
|
||||||
|
cameraCard.setRadius(0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewUtil.setBottomMargin(controls, cameraDisplay.getCameraCaptureMarginBottom(getResources()));
|
||||||
|
|
||||||
|
if (cameraDisplay.getCameraViewportGravity() == CameraDisplay.CameraViewportGravity.CENTER) {
|
||||||
|
ConstraintSet constraintSet = new ConstraintSet();
|
||||||
|
constraintSet.clone((ConstraintLayout) requireView());
|
||||||
|
constraintSet.connect(R.id.camera_preview_parent, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
|
||||||
|
constraintSet.applyTo((ConstraintLayout) requireView());
|
||||||
|
} else {
|
||||||
|
ViewUtil.setBottomMargin(cameraCard, cameraDisplay.getCameraViewportMarginBottom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onCaptureClicked() {
|
private void onCaptureClicked() {
|
||||||
orderEnforcer.reset();
|
orderEnforcer.reset();
|
||||||
|
|
||||||
|
@ -426,9 +435,8 @@ public class Camera1Fragment extends LoggingFragment implements CameraFragment,
|
||||||
return new PointF(scaleX, scaleY);
|
return new PointF(scaleX, scaleY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onOrientationChanged(int orientation) {
|
private void onOrientationChanged() {
|
||||||
int layout = orientation == Configuration.ORIENTATION_PORTRAIT ? R.layout.camera_controls_portrait
|
int layout = R.layout.camera_controls_portrait;
|
||||||
: R.layout.camera_controls_landscape;
|
|
||||||
|
|
||||||
controlsContainer.removeAllViews();
|
controlsContainer.removeAllViews();
|
||||||
controlsContainer.addView(LayoutInflater.from(getContext()).inflate(layout, controlsContainer, false));
|
controlsContainer.addView(LayoutInflater.from(getContext()).inflate(layout, controlsContainer, false));
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
package org.thoughtcrime.securesms.mediasend
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.view.View
|
||||||
|
import androidx.annotation.Dimension
|
||||||
|
import androidx.annotation.Px
|
||||||
|
import androidx.window.WindowManager
|
||||||
|
import org.signal.core.util.dp
|
||||||
|
import org.thoughtcrime.securesms.R
|
||||||
|
import org.thoughtcrime.securesms.stories.Stories
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the Camera Viewport, Controls, and Toggle position information.
|
||||||
|
*/
|
||||||
|
enum class CameraDisplay(
|
||||||
|
private val aspectRatio: Float,
|
||||||
|
val roundViewFinderCorners: Boolean,
|
||||||
|
private val withTogglePositionInfo: PositionInfo,
|
||||||
|
private val withoutTogglePositionInfo: PositionInfo,
|
||||||
|
@Dimension(unit = Dimension.DP) private val toggleBottomMargin: Int
|
||||||
|
) {
|
||||||
|
DISPLAY_20_9(
|
||||||
|
aspectRatio = 9f / 20f,
|
||||||
|
roundViewFinderCorners = true,
|
||||||
|
withTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 130,
|
||||||
|
cameraViewportMarginBottomDp = 106,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.BOTTOM
|
||||||
|
),
|
||||||
|
withoutTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 130,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.CENTER
|
||||||
|
),
|
||||||
|
toggleBottomMargin = 52
|
||||||
|
),
|
||||||
|
DISPLAY_19_9(
|
||||||
|
aspectRatio = 9f / 19f,
|
||||||
|
roundViewFinderCorners = true,
|
||||||
|
withTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 128,
|
||||||
|
cameraViewportMarginBottomDp = 104,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.BOTTOM
|
||||||
|
),
|
||||||
|
withoutTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 128,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.CENTER
|
||||||
|
),
|
||||||
|
toggleBottomMargin = 52
|
||||||
|
),
|
||||||
|
DISPLAY_18_9(
|
||||||
|
aspectRatio = 9f / 18f,
|
||||||
|
roundViewFinderCorners = true,
|
||||||
|
withTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 120,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.CENTER
|
||||||
|
),
|
||||||
|
withoutTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 84,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.CENTER
|
||||||
|
),
|
||||||
|
toggleBottomMargin = 54
|
||||||
|
),
|
||||||
|
DISPLAY_16_9(
|
||||||
|
aspectRatio = 9f / 16f,
|
||||||
|
roundViewFinderCorners = false,
|
||||||
|
withTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 120,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.BOTTOM
|
||||||
|
),
|
||||||
|
withoutTogglePositionInfo = PositionInfo(
|
||||||
|
cameraCaptureMarginBottomDp = 84,
|
||||||
|
cameraViewportGravity = CameraViewportGravity.BOTTOM
|
||||||
|
),
|
||||||
|
toggleBottomMargin = 54
|
||||||
|
);
|
||||||
|
|
||||||
|
@Px
|
||||||
|
fun getCameraCaptureMarginBottom(resources: Resources): Int {
|
||||||
|
val positionInfo = if (Stories.isFeatureEnabled()) withTogglePositionInfo else withoutTogglePositionInfo
|
||||||
|
|
||||||
|
return positionInfo.cameraCaptureMarginBottomDp.dp - getCameraButtonSizeOffset(resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Px
|
||||||
|
fun getCameraViewportMarginBottom(): Int {
|
||||||
|
val positionInfo = if (Stories.isFeatureEnabled()) withTogglePositionInfo else withoutTogglePositionInfo
|
||||||
|
|
||||||
|
return positionInfo.cameraViewportMarginBottomDp.dp
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCameraViewportGravity(): CameraViewportGravity {
|
||||||
|
val positionInfo = if (Stories.isFeatureEnabled()) withTogglePositionInfo else withoutTogglePositionInfo
|
||||||
|
|
||||||
|
return positionInfo.cameraViewportGravity
|
||||||
|
}
|
||||||
|
|
||||||
|
@Px
|
||||||
|
fun getToggleBottomMargin(): Int {
|
||||||
|
return toggleBottomMargin.dp
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Px
|
||||||
|
@JvmStatic
|
||||||
|
private fun getCameraButtonSizeOffset(resources: Resources): Int {
|
||||||
|
val cameraCaptureButtonSize = resources.getDimensionPixelSize(R.dimen.camera_capture_button_size)
|
||||||
|
val cameraCaptureImageButtonSize = resources.getDimensionPixelSize(R.dimen.camera_capture_image_button_size)
|
||||||
|
|
||||||
|
return (cameraCaptureButtonSize - cameraCaptureImageButtonSize) / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getDisplay(view: View): CameraDisplay {
|
||||||
|
val windowManager = WindowManager(view.context)
|
||||||
|
val windowMetrics = windowManager.getCurrentWindowMetrics()
|
||||||
|
val width = windowMetrics.bounds.width()
|
||||||
|
val height = windowMetrics.bounds.height()
|
||||||
|
val aspectRatio = width.toFloat() / height
|
||||||
|
|
||||||
|
return when {
|
||||||
|
aspectRatio <= DISPLAY_20_9.aspectRatio -> DISPLAY_20_9
|
||||||
|
aspectRatio <= DISPLAY_19_9.aspectRatio -> DISPLAY_19_9
|
||||||
|
aspectRatio <= DISPLAY_18_9.aspectRatio -> DISPLAY_18_9
|
||||||
|
else -> DISPLAY_16_9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class CameraViewportGravity {
|
||||||
|
CENTER,
|
||||||
|
BOTTOM
|
||||||
|
}
|
||||||
|
|
||||||
|
data class PositionInfo(
|
||||||
|
@Dimension(unit = Dimension.DP) val cameraCaptureMarginBottomDp: Int,
|
||||||
|
@Dimension(unit = Dimension.DP) val cameraViewportMarginBottomDp: Int = 0,
|
||||||
|
val cameraViewportGravity: CameraViewportGravity
|
||||||
|
)
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ package org.thoughtcrime.securesms.mediasend;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.camera.view.video.ExperimentalVideo;
|
import androidx.camera.view.video.ExperimentalVideo;
|
||||||
|
|
|
@ -25,21 +25,23 @@ import android.widget.ImageView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.camera.core.AspectRatio;
|
|
||||||
import androidx.camera.core.CameraSelector;
|
import androidx.camera.core.CameraSelector;
|
||||||
import androidx.camera.core.ImageCapture;
|
import androidx.camera.core.ImageCapture;
|
||||||
import androidx.camera.core.ImageCaptureException;
|
import androidx.camera.core.ImageCaptureException;
|
||||||
import androidx.camera.core.ImageProxy;
|
import androidx.camera.core.ImageProxy;
|
||||||
import androidx.camera.core.Preview;
|
|
||||||
import androidx.camera.view.CameraController;
|
import androidx.camera.view.CameraController;
|
||||||
import androidx.camera.view.LifecycleCameraController;
|
import androidx.camera.view.LifecycleCameraController;
|
||||||
import androidx.camera.view.PreviewView;
|
import androidx.camera.view.PreviewView;
|
||||||
import androidx.camera.view.video.ExperimentalVideo;
|
import androidx.camera.view.video.ExperimentalVideo;
|
||||||
|
import androidx.cardview.widget.CardView;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintSet;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.util.Executors;
|
import com.bumptech.glide.util.Executors;
|
||||||
|
|
||||||
|
import org.signal.core.util.Stopwatch;
|
||||||
import org.signal.core.util.concurrent.SimpleTask;
|
import org.signal.core.util.concurrent.SimpleTask;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.LoggingFragment;
|
import org.thoughtcrime.securesms.LoggingFragment;
|
||||||
|
@ -52,11 +54,9 @@ import org.thoughtcrime.securesms.mediasend.v2.MediaAnimations;
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.MediaCountIndicatorButton;
|
import org.thoughtcrime.securesms.mediasend.v2.MediaCountIndicatorButton;
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||||
import org.thoughtcrime.securesms.stories.Stories;
|
|
||||||
import org.thoughtcrime.securesms.stories.viewer.page.StoryDisplay;
|
|
||||||
import org.thoughtcrime.securesms.util.MemoryFileDescriptor;
|
import org.thoughtcrime.securesms.util.MemoryFileDescriptor;
|
||||||
import org.signal.core.util.Stopwatch;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
import org.thoughtcrime.securesms.video.VideoUtil;
|
import org.thoughtcrime.securesms.video.VideoUtil;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
@ -147,11 +147,11 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
previewView.setScaleType(PREVIEW_SCALE_TYPE);
|
previewView.setScaleType(PREVIEW_SCALE_TYPE);
|
||||||
previewView.setController(cameraController);
|
previewView.setController(cameraController);
|
||||||
|
|
||||||
onOrientationChanged(getResources().getConfiguration().orientation);
|
onOrientationChanged();
|
||||||
|
|
||||||
view.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
view.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
|
||||||
// Let's assume portrait for now, so 9:16
|
// Let's assume portrait for now, so 9:16
|
||||||
float aspectRatio = CameraFragment.getAspectRatioForOrientation(getResources().getConfiguration().orientation);
|
float aspectRatio = CameraFragment.getAspectRatioForOrientation(Configuration.ORIENTATION_PORTRAIT);
|
||||||
float width = right - left;
|
float width = right - left;
|
||||||
float height = Math.min((1f / aspectRatio) * width, bottom - top);
|
float height = Math.min((1f / aspectRatio) * width, bottom - top);
|
||||||
|
|
||||||
|
@ -176,6 +176,11 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
@ -184,12 +189,6 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
|
requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
onOrientationChanged(newConfig.orientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fadeOutControls(@NonNull Runnable onEndAction) {
|
public void fadeOutControls(@NonNull Runnable onEndAction) {
|
||||||
controlsContainer.setEnabled(false);
|
controlsContainer.setEnabled(false);
|
||||||
|
@ -221,12 +220,11 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onOrientationChanged(int orientation) {
|
private void onOrientationChanged() {
|
||||||
int layout = orientation == Configuration.ORIENTATION_PORTRAIT ? R.layout.camera_controls_portrait
|
int layout = R.layout.camera_controls_portrait;
|
||||||
: R.layout.camera_controls_landscape;
|
|
||||||
|
|
||||||
int resolution = CameraXUtil.getIdealResolution(Resources.getSystem().getDisplayMetrics().widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels);
|
int resolution = CameraXUtil.getIdealResolution(Resources.getSystem().getDisplayMetrics().widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels);
|
||||||
Size size = CameraXUtil.buildResolutionForRatio(resolution, ASPECT_RATIO_16_9, orientation == Configuration.ORIENTATION_PORTRAIT);
|
Size size = CameraXUtil.buildResolutionForRatio(resolution, ASPECT_RATIO_16_9, true);
|
||||||
CameraController.OutputSize outputSize = new CameraController.OutputSize(size);
|
CameraController.OutputSize outputSize = new CameraController.OutputSize(size);
|
||||||
|
|
||||||
cameraController.setImageCaptureTargetSize(outputSize);
|
cameraController.setImageCaptureTargetSize(outputSize);
|
||||||
|
@ -280,28 +278,37 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint({"ClickableViewAccessibility", "MissingPermission"})
|
private void initializeViewFinderAndControlsPositioning() {
|
||||||
private void initControls() {
|
CardView cameraCard = requireView().findViewById(R.id.camerax_camera_parent);
|
||||||
View flipButton = requireView().findViewById(R.id.camera_flip_button);
|
View controls = requireView().findViewById(R.id.camerax_controls_container);
|
||||||
CameraButtonView captureButton = requireView().findViewById(R.id.camera_capture_button);
|
CameraDisplay cameraDisplay = CameraDisplay.getDisplay(requireView());
|
||||||
View galleryButton = requireView().findViewById(R.id.camera_gallery_button);
|
|
||||||
View countButton = requireView().findViewById(R.id.camera_review_button);
|
|
||||||
CameraXFlashToggleView flashButton = requireView().findViewById(R.id.camera_flash_button);
|
|
||||||
View toggleSpacer = requireView().findViewById(R.id.toggle_spacer);
|
|
||||||
|
|
||||||
if (toggleSpacer != null) {
|
if (!cameraDisplay.getRoundViewFinderCorners()) {
|
||||||
if ( Stories.isFeatureEnabled()) {
|
cameraCard.setRadius(0f);
|
||||||
StoryDisplay storyDisplay = StoryDisplay.Companion.getStoryDisplay(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
|
|
||||||
if (storyDisplay == StoryDisplay.SMALL) {
|
|
||||||
toggleSpacer.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
toggleSpacer.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
toggleSpacer.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewUtil.setBottomMargin(controls, cameraDisplay.getCameraCaptureMarginBottom(getResources()));
|
||||||
|
|
||||||
|
if (cameraDisplay.getCameraViewportGravity() == CameraDisplay.CameraViewportGravity.CENTER) {
|
||||||
|
ConstraintSet constraintSet = new ConstraintSet();
|
||||||
|
constraintSet.clone((ConstraintLayout) requireView());
|
||||||
|
constraintSet.connect(R.id.camerax_camera_parent, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
|
||||||
|
constraintSet.applyTo((ConstraintLayout) requireView());
|
||||||
|
} else {
|
||||||
|
ViewUtil.setBottomMargin(cameraCard, cameraDisplay.getCameraViewportMarginBottom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint({ "ClickableViewAccessibility", "MissingPermission" })
|
||||||
|
private void initControls() {
|
||||||
|
View flipButton = requireView().findViewById(R.id.camera_flip_button);
|
||||||
|
CameraButtonView captureButton = requireView().findViewById(R.id.camera_capture_button);
|
||||||
|
View galleryButton = requireView().findViewById(R.id.camera_gallery_button);
|
||||||
|
View countButton = requireView().findViewById(R.id.camera_review_button);
|
||||||
|
CameraXFlashToggleView flashButton = requireView().findViewById(R.id.camera_flash_button);
|
||||||
|
|
||||||
|
initializeViewFinderAndControlsPositioning();
|
||||||
|
|
||||||
mostRecentItemDisposable.dispose();
|
mostRecentItemDisposable.dispose();
|
||||||
mostRecentItemDisposable = controller.getMostRecentMediaItem()
|
mostRecentItemDisposable = controller.getMostRecentMediaItem()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
@ -392,10 +399,10 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isVideoRecordingSupported(@NonNull Context context) {
|
private boolean isVideoRecordingSupported(@NonNull Context context) {
|
||||||
return Build.VERSION.SDK_INT >= 26 &&
|
return Build.VERSION.SDK_INT >= 26 &&
|
||||||
requireArguments().getBoolean(IS_VIDEO_ENABLED, true) &&
|
requireArguments().getBoolean(IS_VIDEO_ENABLED, true) &&
|
||||||
MediaConstraints.isVideoTranscodeAvailable() &&
|
MediaConstraints.isVideoTranscodeAvailable() &&
|
||||||
CameraXUtil.isMixedModeSupported(context) &&
|
CameraXUtil.isMixedModeSupported(context) &&
|
||||||
VideoUtil.getMaxVideoRecordDurationInSeconds(context, controller.getMediaConstraints()) > 0;
|
VideoUtil.getMaxVideoRecordDurationInSeconds(context, controller.getMediaConstraints()) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +516,7 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint({"MissingPermission"})
|
@SuppressLint({ "MissingPermission" })
|
||||||
private void initializeFlipButton(@NonNull View flipButton, @NonNull CameraXFlashToggleView flashButton) {
|
private void initializeFlipButton(@NonNull View flipButton, @NonNull CameraXFlashToggleView flashButton) {
|
||||||
if (getContext() == null) {
|
if (getContext() == null) {
|
||||||
Log.w(TAG, "initializeFlipButton called either before or after fragment was attached.");
|
Log.w(TAG, "initializeFlipButton called either before or after fragment was attached.");
|
||||||
|
@ -518,7 +525,7 @@ public class CameraXFragment extends LoggingFragment implements CameraFragment {
|
||||||
|
|
||||||
if (cameraController.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA) && cameraController.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA)) {
|
if (cameraController.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA) && cameraController.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA)) {
|
||||||
flipButton.setVisibility(View.VISIBLE);
|
flipButton.setVisibility(View.VISIBLE);
|
||||||
flipButton.setOnClickListener(v -> {
|
flipButton.setOnClickListener(v -> {
|
||||||
cameraController.setCameraSelector(cameraController.getCameraSelector() == CameraSelector.DEFAULT_FRONT_CAMERA
|
cameraController.setCameraSelector(cameraController.getCameraSelector() == CameraSelector.DEFAULT_FRONT_CAMERA
|
||||||
? CameraSelector.DEFAULT_BACK_CAMERA
|
? CameraSelector.DEFAULT_BACK_CAMERA
|
||||||
: CameraSelector.DEFAULT_FRONT_CAMERA);
|
: CameraSelector.DEFAULT_FRONT_CAMERA);
|
||||||
|
|
|
@ -6,6 +6,8 @@ import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.widget.FrameLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
@ -13,6 +15,7 @@ import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.constraintlayout.widget.ConstraintSet
|
import androidx.constraintlayout.widget.ConstraintSet
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
@ -29,6 +32,7 @@ import org.thoughtcrime.securesms.conversation.MessageSendType
|
||||||
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageFragment
|
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageFragment
|
||||||
import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchFragment
|
import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchFragment
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil
|
||||||
|
import org.thoughtcrime.securesms.mediasend.CameraDisplay
|
||||||
import org.thoughtcrime.securesms.mediasend.Media
|
import org.thoughtcrime.securesms.mediasend.Media
|
||||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivityResult
|
import org.thoughtcrime.securesms.mediasend.MediaSendActivityResult
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.review.MediaReviewFragment
|
import org.thoughtcrime.securesms.mediasend.v2.review.MediaReviewFragment
|
||||||
|
@ -80,6 +84,10 @@ class MediaSelectionActivity :
|
||||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||||
setContentView(R.layout.media_selection_activity)
|
setContentView(R.layout.media_selection_activity)
|
||||||
|
|
||||||
|
window.addFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
)
|
||||||
|
|
||||||
val sendType: MessageSendType = requireNotNull(intent.getParcelableExtra(MESSAGE_SEND_TYPE))
|
val sendType: MessageSendType = requireNotNull(intent.getParcelableExtra(MESSAGE_SEND_TYPE))
|
||||||
val initialMedia: List<Media> = intent.getParcelableArrayListExtra(MEDIA) ?: listOf()
|
val initialMedia: List<Media> = intent.getParcelableArrayListExtra(MEDIA) ?: listOf()
|
||||||
val message: CharSequence? = if (shareToTextStory) null else draftText
|
val message: CharSequence? = if (shareToTextStory) null else draftText
|
||||||
|
@ -89,6 +97,12 @@ class MediaSelectionActivity :
|
||||||
viewModel = ViewModelProvider(this, factory)[MediaSelectionViewModel::class.java]
|
viewModel = ViewModelProvider(this, factory)[MediaSelectionViewModel::class.java]
|
||||||
|
|
||||||
val textStoryToggle: ConstraintLayout = findViewById(R.id.switch_widget)
|
val textStoryToggle: ConstraintLayout = findViewById(R.id.switch_widget)
|
||||||
|
val cameraDisplay = CameraDisplay.getDisplay(textStoryToggle)
|
||||||
|
|
||||||
|
textStoryToggle.updateLayoutParams<FrameLayout.LayoutParams> {
|
||||||
|
bottomMargin = cameraDisplay.getToggleBottomMargin()
|
||||||
|
}
|
||||||
|
|
||||||
val cameraSelectedConstraintSet = ConstraintSet().apply {
|
val cameraSelectedConstraintSet = ConstraintSet().apply {
|
||||||
clone(textStoryToggle)
|
clone(textStoryToggle)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,20 @@ package org.thoughtcrime.securesms.mediasend.v2.gallery
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Transformations
|
import androidx.lifecycle.Transformations
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import org.signal.core.util.Stopwatch
|
import org.signal.core.util.Stopwatch
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.components.recyclerview.GridDividerDecoration
|
import org.thoughtcrime.securesms.components.recyclerview.GridDividerDecoration
|
||||||
|
import org.thoughtcrime.securesms.databinding.V2MediaGalleryFragmentBinding
|
||||||
import org.thoughtcrime.securesms.mediasend.Media
|
import org.thoughtcrime.securesms.mediasend.Media
|
||||||
import org.thoughtcrime.securesms.mediasend.MediaRepository
|
import org.thoughtcrime.securesms.mediasend.MediaRepository
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.MediaCountIndicatorButton
|
|
||||||
import org.thoughtcrime.securesms.util.Material3OnScrollHelper
|
import org.thoughtcrime.securesms.util.Material3OnScrollHelper
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil
|
import org.thoughtcrime.securesms.util.ViewUtil
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
|
@ -36,12 +36,6 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||||
|
|
||||||
private lateinit var callbacks: Callbacks
|
private lateinit var callbacks: Callbacks
|
||||||
|
|
||||||
private lateinit var toolbar: Toolbar
|
|
||||||
private lateinit var galleryRecycler: RecyclerView
|
|
||||||
private lateinit var countButton: MediaCountIndicatorButton
|
|
||||||
private lateinit var bottomBarGroup: View
|
|
||||||
private lateinit var selectedRecycler: RecyclerView
|
|
||||||
|
|
||||||
private var selectedMediaTouchHelper: ItemTouchHelper? = null
|
private var selectedMediaTouchHelper: ItemTouchHelper? = null
|
||||||
|
|
||||||
private val galleryAdapter = MappingAdapter()
|
private val galleryAdapter = MappingAdapter()
|
||||||
|
@ -57,29 +51,39 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
callbacks = requireListener()
|
callbacks = requireListener()
|
||||||
|
val binding = V2MediaGalleryFragmentBinding.bind(view)
|
||||||
|
|
||||||
toolbar = view.findViewById(R.id.media_gallery_toolbar)
|
binding.root.setPadding(
|
||||||
galleryRecycler = view.findViewById(R.id.media_gallery_grid)
|
0,
|
||||||
selectedRecycler = view.findViewById(R.id.media_gallery_selected)
|
0,
|
||||||
countButton = view.findViewById(R.id.media_gallery_count_button)
|
0,
|
||||||
bottomBarGroup = view.findViewById(R.id.media_gallery_bottom_bar_group)
|
ViewUtil.getNavigationBarHeight(view)
|
||||||
|
)
|
||||||
|
|
||||||
(galleryRecycler.layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
binding.mediaGalleryToolbar.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
topMargin = ViewUtil.getStatusBarHeight(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.mediaGalleryStatusBarBackground.updateLayoutParams {
|
||||||
|
height = ViewUtil.getStatusBarHeight(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
(binding.mediaGalleryGrid.layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||||
override fun getSpanSize(position: Int): Int {
|
override fun getSpanSize(position: Int): Int {
|
||||||
val isFolder: Boolean = (galleryRecycler.adapter as MappingAdapter).getModel(position).map { it is MediaGallerySelectableItem.FolderModel }.orElse(false)
|
val isFolder: Boolean = (binding.mediaGalleryGrid.adapter as MappingAdapter).getModel(position).map { it is MediaGallerySelectableItem.FolderModel }.orElse(false)
|
||||||
|
|
||||||
return if (isFolder) 2 else 1
|
return if (isFolder) 2 else 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toolbar.setNavigationOnClickListener {
|
binding.mediaGalleryToolbar.setNavigationOnClickListener {
|
||||||
onBack()
|
onBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
Material3OnScrollHelper(requireActivity(), toolbar).attach(galleryRecycler)
|
Material3OnScrollHelper(requireActivity(), listOf(binding.mediaGalleryToolbar, binding.mediaGalleryStatusBarBackground)).attach(binding.mediaGalleryGrid)
|
||||||
|
|
||||||
if (callbacks.isCameraEnabled()) {
|
if (callbacks.isCameraEnabled()) {
|
||||||
toolbar.setOnMenuItemClickListener { item ->
|
binding.mediaGalleryToolbar.setOnMenuItemClickListener { item ->
|
||||||
if (item.itemId == R.id.action_camera) {
|
if (item.itemId == R.id.action_camera) {
|
||||||
callbacks.onNavigateToCamera()
|
callbacks.onNavigateToCamera()
|
||||||
true
|
true
|
||||||
|
@ -88,18 +92,18 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toolbar.menu.findItem(R.id.action_camera).isVisible = false
|
binding.mediaGalleryToolbar.menu.findItem(R.id.action_camera).isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
countButton.setOnClickListener {
|
binding.mediaGalleryCountButton.setOnClickListener {
|
||||||
callbacks.onSubmit()
|
callbacks.onSubmit()
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaGallerySelectedItem.register(selectedAdapter) { media ->
|
MediaGallerySelectedItem.register(selectedAdapter) { media ->
|
||||||
callbacks.onSelectedMediaClicked(media)
|
callbacks.onSelectedMediaClicked(media)
|
||||||
}
|
}
|
||||||
selectedRecycler.adapter = selectedAdapter
|
binding.mediaGallerySelected.adapter = selectedAdapter
|
||||||
selectedMediaTouchHelper?.attachToRecyclerView(selectedRecycler)
|
selectedMediaTouchHelper?.attachToRecyclerView(binding.mediaGallerySelected)
|
||||||
|
|
||||||
MediaGallerySelectableItem.registerAdapter(
|
MediaGallerySelectableItem.registerAdapter(
|
||||||
mappingAdapter = galleryAdapter,
|
mappingAdapter = galleryAdapter,
|
||||||
|
@ -117,25 +121,25 @@ class MediaGalleryFragment : Fragment(R.layout.v2_media_gallery_fragment) {
|
||||||
callbacks.isMultiselectEnabled()
|
callbacks.isMultiselectEnabled()
|
||||||
)
|
)
|
||||||
|
|
||||||
galleryRecycler.adapter = galleryAdapter
|
binding.mediaGalleryGrid.adapter = galleryAdapter
|
||||||
galleryRecycler.addItemDecoration(GridDividerDecoration(4, ViewUtil.dpToPx(2)))
|
binding.mediaGalleryGrid.addItemDecoration(GridDividerDecoration(4, ViewUtil.dpToPx(2)))
|
||||||
|
|
||||||
viewStateLiveData.observe(viewLifecycleOwner) { state ->
|
viewStateLiveData.observe(viewLifecycleOwner) { state ->
|
||||||
bottomBarGroup.visible = state.selectedMedia.isNotEmpty()
|
binding.mediaGalleryBottomBarGroup.visible = state.selectedMedia.isNotEmpty()
|
||||||
countButton.setCount(state.selectedMedia.size)
|
binding.mediaGalleryCountButton.setCount(state.selectedMedia.size)
|
||||||
|
|
||||||
val stopwatch = Stopwatch("mediaSubmit")
|
val stopwatch = Stopwatch("mediaSubmit")
|
||||||
selectedAdapter.submitList(state.selectedMedia.map { MediaGallerySelectedItem.Model(it) }) {
|
selectedAdapter.submitList(state.selectedMedia.map { MediaGallerySelectedItem.Model(it) }) {
|
||||||
stopwatch.split("after-submit")
|
stopwatch.split("after-submit")
|
||||||
stopwatch.stop("MediaGalleryFragment")
|
stopwatch.stop("MediaGalleryFragment")
|
||||||
if (state.selectedMedia.isNotEmpty()) {
|
if (state.selectedMedia.isNotEmpty()) {
|
||||||
selectedRecycler.smoothScrollToPosition(state.selectedMedia.size - 1)
|
binding.mediaGallerySelected.smoothScrollToPosition(state.selectedMedia.size - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.state.observe(viewLifecycleOwner) { state ->
|
viewModel.state.observe(viewLifecycleOwner) { state ->
|
||||||
toolbar.title = state.bucketTitle ?: requireContext().getString(R.string.AttachmentKeyboard_gallery)
|
binding.mediaGalleryToolbar.title = state.bucketTitle ?: requireContext().getString(R.string.AttachmentKeyboard_gallery)
|
||||||
}
|
}
|
||||||
|
|
||||||
val galleryItemsWithSelection = LiveDataUtil.combineLatest(
|
val galleryItemsWithSelection = LiveDataUtil.combineLatest(
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.thoughtcrime.securesms.permissions.Permissions
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||||
import org.thoughtcrime.securesms.util.MediaUtil
|
import org.thoughtcrime.securesms.util.MediaUtil
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
import org.thoughtcrime.securesms.util.fragments.requireListener
|
import org.thoughtcrime.securesms.util.fragments.requireListener
|
||||||
import org.thoughtcrime.securesms.util.views.TouchInterceptingFrameLayout
|
import org.thoughtcrime.securesms.util.views.TouchInterceptingFrameLayout
|
||||||
|
@ -90,6 +91,13 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment) {
|
||||||
|
|
||||||
callback = requireListener()
|
callback = requireListener()
|
||||||
|
|
||||||
|
view.setPadding(
|
||||||
|
0,
|
||||||
|
ViewUtil.getStatusBarHeight(view),
|
||||||
|
0,
|
||||||
|
ViewUtil.getNavigationBarHeight(view)
|
||||||
|
)
|
||||||
|
|
||||||
drawToolButton = view.findViewById(R.id.draw_tool)
|
drawToolButton = view.findViewById(R.id.draw_tool)
|
||||||
cropAndRotateButton = view.findViewById(R.id.crop_and_rotate_tool)
|
cropAndRotateButton = view.findViewById(R.id.crop_and_rotate_tool)
|
||||||
qualityButton = view.findViewById(R.id.quality_selector)
|
qualityButton = view.findViewById(R.id.quality_selector)
|
||||||
|
|
|
@ -4,10 +4,11 @@ import android.content.pm.ActivityInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.constraintlayout.widget.ConstraintSet
|
||||||
import androidx.core.view.drawToBitmap
|
import androidx.core.view.drawToBitmap
|
||||||
import androidx.core.view.postDelayed
|
import androidx.core.view.postDelayed
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
@ -15,8 +16,10 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||||
|
import org.thoughtcrime.securesms.databinding.StoriesTextPostCreationFragmentBinding
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository
|
||||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel
|
import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel
|
||||||
|
import org.thoughtcrime.securesms.mediasend.CameraDisplay
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.HudCommand
|
import org.thoughtcrime.securesms.mediasend.v2.HudCommand
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionViewModel
|
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionViewModel
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.stories.StoriesMultiselectForwardActivity
|
import org.thoughtcrime.securesms.mediasend.v2.stories.StoriesMultiselectForwardActivity
|
||||||
|
@ -24,18 +27,14 @@ import org.thoughtcrime.securesms.mediasend.v2.text.send.TextStoryPostSendReposi
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.text.send.TextStoryPostSendResult
|
import org.thoughtcrime.securesms.mediasend.v2.text.send.TextStoryPostSendResult
|
||||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||||
import org.thoughtcrime.securesms.stories.Stories
|
import org.thoughtcrime.securesms.stories.Stories
|
||||||
import org.thoughtcrime.securesms.stories.StoryTextPostView
|
|
||||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil
|
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil
|
||||||
import org.thoughtcrime.securesms.util.visible
|
import org.thoughtcrime.securesms.util.visible
|
||||||
|
|
||||||
class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creation_fragment), TextStoryPostTextEntryFragment.Callback, SafetyNumberBottomSheet.Callbacks {
|
class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creation_fragment), TextStoryPostTextEntryFragment.Callback, SafetyNumberBottomSheet.Callbacks {
|
||||||
|
|
||||||
private lateinit var scene: ConstraintLayout
|
private var _binding: StoriesTextPostCreationFragmentBinding? = null
|
||||||
private lateinit var backgroundButton: AppCompatImageView
|
private val binding: StoriesTextPostCreationFragmentBinding get() = _binding!!
|
||||||
private lateinit var send: View
|
|
||||||
private lateinit var storyTextPostView: StoryTextPostView
|
|
||||||
private lateinit var sendInProgressCard: View
|
|
||||||
|
|
||||||
private val sharedViewModel: MediaSelectionViewModel by viewModels(
|
private val sharedViewModel: MediaSelectionViewModel by viewModels(
|
||||||
ownerProducer = {
|
ownerProducer = {
|
||||||
|
@ -66,16 +65,9 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
scene = view.findViewById(R.id.scene)
|
_binding = StoriesTextPostCreationFragmentBinding.bind(view)
|
||||||
backgroundButton = view.findViewById(R.id.background_selector)
|
|
||||||
send = view.findViewById(R.id.send)
|
|
||||||
storyTextPostView = view.findViewById(R.id.story_text_post)
|
|
||||||
sendInProgressCard = view.findViewById(R.id.send_in_progress_indicator)
|
|
||||||
|
|
||||||
val backgroundProtection: View = view.findViewById(R.id.background_protection)
|
binding.storyTextPost.showCloseButton()
|
||||||
val addLinkProtection: View = view.findViewById(R.id.add_link_protection)
|
|
||||||
|
|
||||||
storyTextPostView.showCloseButton()
|
|
||||||
|
|
||||||
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
||||||
lifecycleDisposable += sharedViewModel.hudCommands.subscribe {
|
lifecycleDisposable += sharedViewModel.hudCommands.subscribe {
|
||||||
|
@ -85,12 +77,12 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.typeface.observe(viewLifecycleOwner) { typeface ->
|
viewModel.typeface.observe(viewLifecycleOwner) { typeface ->
|
||||||
storyTextPostView.setTypeface(typeface)
|
binding.storyTextPost.setTypeface(typeface)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.state.observe(viewLifecycleOwner) { state ->
|
viewModel.state.observe(viewLifecycleOwner) { state ->
|
||||||
backgroundButton.background = state.backgroundColor.chatBubbleMask
|
binding.backgroundSelector.background = state.backgroundColor.chatBubbleMask
|
||||||
storyTextPostView.bindFromCreationState(state)
|
binding.storyTextPost.bindFromCreationState(state)
|
||||||
|
|
||||||
if (state.linkPreviewUri != null) {
|
if (state.linkPreviewUri != null) {
|
||||||
linkPreviewViewModel.onTextChanged(requireContext(), state.linkPreviewUri, 0, state.linkPreviewUri.lastIndex)
|
linkPreviewViewModel.onTextChanged(requireContext(), state.linkPreviewUri, 0, state.linkPreviewUri.lastIndex)
|
||||||
|
@ -99,32 +91,32 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
|
||||||
}
|
}
|
||||||
|
|
||||||
val canSend = state.body.isNotEmpty() || !state.linkPreviewUri.isNullOrEmpty()
|
val canSend = state.body.isNotEmpty() || !state.linkPreviewUri.isNullOrEmpty()
|
||||||
send.alpha = if (canSend) 1f else 0.5f
|
binding.send.alpha = if (canSend) 1f else 0.5f
|
||||||
send.isEnabled = canSend
|
binding.send.isEnabled = canSend
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveDataUtil.combineLatest(viewModel.state, linkPreviewViewModel.linkPreviewState) { viewState, linkState ->
|
LiveDataUtil.combineLatest(viewModel.state, linkPreviewViewModel.linkPreviewState) { viewState, linkState ->
|
||||||
Pair(viewState.body.isBlank(), linkState)
|
Pair(viewState.body.isBlank(), linkState)
|
||||||
}.observe(viewLifecycleOwner) { (useLargeThumb, linkState) ->
|
}.observe(viewLifecycleOwner) { (useLargeThumb, linkState) ->
|
||||||
storyTextPostView.bindLinkPreviewState(linkState, View.GONE, useLargeThumb)
|
binding.storyTextPost.bindLinkPreviewState(linkState, View.GONE, useLargeThumb)
|
||||||
storyTextPostView.postAdjustLinkPreviewTranslationY()
|
binding.storyTextPost.postAdjustLinkPreviewTranslationY()
|
||||||
}
|
}
|
||||||
|
|
||||||
storyTextPostView.setTextViewClickListener {
|
binding.storyTextPost.setTextViewClickListener {
|
||||||
storyTextPostView.hidePostContent()
|
binding.storyTextPost.hidePostContent()
|
||||||
storyTextPostView.isEnabled = false
|
binding.storyTextPost.isEnabled = false
|
||||||
TextStoryPostTextEntryFragment().show(childFragmentManager, null)
|
TextStoryPostTextEntryFragment().show(childFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundProtection.setOnClickListener {
|
binding.backgroundProtection.setOnClickListener {
|
||||||
viewModel.cycleBackgroundColor()
|
viewModel.cycleBackgroundColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
addLinkProtection.setOnClickListener {
|
binding.addLinkProtection.setOnClickListener {
|
||||||
TextStoryPostLinkEntryFragment().show(childFragmentManager, null)
|
TextStoryPostLinkEntryFragment().show(childFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
storyTextPostView.setLinkPreviewCloseListener {
|
binding.storyTextPost.setLinkPreviewCloseListener {
|
||||||
viewModel.setLinkPreview("")
|
viewModel.setLinkPreview("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,23 +124,23 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
|
||||||
if (it.isNotEmpty()) {
|
if (it.isNotEmpty()) {
|
||||||
performSend(it.toSet())
|
performSend(it.toSet())
|
||||||
} else {
|
} else {
|
||||||
send.isClickable = true
|
binding.send.isClickable = true
|
||||||
sendInProgressCard.visible = false
|
binding.sendInProgressIndicator.visible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send.setOnClickListener {
|
binding.send.setOnClickListener {
|
||||||
send.isClickable = false
|
binding.send.isClickable = false
|
||||||
sendInProgressCard.visible = true
|
binding.sendInProgressIndicator.visible = true
|
||||||
|
|
||||||
storyTextPostView.hideCloseButton()
|
binding.storyTextPost.hideCloseButton()
|
||||||
|
|
||||||
val contacts = (sharedViewModel.destination.getRecipientSearchKeyList() + sharedViewModel.destination.getRecipientSearchKey())
|
val contacts = (sharedViewModel.destination.getRecipientSearchKeyList() + sharedViewModel.destination.getRecipientSearchKey())
|
||||||
.filterIsInstance(ContactSearchKey::class.java)
|
.filterIsInstance(ContactSearchKey::class.java)
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
if (contacts.isEmpty()) {
|
if (contacts.isEmpty()) {
|
||||||
val bitmap = storyTextPostView.drawToBitmap()
|
val bitmap = binding.storyTextPost.drawToBitmap()
|
||||||
viewModel.compressToBlob(bitmap).observeOn(AndroidSchedulers.mainThread()).subscribe { uri ->
|
viewModel.compressToBlob(bitmap).observeOn(AndroidSchedulers.mainThread()).subscribe { uri ->
|
||||||
launcher.launch(
|
launcher.launch(
|
||||||
StoriesMultiselectForwardActivity.Args(
|
StoriesMultiselectForwardActivity.Args(
|
||||||
|
@ -166,18 +158,54 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
|
||||||
performSend(contacts)
|
performSend(contacts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initializeScenePositioning()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
storyTextPostView.showCloseButton()
|
binding.storyTextPost.showCloseButton()
|
||||||
requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
override fun onTextStoryPostTextEntryDismissed() {
|
override fun onTextStoryPostTextEntryDismissed() {
|
||||||
storyTextPostView.postDelayed(resources.getInteger(R.integer.text_entry_exit_duration).toLong()) {
|
binding.storyTextPost.postDelayed(resources.getInteger(R.integer.text_entry_exit_duration).toLong()) {
|
||||||
storyTextPostView.showPostContent()
|
binding.storyTextPost.showPostContent()
|
||||||
storyTextPostView.isEnabled = true
|
binding.storyTextPost.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeScenePositioning() {
|
||||||
|
val cameraDisplay = CameraDisplay.getDisplay(requireView())
|
||||||
|
|
||||||
|
if (!cameraDisplay.roundViewFinderCorners) {
|
||||||
|
binding.storyTextPostCard.radius = 0f
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.send.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
bottomMargin = cameraDisplay.getToggleBottomMargin()
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf(binding.backgroundProtection, binding.addLinkProtection).forEach {
|
||||||
|
it.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
bottomMargin += cameraDisplay.getCameraCaptureMarginBottom(resources)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraDisplay.getCameraViewportGravity() == CameraDisplay.CameraViewportGravity.CENTER) {
|
||||||
|
val constraintSet = ConstraintSet()
|
||||||
|
constraintSet.clone(binding.scene)
|
||||||
|
constraintSet.connect(R.id.story_text_post_card, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
|
||||||
|
constraintSet.applyTo(binding.scene)
|
||||||
|
} else {
|
||||||
|
binding.storyTextPostCard.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
bottomMargin = cameraDisplay.getCameraViewportMarginBottom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,8 +224,8 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
is TextStoryPostSendResult.UntrustedRecordsError -> {
|
is TextStoryPostSendResult.UntrustedRecordsError -> {
|
||||||
send.isClickable = true
|
binding.send.isClickable = true
|
||||||
sendInProgressCard.visible = false
|
binding.sendInProgressIndicator.visible = false
|
||||||
|
|
||||||
SafetyNumberBottomSheet
|
SafetyNumberBottomSheet
|
||||||
.forIdentityRecordsAndDestinations(result.untrustedRecords, contacts.toList())
|
.forIdentityRecordsAndDestinations(result.untrustedRecords, contacts.toList())
|
||||||
|
|
|
@ -224,6 +224,15 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||||
|
|
||||||
Mode mode = Mode.getByCode(requireArguments().getString(KEY_MODE));
|
Mode mode = Mode.getByCode(requireArguments().getString(KEY_MODE));
|
||||||
|
|
||||||
|
if (mode == Mode.AVATAR_CAPTURE || mode == Mode.AVATAR_EDIT) {
|
||||||
|
view.setPadding(
|
||||||
|
0,
|
||||||
|
ViewUtil.getStatusBarHeight(view),
|
||||||
|
0,
|
||||||
|
ViewUtil.getNavigationBarHeight(view)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
imageEditorHud = view.findViewById(R.id.scribble_hud);
|
imageEditorHud = view.findViewById(R.id.scribble_hud);
|
||||||
imageEditorView = view.findViewById(R.id.image_editor_view);
|
imageEditorView = view.findViewById(R.id.image_editor_view);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
@ -40,6 +41,11 @@ public final class WallpaperImageSelectionActivity extends AppCompatActivity
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
getWindow().addFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
);
|
||||||
|
|
||||||
setContentView(R.layout.wallpaper_image_selection_activity);
|
setContentView(R.layout.wallpaper_image_selection_activity);
|
||||||
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
tools:viewBindingIgnore="true"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.mediasend.CameraButtonView
|
|
||||||
android:id="@+id/camera_capture_button"
|
|
||||||
android:layout_width="96dp"
|
|
||||||
android:layout_height="96dp"
|
|
||||||
android:layout_marginEnd="18dp"
|
|
||||||
android:contentDescription="@string/CameraXFragment_capture_description"
|
|
||||||
app:imageCaptureSize="60dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:recordSize="42dp" />
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.mediasend.camerax.CameraXFlashToggleView
|
|
||||||
android:id="@+id/camera_flash_button"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:background="@drawable/circle_transparent_black_40"
|
|
||||||
android:padding="6dp"
|
|
||||||
android:src="@drawable/camerax_flash_toggle"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageButton
|
|
||||||
android:id="@+id/camera_flip_button"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="52dp"
|
|
||||||
android:layout_marginTop="36dp"
|
|
||||||
android:layout_marginEnd="40dp"
|
|
||||||
android:background="@drawable/media_selection_camera_switch_background"
|
|
||||||
android:contentDescription="@string/CameraXFragment_change_camera_description"
|
|
||||||
android:scaleType="centerInside"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@drawable/ic_switch_camera_28"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/camera_gallery_button_background"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="40dp"
|
|
||||||
android:layout_marginBottom="36dp"
|
|
||||||
android:background="@drawable/circle_tintable"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
|
||||||
|
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
|
||||||
android:id="@+id/camera_gallery_button"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="52dp"
|
|
||||||
android:contentDescription="@string/CameraXFragment_open_gallery_description"
|
|
||||||
android:padding="2dp"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Signal.Circle"
|
|
||||||
tools:src="@color/black" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.mediasend.v2.MediaCountIndicatorButton
|
|
||||||
android:id="@+id/camera_review_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="40dp"
|
|
||||||
android:layout_marginBottom="36dp"
|
|
||||||
android:background="@drawable/v2_media_count_indicator_background"
|
|
||||||
android:minHeight="44dp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/camera_capture_button"
|
|
||||||
tools:visibility="visible" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/camera_selfie_flash"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:alpha="0"
|
|
||||||
android:background="@color/white"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.mediasend.CameraButtonView
|
<org.thoughtcrime.securesms.mediasend.CameraButtonView
|
||||||
android:id="@+id/camera_capture_button"
|
android:id="@+id/camera_capture_button"
|
||||||
android:layout_width="124dp"
|
android:layout_width="@dimen/camera_capture_button_size"
|
||||||
android:layout_height="124dp"
|
android:layout_height="@dimen/camera_capture_button_size"
|
||||||
android:contentDescription="@string/CameraXFragment_capture_description"
|
android:contentDescription="@string/CameraXFragment_capture_description"
|
||||||
app:imageCaptureSize="76dp"
|
app:imageCaptureSize="@dimen/camera_capture_image_button_size"
|
||||||
app:layout_constraintBottom_toTopOf="@id/toggle_spacer"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:recordSize="54dp" />
|
app:recordSize="54dp" />
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
android:contentDescription="@string/CameraXFragment_change_camera_description"
|
android:contentDescription="@string/CameraXFragment_change_camera_description"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="centerInside"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/toggle_spacer"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:srcCompat="@drawable/ic_switch_camera_28"
|
app:srcCompat="@drawable/ic_switch_camera_28"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
android:layout_marginEnd="40dp"
|
android:layout_marginEnd="40dp"
|
||||||
android:layout_marginBottom="36dp"
|
android:layout_marginBottom="36dp"
|
||||||
android:background="@drawable/circle_tintable"
|
android:background="@drawable/circle_tintable"
|
||||||
app:layout_constraintBottom_toTopOf="@id/toggle_spacer"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
@ -91,14 +91,5 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/toggle_spacer"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardCornerRadius="18dp"
|
app:cardCornerRadius="18dp"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
<TextureView
|
<TextureView
|
||||||
android:id="@+id/camera_preview"
|
android:id="@+id/camera_preview"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
android:id="@+id/camera_controls_container"
|
android:id="@+id/camera_controls_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/camera_preview_parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="@id/camera_preview_parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:viewBindingIgnore="true"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
tools:viewBindingIgnore="true">
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/camerax_camera_parent"
|
android:id="@+id/camerax_camera_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
app:cardCornerRadius="18dp"
|
app:cardCornerRadius="18dp"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
<androidx.camera.view.PreviewView
|
<androidx.camera.view.PreviewView
|
||||||
android:id="@+id/camerax_camera"
|
android:id="@+id/camerax_camera"
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
android:id="@+id/camerax_controls_container"
|
android:id="@+id/camerax_controls_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/camerax_camera_parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="@id/camerax_camera_parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
tools:viewBindingIgnore="true"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
tools:viewBindingIgnore="true">
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/fragment_container"
|
android:id="@+id/fragment_container"
|
||||||
|
@ -15,8 +15,7 @@
|
||||||
android:id="@+id/switch_widget"
|
android:id="@+id/switch_widget"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_gravity="bottom|center_horizontal"
|
android:layout_gravity="bottom|center_horizontal">
|
||||||
android:layout_marginBottom="8dp">
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/selected_pill"
|
android:id="@+id/selected_pill"
|
||||||
|
@ -31,8 +30,9 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/camera_switch"
|
android:id="@+id/camera_switch"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="36sp"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:minHeight="36sp"
|
||||||
android:paddingHorizontal="18dp"
|
android:paddingHorizontal="18dp"
|
||||||
android:shadowColor="@color/black"
|
android:shadowColor="@color/black"
|
||||||
android:text="@string/MediaSelectionActivity__camera"
|
android:text="@string/MediaSelectionActivity__camera"
|
||||||
|
@ -47,8 +47,9 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_switch"
|
android:id="@+id/text_switch"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="36sp"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:minHeight="36sp"
|
||||||
android:paddingHorizontal="18dp"
|
android:paddingHorizontal="18dp"
|
||||||
android:shadowColor="@color/black"
|
android:shadowColor="@color/black"
|
||||||
android:shadowRadius="3"
|
android:shadowRadius="3"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
tools:viewBindingIgnore="true"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/scene"
|
android:id="@+id/scene"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -11,15 +10,12 @@
|
||||||
android:id="@+id/story_text_post_card"
|
android:id="@+id/story_text_post_card"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
app:cardCornerRadius="18dp"
|
app:cardCornerRadius="18dp"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/toggle_spacer"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintDimensionRatio="9:16"
|
app:layout_constraintDimensionRatio="9:16"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="0">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.stories.StoryTextPostView
|
<org.thoughtcrime.securesms.stories.StoryTextPostView
|
||||||
android:id="@+id/story_text_post"
|
android:id="@+id/story_text_post"
|
||||||
|
@ -36,7 +32,7 @@
|
||||||
android:layout_marginBottom="6dp"
|
android:layout_marginBottom="6dp"
|
||||||
android:padding="2dp"
|
android:padding="2dp"
|
||||||
android:src="@drawable/circle_tintable"
|
android:src="@drawable/circle_tintable"
|
||||||
app:layout_constraintBottom_toTopOf="@id/button_bar_barrier"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="@id/story_text_post_card"
|
app:layout_constraintStart_toStartOf="@id/story_text_post_card"
|
||||||
app:tint="@color/transparent_black_40" />
|
app:tint="@color/transparent_black_40" />
|
||||||
|
|
||||||
|
@ -60,7 +56,7 @@
|
||||||
android:layout_marginBottom="6dp"
|
android:layout_marginBottom="6dp"
|
||||||
android:padding="2dp"
|
android:padding="2dp"
|
||||||
android:src="@drawable/circle_tintable"
|
android:src="@drawable/circle_tintable"
|
||||||
app:layout_constraintBottom_toTopOf="@id/button_bar_barrier"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/background_protection"
|
app:layout_constraintStart_toEndOf="@id/background_protection"
|
||||||
app:tint="@color/transparent_black_40" />
|
app:tint="@color/transparent_black_40" />
|
||||||
|
|
||||||
|
@ -84,35 +80,12 @@
|
||||||
android:background="@color/signal_colorOnSecondaryContainer"
|
android:background="@color/signal_colorOnSecondaryContainer"
|
||||||
android:padding="4dp"
|
android:padding="4dp"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="centerInside"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/toggle_spacer"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/toggle_spacer"
|
|
||||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Signal.Circle"
|
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Signal.Circle"
|
||||||
app:srcCompat="@drawable/ic_arrow_end_24"
|
app:srcCompat="@drawable/ic_arrow_end_24"
|
||||||
app:tint="@color/signal_colorSecondaryContainer" />
|
app:tint="@color/signal_colorSecondaryContainer" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Barrier
|
|
||||||
android:id="@+id/button_bar_barrier"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:barrierDirection="top"
|
|
||||||
app:constraint_referenced_ids="barrier_helper,toggle_spacer" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/barrier_helper"
|
|
||||||
android:layout_width="1dp"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/story_text_post_card" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/toggle_spacer"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/send_in_progress_indicator"
|
android:id="@+id/send_in_progress_indicator"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
tools:viewBindingIgnore="true"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/media_gallery_status_bar_background"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/media_gallery_toolbar"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/media_gallery_toolbar"
|
android:id="@+id/media_gallery_toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
<dimen name="album_5_cell_size_small">69dp</dimen>
|
<dimen name="album_5_cell_size_small">69dp</dimen>
|
||||||
|
|
||||||
<dimen name="camera_contacts_horizontal_margin">16dp</dimen>
|
<dimen name="camera_contacts_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="camera_capture_button_size">124dp</dimen>
|
||||||
|
<dimen name="camera_capture_image_button_size">76dp</dimen>
|
||||||
|
|
||||||
<dimen name="message_corner_radius">18dp</dimen>
|
<dimen name="message_corner_radius">18dp</dimen>
|
||||||
<dimen name="message_corner_collapse_radius">4dp</dimen>
|
<dimen name="message_corner_collapse_radius">4dp</dimen>
|
||||||
|
|
Loading…
Add table
Reference in a new issue