mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 16:49:40 +01:00
Add avatar picker and defaults.
This commit is contained in:
committed by
Greyson Parrelli
parent
0093e1d3eb
commit
ed23c3fe7c
@@ -16,6 +16,7 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
@@ -51,6 +52,7 @@ import org.whispersystems.libsignal.util.Pair;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
@@ -60,8 +62,8 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
|
||||
private static final String TAG = Log.tag(ImageEditorFragment.class);
|
||||
|
||||
private static final String KEY_IMAGE_URI = "image_uri";
|
||||
private static final String KEY_IS_AVATAR_MODE = "avatar_mode";
|
||||
private static final String KEY_IMAGE_URI = "image_uri";
|
||||
private static final String KEY_MODE = "mode";
|
||||
|
||||
private static final int SELECT_STICKER_REQUEST_CODE = 124;
|
||||
|
||||
@@ -104,15 +106,22 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
private ImageEditorHud imageEditorHud;
|
||||
private ImageEditorView imageEditorView;
|
||||
|
||||
public static ImageEditorFragment newInstanceForAvatar(@NonNull Uri imageUri) {
|
||||
public static ImageEditorFragment newInstanceForAvatarCapture(@NonNull Uri imageUri) {
|
||||
ImageEditorFragment fragment = newInstance(imageUri);
|
||||
fragment.requireArguments().putBoolean(KEY_IS_AVATAR_MODE, true);
|
||||
fragment.requireArguments().putString(KEY_MODE, Mode.AVATAR_CAPTURE.code);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static ImageEditorFragment newInstanceForAvatarEdit(@NonNull Uri imageUri) {
|
||||
ImageEditorFragment fragment = newInstance(imageUri);
|
||||
fragment.requireArguments().putString(KEY_MODE, Mode.AVATAR_EDIT.code);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static ImageEditorFragment newInstance(@NonNull Uri imageUri) {
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(KEY_IMAGE_URI, imageUri);
|
||||
args.putString(KEY_MODE, Mode.NORMAL.code);
|
||||
|
||||
ImageEditorFragment fragment = new ImageEditorFragment();
|
||||
fragment.setArguments(args);
|
||||
@@ -123,10 +132,16 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (!(getActivity() instanceof Controller)) {
|
||||
|
||||
Fragment parent = getParentFragment();
|
||||
if (parent instanceof Controller) {
|
||||
controller = (Controller) parent;
|
||||
} else if (getActivity() instanceof Controller) {
|
||||
controller = (Controller) getActivity();
|
||||
} else {
|
||||
throw new IllegalStateException("Parent activity must implement Controller interface.");
|
||||
}
|
||||
controller = (Controller) getActivity();
|
||||
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
imageUri = arguments.getParcelable(KEY_IMAGE_URI);
|
||||
@@ -152,7 +167,7 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
boolean isAvatarMode = requireArguments().getBoolean(KEY_IS_AVATAR_MODE, false);
|
||||
Mode mode = Mode.getByCode(requireArguments().getString(KEY_MODE));
|
||||
|
||||
imageEditorHud = view.findViewById(R.id.scribble_hud);
|
||||
imageEditorView = view.findViewById(R.id.image_editor_view);
|
||||
@@ -171,14 +186,28 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
}
|
||||
|
||||
if (editorModel == null) {
|
||||
editorModel = isAvatarMode ? EditorModel.createForCircleEditing() : EditorModel.create();
|
||||
switch (mode) {
|
||||
case AVATAR_EDIT:
|
||||
editorModel = EditorModel.createForAvatarEdit();
|
||||
break;
|
||||
case AVATAR_CAPTURE:
|
||||
editorModel = EditorModel.createForAvatarCapture();
|
||||
break;
|
||||
default:
|
||||
editorModel = EditorModel.create();
|
||||
break;
|
||||
}
|
||||
|
||||
EditorElement image = new EditorElement(new UriGlideRenderer(imageUri, true, imageMaxWidth, imageMaxHeight));
|
||||
image.getFlags().setSelectable(false).persist();
|
||||
editorModel.addElement(image);
|
||||
}
|
||||
|
||||
if (isAvatarMode) {
|
||||
if (mode == Mode.AVATAR_CAPTURE || mode == Mode.AVATAR_EDIT) {
|
||||
imageEditorHud.setUpForAvatarEditing();
|
||||
}
|
||||
|
||||
if (mode == Mode.AVATAR_CAPTURE) {
|
||||
imageEditorHud.enterMode(ImageEditorHud.Mode.CROP);
|
||||
}
|
||||
|
||||
@@ -460,24 +489,27 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
}
|
||||
|
||||
private void performSaveToDisk() {
|
||||
SimpleTask.run(() -> {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
Bitmap image = imageEditorView.getModel().render(requireContext());
|
||||
|
||||
image.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
|
||||
|
||||
return BlobProvider.getInstance()
|
||||
.forData(outputStream.toByteArray())
|
||||
.withMimeType(MediaUtil.IMAGE_JPEG)
|
||||
.createForSingleUseInMemory();
|
||||
|
||||
}, uri -> {
|
||||
SimpleTask.run(this::renderToSingleUseBlob, uri -> {
|
||||
SaveAttachmentTask saveTask = new SaveAttachmentTask(requireContext());
|
||||
SaveAttachmentTask.Attachment attachment = new SaveAttachmentTask.Attachment(uri, MediaUtil.IMAGE_JPEG, System.currentTimeMillis(), null);
|
||||
saveTask.executeOnExecutor(SignalExecutors.BOUNDED, attachment);
|
||||
});
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public @NonNull Uri renderToSingleUseBlob() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
Bitmap image = imageEditorView.getModel().render(requireContext());
|
||||
|
||||
image.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
|
||||
image.recycle();
|
||||
|
||||
return BlobProvider.getInstance()
|
||||
.forData(outputStream.toByteArray())
|
||||
.withMimeType(MediaUtil.IMAGE_JPEG)
|
||||
.createForSingleUseInMemory();
|
||||
}
|
||||
|
||||
private void refreshUniqueColors() {
|
||||
imageEditorHud.setColorPalette(imageEditorView.getModel().getUniqueColorsIgnoringAlpha());
|
||||
}
|
||||
@@ -587,4 +619,35 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
this.position.preConcat(imageProjectionMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
private enum Mode {
|
||||
|
||||
NORMAL("normal"),
|
||||
AVATAR_CAPTURE("avatar_capture"),
|
||||
AVATAR_EDIT("avatar_edit");
|
||||
|
||||
private final String code;
|
||||
|
||||
Mode(@NonNull String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
static Mode getByCode(@Nullable String code) {
|
||||
if (code == null) {
|
||||
return NORMAL;
|
||||
}
|
||||
|
||||
for (Mode mode : values()) {
|
||||
if (Objects.equals(code, mode.code)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
return NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user