deltachat/src/main/java/org/thoughtcrime/securesms/GroupCreateActivity.java

415 lines
13 KiB
Java

package org.thoughtcrime.securesms;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.loader.app.LoaderManager;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import org.thoughtcrime.securesms.components.AvatarSelector;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
import org.thoughtcrime.securesms.mms.AttachmentManager;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.scribbles.ScribbleActivity;
import org.thoughtcrime.securesms.util.SelectedContactsAdapter;
import org.thoughtcrime.securesms.util.SelectedContactsAdapter.ItemClickListener;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Objects;
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
implements ItemClickListener
{
public static final String EDIT_GROUP_CHAT_ID = "edit_group_chat_id";
public static final String CREATE_BROADCAST = "group_create_broadcast";
public static final String CLONE_CHAT_EXTRA = "clone_chat";
private static final int PICK_CONTACT = 1;
public static final int AVATAR_SIZE = 210;
private static final int REQUEST_CODE_AVATAR = 2759;
private DcContext dcContext;
private boolean verified;
private boolean broadcast;
private EditText groupName;
private ListView lv;
private ImageView avatar;
private Bitmap avatarBmp;
private int groupChatId;
private boolean isEdit;
private boolean avatarChanged;
private boolean imageLoaded;
private AttachmentManager attachmentManager;
@Override
protected void onCreate(Bundle state, boolean ready) {
dcContext = DcHelper.getContext(this);
setContentView(R.layout.group_create_activity);
verified = false;
broadcast = getIntent().getBooleanExtra(CREATE_BROADCAST, false);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
groupChatId = getIntent().getIntExtra(EDIT_GROUP_CHAT_ID, 0);
attachmentManager = new AttachmentManager(this, () -> {});
avatarChanged = false;
// groupChatId may be set during creation,
// so always check isEdit()
if(groupChatId !=0) {
isEdit = true;
DcChat dcChat = dcContext.getChat(groupChatId);
verified = dcChat.isProtected();
broadcast = dcChat.isBroadcast();
}
int chatId = getIntent().getIntExtra(CLONE_CHAT_EXTRA, 0);
if (chatId != 0) {
broadcast = dcContext.getChat(chatId).isBroadcast();
}
initializeResources();
}
@Override
public void onResume() {
super.onResume();
updateViewState();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@SuppressWarnings("ConstantConditions")
private void updateViewState() {
avatar.setEnabled(true);
groupName.setEnabled(true);
String title;
if(isEdit()) {
title = getString(R.string.global_menu_edit_desktop);
}
else if(broadcast) {
title = getString(R.string.new_broadcast_list);
}
else {
title = getString(R.string.menu_new_group);
}
getSupportActionBar().setTitle(title);
}
private void initializeResources() {
lv = ViewUtil.findById(this, R.id.selected_contacts_list);
avatar = ViewUtil.findById(this, R.id.avatar);
groupName = ViewUtil.findById(this, R.id.group_name);
TextView chatHints = ViewUtil.findById(this, R.id.chat_hints);
initializeAvatarView();
SelectedContactsAdapter adapter = new SelectedContactsAdapter(this, GlideApp.with(this), broadcast);
adapter.setItemClickListener(this);
lv.setAdapter(adapter);
int chatId = getIntent().getIntExtra(CLONE_CHAT_EXTRA, 0);
if (chatId != 0) {
DcChat dcChat = dcContext.getChat(chatId);
groupName.setText(dcChat.getName());
File file = new File(dcChat.getProfileImage());
if (file.exists()) {
setAvatarView(Uri.fromFile(file));
}
int[] contactIds = dcContext.getChatContacts(chatId);
ArrayList<Integer> preselectedContactIds = new ArrayList<>(contactIds.length);
for (int id : contactIds) {
preselectedContactIds.add(id);
}
adapter.changeData(preselectedContactIds);
} else {
adapter.changeData(null);
}
if (broadcast) {
avatar.setVisibility(View.GONE);
groupName.setHint(R.string.broadcast_list_name);
chatHints.setVisibility(isEdit()? View.GONE : View.VISIBLE);
} else {
chatHints.setVisibility(View.GONE);
}
if(isEdit()) {
groupName.setText(dcContext.getChat(groupChatId).getName());
lv.setVisibility(View.GONE);
}
}
private void initializeAvatarView() {
imageLoaded = false;
if (groupChatId != 0) {
String avatarPath = dcContext.getChat(groupChatId).getProfileImage();
File avatarFile = new File(avatarPath);
if (avatarFile.exists()) {
imageLoaded = true;
GlideApp.with(this)
.load(avatarFile)
.circleCrop()
.into(avatar);
}
}
if (!imageLoaded) {
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_group_white_24dp).asDrawable(this, ThemeUtil.getDummyContactColor(this)));
}
avatar.setOnClickListener(view ->
new AvatarSelector(this, LoaderManager.getInstance(this), new AvatarSelectedListener(), imageLoaded)
.show(this, avatar)
);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getMenuInflater();
menu.clear();
inflater.inflate(R.menu.group_create, menu);
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
super.onOptionsItemSelected(item);
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
finish();
return true;
} else if (itemId == R.id.menu_create_group) {
String groupName = getGroupName();
if (showGroupNameEmptyToast(groupName)) return true;
if (groupChatId != 0) {
updateGroup(groupName);
} else {
verified = !broadcast && allMembersVerified();
createGroup(groupName);
}
return true;
}
return false;
}
private boolean allMembersVerified() {
for (int id : getAdapter().getContacts()) {
DcContact contact = dcContext.getContact(id);
if (contact != null && !contact.isVerified()) {
return false;
}
}
return true;
}
@Override
public void onItemClick(int contactId) {
if (contactId == DcContact.DC_CONTACT_ID_ADD_MEMBER) {
Intent intent = new Intent(this, ContactMultiSelectionActivity.class);
intent.putExtra(ContactSelectionListFragment.SELECT_VERIFIED_EXTRA, verified);
ArrayList<Integer> preselectedContacts = new ArrayList<>(getAdapter().getContacts());
intent.putExtra(ContactSelectionListFragment.PRESELECTED_CONTACTS, preselectedContacts);
startActivityForResult(intent, PICK_CONTACT);
}
}
@Override
public void onItemDeleteClick(int contactId) {
getAdapter().remove(contactId);
}
private void createGroup(String groupName) {
if (broadcast) {
groupChatId = dcContext.createBroadcastList();
dcContext.setChatName(groupChatId, groupName);
} else {
groupChatId = dcContext.createGroupChat(verified, groupName);
}
for (int contactId : getAdapter().getContacts()) {
dcContext.addContactToChat(groupChatId, contactId);
}
if (avatarBmp!=null) {
AvatarHelper.setGroupAvatar(this, groupChatId, avatarBmp);
}
attachmentManager.cleanup();
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, groupChatId);
startActivity(intent);
finish();
}
private boolean showGroupNameEmptyToast(String groupName) {
if(groupName == null) {
Toast.makeText(this, getString(R.string.group_please_enter_group_name), Toast.LENGTH_LONG).show();
return true;
}
return false;
}
private void updateGroup(String groupName) {
if (groupChatId == 0) {
return;
}
dcContext.setChatName(groupChatId, groupName);
if (avatarChanged) AvatarHelper.setGroupAvatar(this, groupChatId, avatarBmp);
attachmentManager.cleanup();
Intent intent = new Intent();
intent.putExtra(GroupCreateActivity.EDIT_GROUP_CHAT_ID, groupChatId);
setResult(RESULT_OK, intent);
finish();
}
private SelectedContactsAdapter getAdapter() {
return (SelectedContactsAdapter)lv.getAdapter();
}
private @Nullable String getGroupName() {
String ret = groupName.getText() != null ? groupName.getText().toString() : null;
if(ret!=null) {
ret = ret.trim();
if(ret.isEmpty()) {
ret = null;
}
}
return ret;
}
@Override
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if (resultCode != Activity.RESULT_OK)
return;
switch (reqCode) {
case REQUEST_CODE_AVATAR:
Uri inputFile = (data != null ? data.getData() : null);
onFileSelected(inputFile);
break;
case PICK_CONTACT:
ArrayList<Integer> contactIds = new ArrayList<>();
for (Integer contactId : Objects.requireNonNull(data.getIntegerArrayListExtra(ContactMultiSelectionActivity.CONTACTS_EXTRA))) {
if(contactId != null) {
contactIds.add(contactId);
}
}
getAdapter().changeData(contactIds);
break;
case ScribbleActivity.SCRIBBLE_REQUEST_CODE:
setAvatarView(data.getData());
break;
}
}
private void setAvatarView(Uri output) {
GlideApp.with(this)
.asBitmap()
.load(output)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.centerCrop()
.override(AVATAR_SIZE, AVATAR_SIZE)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
setAvatar(output, resource);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {}
});
}
private <T> void setAvatar(T model, Bitmap bitmap) {
avatarBmp = bitmap;
avatarChanged = true;
imageLoaded = true;
GlideApp.with(this)
.load(model)
.circleCrop()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(avatar);
}
private boolean isEdit() {
return isEdit;
}
private class AvatarSelectedListener implements AvatarSelector.AttachmentClickedListener {
@Override
public void onClick(int type) {
switch (type) {
case AvatarSelector.ADD_GALLERY:
AttachmentManager.selectImage(GroupCreateActivity.this, REQUEST_CODE_AVATAR);
break;
case AvatarSelector.REMOVE_PHOTO:
avatarBmp = null;
imageLoaded = false;
avatarChanged = true;
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_group_white_24dp).asDrawable(GroupCreateActivity.this, ThemeUtil.getDummyContactColor(GroupCreateActivity.this)));
break;
case AvatarSelector.TAKE_PHOTO:
attachmentManager.capturePhoto(GroupCreateActivity.this, REQUEST_CODE_AVATAR);
break;
}
}
@Override
public void onQuickAttachment(Uri inputFile) {
onFileSelected(inputFile);
}
}
private void onFileSelected(Uri inputFile) {
if (inputFile == null) {
inputFile = attachmentManager.getImageCaptureUri();
}
AvatarHelper.cropAvatar(this, inputFile);
}
}