2017-10-11 17:12:46 -07:00
|
|
|
/*
|
2014-02-27 22:44:02 -08:00
|
|
|
* Copyright (C) 2014 Open Whisper Systems
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2014-01-18 18:17:08 -08:00
|
|
|
package org.thoughtcrime.securesms;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.graphics.Bitmap;
|
2014-02-17 17:31:48 -08:00
|
|
|
import android.net.Uri;
|
2014-02-13 11:44:07 -08:00
|
|
|
import android.os.AsyncTask;
|
2014-01-18 18:17:08 -08:00
|
|
|
import android.os.Bundle;
|
2020-08-19 10:06:26 +10:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
2015-11-12 12:20:14 -08:00
|
|
|
import android.text.TextUtils;
|
2014-06-28 20:40:57 -07:00
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuInflater;
|
|
|
|
import android.view.MenuItem;
|
2014-01-18 18:17:08 -08:00
|
|
|
import android.view.View;
|
2014-02-12 12:05:18 -08:00
|
|
|
import android.widget.EditText;
|
2014-02-06 18:06:23 -08:00
|
|
|
import android.widget.ImageView;
|
2014-01-18 18:17:08 -08:00
|
|
|
import android.widget.ListView;
|
2014-02-13 11:44:07 -08:00
|
|
|
import android.widget.TextView;
|
2014-02-17 15:23:47 -08:00
|
|
|
import android.widget.Toast;
|
2014-01-18 18:17:08 -08:00
|
|
|
|
2016-10-28 12:30:50 -07:00
|
|
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
2015-07-24 17:07:33 -07:00
|
|
|
import com.bumptech.glide.request.target.SimpleTarget;
|
2017-10-11 17:12:46 -07:00
|
|
|
import com.bumptech.glide.request.transition.Transition;
|
2014-01-18 18:17:08 -08:00
|
|
|
|
2019-07-24 12:30:23 +10:00
|
|
|
import org.thoughtcrime.securesms.avatar.AvatarSelection;
|
2014-02-06 18:06:23 -08:00
|
|
|
import org.thoughtcrime.securesms.components.PushRecipientsPanel;
|
2015-11-05 10:41:43 -08:00
|
|
|
import org.thoughtcrime.securesms.components.PushRecipientsPanel.RecipientsPanelChangedListener;
|
2014-02-20 15:41:52 -08:00
|
|
|
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
|
2015-11-20 14:13:17 -08:00
|
|
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
2017-10-16 13:11:42 -07:00
|
|
|
import org.thoughtcrime.securesms.contacts.avatars.ResourceContactPhoto;
|
2019-07-24 12:30:23 +10:00
|
|
|
import org.thoughtcrime.securesms.conversation.ConversationActivity;
|
2017-07-26 09:59:15 -07:00
|
|
|
import org.thoughtcrime.securesms.database.Address;
|
2014-02-13 17:10:20 -08:00
|
|
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|
|
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
2015-11-05 10:41:43 -08:00
|
|
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
2017-08-22 10:44:04 -07:00
|
|
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
2014-02-13 17:10:20 -08:00
|
|
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
2015-11-05 10:41:43 -08:00
|
|
|
import org.thoughtcrime.securesms.groups.GroupManager;
|
|
|
|
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
|
2019-07-24 12:30:23 +10:00
|
|
|
import org.thoughtcrime.securesms.logging.Log;
|
2020-05-11 16:19:26 +10:00
|
|
|
import org.thoughtcrime.securesms.loki.fragments.ContactSelectionListFragment;
|
|
|
|
import org.thoughtcrime.securesms.loki.fragments.ContactSelectionListLoader.DisplayMode;
|
2017-10-11 17:12:46 -07:00
|
|
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
2014-01-18 18:17:08 -08:00
|
|
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
2015-11-05 10:41:43 -08:00
|
|
|
import org.thoughtcrime.securesms.util.BitmapUtil;
|
2014-01-18 18:17:08 -08:00
|
|
|
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
|
|
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
|
|
|
import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter;
|
2015-11-05 10:41:43 -08:00
|
|
|
import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter.OnRecipientDeletedListener;
|
2014-02-13 17:10:20 -08:00
|
|
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
2015-11-05 10:41:43 -08:00
|
|
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
2017-07-26 09:59:15 -07:00
|
|
|
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
2016-03-23 10:34:41 -07:00
|
|
|
import org.whispersystems.libsignal.util.guava.Optional;
|
|
|
|
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
2014-01-18 18:17:08 -08:00
|
|
|
|
2014-12-29 17:31:41 -08:00
|
|
|
import java.io.File;
|
2014-02-12 17:17:33 -08:00
|
|
|
import java.util.Collection;
|
2019-12-13 10:25:53 +11:00
|
|
|
import java.util.Collections;
|
2014-01-18 18:17:08 -08:00
|
|
|
import java.util.HashSet;
|
2015-11-12 12:20:14 -08:00
|
|
|
import java.util.LinkedList;
|
2014-01-18 18:17:08 -08:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
|
2019-07-24 12:30:23 +10:00
|
|
|
import network.loki.messenger.R;
|
|
|
|
|
2014-02-27 22:44:02 -08:00
|
|
|
/**
|
|
|
|
* Activity to create and update groups
|
|
|
|
*
|
|
|
|
* @author Jake McGinty
|
|
|
|
*/
|
2015-11-05 10:41:43 -08:00
|
|
|
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|
|
|
implements OnRecipientDeletedListener,
|
|
|
|
RecipientsPanelChangedListener
|
|
|
|
{
|
2014-01-18 18:17:08 -08:00
|
|
|
|
2014-02-18 16:28:54 -08:00
|
|
|
private final static String TAG = GroupCreateActivity.class.getSimpleName();
|
2014-02-06 18:06:23 -08:00
|
|
|
|
2017-07-26 09:59:15 -07:00
|
|
|
public static final String GROUP_ADDRESS_EXTRA = "group_recipient";
|
|
|
|
public static final String GROUP_THREAD_EXTRA = "group_thread";
|
2014-02-13 12:36:31 -08:00
|
|
|
|
2014-01-18 18:17:08 -08:00
|
|
|
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
|
|
|
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
|
|
|
|
|
|
|
private static final int PICK_CONTACT = 1;
|
2014-02-20 15:41:52 -08:00
|
|
|
public static final int AVATAR_SIZE = 210;
|
2014-02-06 18:06:23 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private EditText groupName;
|
|
|
|
private ListView lv;
|
|
|
|
private ImageView avatar;
|
|
|
|
private TextView creatingText;
|
|
|
|
private Bitmap avatarBmp;
|
2014-02-20 15:41:52 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
@NonNull private Optional<GroupData> groupToUpdate = Optional.absent();
|
2014-01-18 18:17:08 -08:00
|
|
|
|
|
|
|
@Override
|
2014-12-15 12:25:55 -08:00
|
|
|
protected void onPreCreate() {
|
2014-01-18 18:17:08 -08:00
|
|
|
dynamicTheme.onCreate(this);
|
|
|
|
dynamicLanguage.onCreate(this);
|
2014-12-15 12:25:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-02-01 19:22:48 -08:00
|
|
|
protected void onCreate(Bundle state, boolean ready) {
|
2014-01-18 18:17:08 -08:00
|
|
|
setContentView(R.layout.group_create_activity);
|
2015-11-05 10:41:43 -08:00
|
|
|
//noinspection ConstantConditions
|
2014-01-18 18:17:08 -08:00
|
|
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
|
|
initializeResources();
|
2015-11-05 10:41:43 -08:00
|
|
|
initializeExistingGroup();
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onResume() {
|
|
|
|
super.onResume();
|
|
|
|
dynamicTheme.onResume(this);
|
2014-02-17 17:31:48 -08:00
|
|
|
dynamicLanguage.onResume(this);
|
2015-11-05 10:41:43 -08:00
|
|
|
updateViewState();
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private boolean isSignalGroup() {
|
|
|
|
return TextSecurePreferences.isPushRegistered(this) && !getAdapter().hasNonPushMembers();
|
2014-02-13 12:15:26 -08:00
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private void disableSignalGroupViews(int reasonResId) {
|
2014-02-12 17:17:33 -08:00
|
|
|
View pushDisabled = findViewById(R.id.push_disabled);
|
|
|
|
pushDisabled.setVisibility(View.VISIBLE);
|
2014-02-20 15:41:52 -08:00
|
|
|
((TextView) findViewById(R.id.push_disabled_reason)).setText(reasonResId);
|
2014-02-12 17:17:33 -08:00
|
|
|
avatar.setEnabled(false);
|
|
|
|
groupName.setEnabled(false);
|
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private void enableSignalGroupViews() {
|
2014-02-12 17:17:33 -08:00
|
|
|
findViewById(R.id.push_disabled).setVisibility(View.GONE);
|
|
|
|
avatar.setEnabled(true);
|
|
|
|
groupName.setEnabled(true);
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
private void updateViewState() {
|
|
|
|
if (!TextSecurePreferences.isPushRegistered(this)) {
|
2015-11-27 12:57:01 +09:00
|
|
|
disableSignalGroupViews(R.string.GroupCreateActivity_youre_not_registered_for_signal);
|
2015-11-05 10:41:43 -08:00
|
|
|
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
|
|
|
|
} else if (getAdapter().hasNonPushMembers()) {
|
|
|
|
disableSignalGroupViews(R.string.GroupCreateActivity_contacts_dont_support_push);
|
|
|
|
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
|
2014-03-15 01:23:39 +01:00
|
|
|
} else {
|
2015-11-05 10:41:43 -08:00
|
|
|
enableSignalGroupViews();
|
2015-11-12 12:20:14 -08:00
|
|
|
getSupportActionBar().setTitle(groupToUpdate.isPresent()
|
2017-02-10 11:46:01 +01:00
|
|
|
? R.string.GroupCreateActivity_actionbar_edit_title
|
2015-11-12 12:20:14 -08:00
|
|
|
: R.string.GroupCreateActivity_actionbar_title);
|
2014-03-15 01:23:39 +01:00
|
|
|
}
|
2014-02-12 17:17:33 -08:00
|
|
|
}
|
|
|
|
|
2017-08-22 10:44:04 -07:00
|
|
|
private static boolean isActiveInDirectory(Recipient recipient) {
|
|
|
|
return recipient.resolve().getRegistered() == RecipientDatabase.RegisteredState.REGISTERED;
|
2014-02-12 17:17:33 -08:00
|
|
|
}
|
|
|
|
|
2015-11-12 12:20:14 -08:00
|
|
|
private void addSelectedContacts(@NonNull Recipient... recipients) {
|
2017-10-23 13:03:32 -07:00
|
|
|
new AddMembersTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, recipients);
|
2014-02-12 17:17:33 -08:00
|
|
|
}
|
|
|
|
|
2015-11-12 12:20:14 -08:00
|
|
|
private void addSelectedContacts(@NonNull Collection<Recipient> recipients) {
|
|
|
|
addSelectedContacts(recipients.toArray(new Recipient[recipients.size()]));
|
2014-02-12 17:17:33 -08:00
|
|
|
}
|
|
|
|
|
2014-01-18 18:17:08 -08:00
|
|
|
private void initializeResources() {
|
2015-11-05 10:41:43 -08:00
|
|
|
RecipientsEditor recipientsEditor = ViewUtil.findById(this, R.id.recipients_text);
|
|
|
|
PushRecipientsPanel recipientsPanel = ViewUtil.findById(this, R.id.recipients);
|
|
|
|
lv = ViewUtil.findById(this, R.id.selected_contacts_list);
|
|
|
|
avatar = ViewUtil.findById(this, R.id.avatar);
|
|
|
|
groupName = ViewUtil.findById(this, R.id.group_name);
|
|
|
|
creatingText = ViewUtil.findById(this, R.id.creating_group_text);
|
|
|
|
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(this);
|
|
|
|
adapter.setOnRecipientDeletedListener(this);
|
2014-02-12 17:17:33 -08:00
|
|
|
lv.setAdapter(adapter);
|
2016-09-17 17:09:24 +02:00
|
|
|
recipientsEditor.setHint(R.string.recipients_panel__add_members);
|
2015-11-05 10:41:43 -08:00
|
|
|
recipientsPanel.setPanelChangeListener(this);
|
|
|
|
findViewById(R.id.contacts_button).setOnClickListener(new AddRecipientButtonListener());
|
2017-10-16 13:11:42 -07:00
|
|
|
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_group_white_24dp).asDrawable(this, ContactColors.UNKNOWN_COLOR.toConversationColor(this)));
|
2019-03-18 16:09:57 -03:00
|
|
|
avatar.setOnClickListener(view -> AvatarSelection.startAvatarSelection(this, false, false));
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
2014-02-20 15:41:52 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private void initializeExistingGroup() {
|
2017-07-26 09:59:15 -07:00
|
|
|
final Address groupAddress = getIntent().getParcelableExtra(GROUP_ADDRESS_EXTRA);
|
|
|
|
|
2017-08-01 08:56:00 -07:00
|
|
|
if (groupAddress != null) {
|
2017-10-23 13:03:32 -07:00
|
|
|
new FillExistingGroupInfoAsyncTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, groupAddress.toGroupString());
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
2014-06-28 20:40:57 -07:00
|
|
|
MenuInflater inflater = this.getMenuInflater();
|
2014-01-18 18:17:08 -08:00
|
|
|
menu.clear();
|
|
|
|
|
2020-06-12 14:37:21 +10:00
|
|
|
inflater.inflate(R.menu.menu_apply, menu);
|
2014-01-18 18:17:08 -08:00
|
|
|
super.onPrepareOptionsMenu(menu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
super.onOptionsItemSelected(item);
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
case android.R.id.home:
|
2014-02-13 11:44:07 -08:00
|
|
|
finish();
|
|
|
|
return true;
|
2020-06-12 14:37:21 +10:00
|
|
|
case R.id.applyButton:
|
2015-11-05 10:41:43 -08:00
|
|
|
if (groupToUpdate.isPresent()) handleGroupUpdate();
|
|
|
|
else handleGroupCreate();
|
2014-02-17 15:23:47 -08:00
|
|
|
return true;
|
|
|
|
}
|
2014-02-13 11:44:07 -08:00
|
|
|
|
2014-02-17 15:23:47 -08:00
|
|
|
return false;
|
|
|
|
}
|
2014-02-13 11:44:07 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
@Override
|
|
|
|
public void onRecipientDeleted(Recipient recipient) {
|
|
|
|
getAdapter().remove(recipient);
|
|
|
|
updateViewState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-08-01 08:56:00 -07:00
|
|
|
public void onRecipientsPanelUpdate(List<Recipient> recipients) {
|
|
|
|
if (recipients != null && !recipients.isEmpty()) addSelectedContacts(recipients);
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
2014-02-17 15:23:47 -08:00
|
|
|
private void handleGroupCreate() {
|
2015-11-05 10:41:43 -08:00
|
|
|
if (getAdapter().getCount() < 1) {
|
2014-02-17 16:36:31 -08:00
|
|
|
Log.i(TAG, getString(R.string.GroupCreateActivity_contacts_no_members));
|
|
|
|
Toast.makeText(getApplicationContext(), R.string.GroupCreateActivity_contacts_no_members, Toast.LENGTH_SHORT).show();
|
2014-02-17 15:23:47 -08:00
|
|
|
return;
|
|
|
|
}
|
2015-11-05 10:41:43 -08:00
|
|
|
if (isSignalGroup()) {
|
2019-12-13 10:25:53 +11:00
|
|
|
Recipient local = Recipient.from(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)), false);
|
|
|
|
new CreateSignalGroupTask(this, avatarBmp, getGroupName(), getAdapter().getRecipients(), Collections.singleton(local)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
2014-02-17 15:23:47 -08:00
|
|
|
} else {
|
2018-01-24 19:17:44 -08:00
|
|
|
new CreateMmsGroupTask(this, getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
2014-02-17 16:36:31 -08:00
|
|
|
}
|
|
|
|
}
|
2014-01-18 18:17:08 -08:00
|
|
|
|
2014-02-21 17:51:25 -08:00
|
|
|
private void handleGroupUpdate() {
|
2018-01-24 19:17:44 -08:00
|
|
|
new UpdateSignalGroupTask(this, groupToUpdate.get().id, avatarBmp,
|
2019-12-13 10:25:53 +11:00
|
|
|
getGroupName(), getAdapter().getRecipients(), groupToUpdate.get().admins).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
2014-02-21 17:51:25 -08:00
|
|
|
}
|
|
|
|
|
2017-08-01 08:56:00 -07:00
|
|
|
private void handleOpenConversation(long threadId, Recipient recipient) {
|
2015-11-05 10:41:43 -08:00
|
|
|
Intent intent = new Intent(this, ConversationActivity.class);
|
|
|
|
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
|
|
|
|
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
|
2017-08-01 08:56:00 -07:00
|
|
|
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, recipient.getAddress());
|
2015-11-05 10:41:43 -08:00
|
|
|
startActivity(intent);
|
|
|
|
finish();
|
2014-02-17 16:36:31 -08:00
|
|
|
}
|
2014-02-17 15:23:47 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private SelectedRecipientsAdapter getAdapter() {
|
|
|
|
return (SelectedRecipientsAdapter)lv.getAdapter();
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private @Nullable String getGroupName() {
|
|
|
|
return groupName.getText() != null ? groupName.getText().toString() : null;
|
2014-02-06 18:06:23 -08:00
|
|
|
}
|
|
|
|
|
2014-01-18 18:17:08 -08:00
|
|
|
@Override
|
2015-07-24 17:07:33 -07:00
|
|
|
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
|
2014-01-18 18:17:08 -08:00
|
|
|
super.onActivityResult(reqCode, resultCode, data);
|
2014-12-29 17:31:41 -08:00
|
|
|
Uri outputFile = Uri.fromFile(new File(getCacheDir(), "cropped"));
|
2014-01-18 18:17:08 -08:00
|
|
|
|
|
|
|
if (data == null || resultCode != Activity.RESULT_OK)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (reqCode) {
|
|
|
|
case PICK_CONTACT:
|
2015-05-19 14:00:54 -07:00
|
|
|
List<String> selected = data.getStringArrayListExtra("contacts");
|
2017-07-26 09:59:15 -07:00
|
|
|
|
2015-05-19 14:00:54 -07:00
|
|
|
for (String contact : selected) {
|
2017-07-26 09:59:15 -07:00
|
|
|
Address address = Address.fromExternal(this, contact);
|
2017-08-21 18:32:38 -07:00
|
|
|
Recipient recipient = Recipient.from(this, address, false);
|
2017-07-26 09:59:15 -07:00
|
|
|
|
|
|
|
addSelectedContacts(recipient);
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|
|
|
|
break;
|
2014-03-03 04:30:50 +01:00
|
|
|
|
2019-03-18 16:09:57 -03:00
|
|
|
case AvatarSelection.REQUEST_CODE_AVATAR:
|
|
|
|
AvatarSelection.circularCropImage(this, data.getData(), outputFile, R.string.CropImageActivity_group_avatar);
|
2014-03-03 04:30:50 +01:00
|
|
|
break;
|
2019-03-18 16:09:57 -03:00
|
|
|
case AvatarSelection.REQUEST_CODE_CROP_IMAGE:
|
|
|
|
final Uri resultUri = AvatarSelection.getResultUri(data);
|
2017-10-11 17:12:46 -07:00
|
|
|
GlideApp.with(this)
|
|
|
|
.asBitmap()
|
2019-03-18 16:09:57 -03:00
|
|
|
.load(resultUri)
|
2017-10-11 17:12:46 -07:00
|
|
|
.skipMemoryCache(true)
|
|
|
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
|
|
.centerCrop()
|
|
|
|
.override(AVATAR_SIZE, AVATAR_SIZE)
|
|
|
|
.into(new SimpleTarget<Bitmap>() {
|
|
|
|
@Override
|
2018-01-24 19:17:44 -08:00
|
|
|
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
2019-03-18 16:09:57 -03:00
|
|
|
setAvatar(resultUri, resource);
|
2017-10-11 17:12:46 -07:00
|
|
|
}
|
|
|
|
});
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class AddRecipientButtonListener implements View.OnClickListener {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
Intent intent = new Intent(GroupCreateActivity.this, PushContactSelectionActivity.class);
|
2020-07-15 14:26:20 +10:00
|
|
|
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_CONTACTS);
|
2014-01-18 18:17:08 -08:00
|
|
|
startActivityForResult(intent, PICK_CONTACT);
|
|
|
|
}
|
|
|
|
}
|
2014-02-13 12:15:26 -08:00
|
|
|
|
2017-08-01 08:56:00 -07:00
|
|
|
private static class CreateMmsGroupTask extends AsyncTask<Void,Void,GroupActionResult> {
|
|
|
|
private final GroupCreateActivity activity;
|
|
|
|
private final Set<Recipient> members;
|
2014-02-13 12:15:26 -08:00
|
|
|
|
2018-01-24 19:17:44 -08:00
|
|
|
public CreateMmsGroupTask(GroupCreateActivity activity, Set<Recipient> members) {
|
2017-08-01 08:56:00 -07:00
|
|
|
this.activity = activity;
|
|
|
|
this.members = members;
|
2014-02-20 15:41:52 -08:00
|
|
|
}
|
2014-02-17 16:36:31 -08:00
|
|
|
|
|
|
|
@Override
|
2017-08-01 08:56:00 -07:00
|
|
|
protected GroupActionResult doInBackground(Void... avoid) {
|
|
|
|
List<Address> memberAddresses = new LinkedList<>();
|
|
|
|
|
|
|
|
for (Recipient recipient : members) {
|
|
|
|
memberAddresses.add(recipient.getAddress());
|
|
|
|
}
|
2019-12-13 10:25:53 +11:00
|
|
|
Address local = Address.fromSerialized(TextSecurePreferences.getLocalNumber(activity));
|
|
|
|
memberAddresses.add(local);
|
2017-08-01 08:56:00 -07:00
|
|
|
|
2019-12-13 10:25:53 +11:00
|
|
|
String groupId = DatabaseFactory.getGroupDatabase(activity).getOrCreateGroupForMembers(memberAddresses, true, Collections.singletonList(local));
|
2017-08-21 18:32:38 -07:00
|
|
|
Recipient groupRecipient = Recipient.from(activity, Address.fromSerialized(groupId), true);
|
2017-08-01 08:56:00 -07:00
|
|
|
long threadId = DatabaseFactory.getThreadDatabase(activity).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.DEFAULT);
|
|
|
|
|
|
|
|
return new GroupActionResult(groupRecipient, threadId);
|
2014-02-17 16:36:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-08-01 08:56:00 -07:00
|
|
|
protected void onPostExecute(GroupActionResult result) {
|
|
|
|
activity.handleOpenConversation(result.getThreadId(), result.getGroupRecipient());
|
2014-02-17 16:36:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onProgressUpdate(Void... values) {
|
|
|
|
super.onProgressUpdate(values);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private abstract static class SignalGroupTask extends AsyncTask<Void,Void,Optional<GroupActionResult>> {
|
2018-01-24 19:17:44 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
protected GroupCreateActivity activity;
|
|
|
|
protected Bitmap avatar;
|
|
|
|
protected Set<Recipient> members;
|
|
|
|
protected String name;
|
2019-12-13 10:25:53 +11:00
|
|
|
protected Set<Recipient> admins;
|
2015-11-05 10:41:43 -08:00
|
|
|
|
|
|
|
public SignalGroupTask(GroupCreateActivity activity,
|
|
|
|
Bitmap avatar,
|
|
|
|
String name,
|
2019-12-13 10:25:53 +11:00
|
|
|
Set<Recipient> members,
|
|
|
|
Set<Recipient> admins)
|
2015-11-05 10:41:43 -08:00
|
|
|
{
|
|
|
|
this.activity = activity;
|
|
|
|
this.avatar = avatar;
|
|
|
|
this.name = name;
|
|
|
|
this.members = members;
|
2019-12-13 10:25:53 +11:00
|
|
|
this.admins = admins;
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
2014-02-21 17:51:25 -08:00
|
|
|
@Override
|
2015-11-05 10:41:43 -08:00
|
|
|
protected void onPreExecute() {
|
|
|
|
activity.findViewById(R.id.group_details_layout).setVisibility(View.GONE);
|
|
|
|
activity.findViewById(R.id.creating_group_layout).setVisibility(View.VISIBLE);
|
2020-06-12 14:37:21 +10:00
|
|
|
activity.findViewById(R.id.applyButton).setVisibility(View.GONE);
|
2015-11-05 10:41:43 -08:00
|
|
|
final int titleResId = activity.groupToUpdate.isPresent()
|
|
|
|
? R.string.GroupCreateActivity_updating_group
|
|
|
|
: R.string.GroupCreateActivity_creating_group;
|
|
|
|
activity.creatingText.setText(activity.getString(titleResId, activity.getGroupName()));
|
2014-02-21 17:51:25 -08:00
|
|
|
}
|
2015-11-05 10:41:43 -08:00
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Optional<GroupActionResult> groupActionResultOptional) {
|
|
|
|
if (activity.isFinishing()) return;
|
|
|
|
activity.findViewById(R.id.group_details_layout).setVisibility(View.VISIBLE);
|
|
|
|
activity.findViewById(R.id.creating_group_layout).setVisibility(View.GONE);
|
2020-06-12 14:37:21 +10:00
|
|
|
activity.findViewById(R.id.applyButton).setVisibility(View.VISIBLE);
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class CreateSignalGroupTask extends SignalGroupTask {
|
2019-12-13 10:25:53 +11:00
|
|
|
public CreateSignalGroupTask(GroupCreateActivity activity, Bitmap avatar, String name, Set<Recipient> members, Set<Recipient> admins) {
|
|
|
|
super(activity, avatar, name, members, admins);
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
|
2019-12-13 10:25:53 +11:00
|
|
|
return Optional.of(GroupManager.createGroup(activity, members, avatar, name, false, admins));
|
2014-02-21 17:51:25 -08:00
|
|
|
}
|
2014-02-23 21:18:08 -08:00
|
|
|
|
|
|
|
@Override
|
2015-11-05 10:41:43 -08:00
|
|
|
protected void onPostExecute(Optional<GroupActionResult> result) {
|
|
|
|
if (result.isPresent() && result.get().getThreadId() > -1) {
|
|
|
|
if (!activity.isFinishing()) {
|
|
|
|
activity.handleOpenConversation(result.get().getThreadId(), result.get().getGroupRecipient());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
super.onPostExecute(result);
|
|
|
|
Toast.makeText(activity.getApplicationContext(),
|
|
|
|
R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show();
|
2014-02-23 21:18:08 -08:00
|
|
|
}
|
|
|
|
}
|
2014-02-21 17:51:25 -08:00
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private static class UpdateSignalGroupTask extends SignalGroupTask {
|
2017-08-01 08:56:00 -07:00
|
|
|
private String groupId;
|
2015-11-05 10:41:43 -08:00
|
|
|
|
2018-01-24 19:17:44 -08:00
|
|
|
public UpdateSignalGroupTask(GroupCreateActivity activity, String groupId,
|
2019-12-13 10:25:53 +11:00
|
|
|
Bitmap avatar, String name, Set<Recipient> members, Set<Recipient> admins)
|
2015-11-05 10:41:43 -08:00
|
|
|
{
|
2019-12-13 10:25:53 +11:00
|
|
|
super(activity, avatar, name, members, admins);
|
2015-11-05 10:41:43 -08:00
|
|
|
this.groupId = groupId;
|
|
|
|
}
|
2014-02-17 16:36:31 -08:00
|
|
|
|
|
|
|
@Override
|
2015-11-05 10:41:43 -08:00
|
|
|
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
|
2014-02-17 16:36:31 -08:00
|
|
|
try {
|
2019-12-13 10:25:53 +11:00
|
|
|
return Optional.of(GroupManager.updateGroup(activity, groupId, members, avatar, name, admins));
|
2014-02-17 16:36:31 -08:00
|
|
|
} catch (InvalidNumberException e) {
|
2015-11-05 10:41:43 -08:00
|
|
|
return Optional.absent();
|
2014-02-17 16:36:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-11-05 10:41:43 -08:00
|
|
|
protected void onPostExecute(Optional<GroupActionResult> result) {
|
|
|
|
if (result.isPresent() && result.get().getThreadId() > -1) {
|
|
|
|
if (!activity.isFinishing()) {
|
|
|
|
Intent intent = activity.getIntent();
|
|
|
|
intent.putExtra(GROUP_THREAD_EXTRA, result.get().getThreadId());
|
2017-08-01 08:56:00 -07:00
|
|
|
intent.putExtra(GROUP_ADDRESS_EXTRA, result.get().getGroupRecipient().getAddress());
|
2015-11-05 10:41:43 -08:00
|
|
|
activity.setResult(RESULT_OK, intent);
|
|
|
|
activity.finish();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
super.onPostExecute(result);
|
|
|
|
Toast.makeText(activity.getApplicationContext(),
|
|
|
|
R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show();
|
2014-02-17 16:36:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-02-20 15:41:52 -08:00
|
|
|
|
2015-11-12 12:20:14 -08:00
|
|
|
private static class AddMembersTask extends AsyncTask<Recipient,Void,List<AddMembersTask.Result>> {
|
|
|
|
static class Result {
|
|
|
|
Optional<Recipient> recipient;
|
|
|
|
boolean isPush;
|
|
|
|
String reason;
|
|
|
|
|
|
|
|
public Result(@Nullable Recipient recipient, boolean isPush, @Nullable String reason) {
|
|
|
|
this.recipient = Optional.fromNullable(recipient);
|
|
|
|
this.isPush = isPush;
|
|
|
|
this.reason = reason;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private GroupCreateActivity activity;
|
|
|
|
private boolean failIfNotPush;
|
|
|
|
|
|
|
|
public AddMembersTask(@NonNull GroupCreateActivity activity) {
|
|
|
|
this.activity = activity;
|
|
|
|
this.failIfNotPush = activity.groupToUpdate.isPresent();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected List<Result> doInBackground(Recipient... recipients) {
|
|
|
|
final List<Result> results = new LinkedList<>();
|
|
|
|
|
|
|
|
for (Recipient recipient : recipients) {
|
2017-08-22 10:44:04 -07:00
|
|
|
boolean isPush = isActiveInDirectory(recipient);
|
2015-11-12 12:20:14 -08:00
|
|
|
|
2019-12-13 16:04:24 +11:00
|
|
|
if (failIfNotPush && !isPush && !recipient.getAddress().isPhone()) {
|
2015-11-12 12:20:14 -08:00
|
|
|
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
|
2017-07-26 09:59:15 -07:00
|
|
|
recipient.toShortString())));
|
|
|
|
} else if (TextUtils.equals(TextSecurePreferences.getLocalNumber(activity), recipient.getAddress().serialize())) {
|
2015-11-12 12:20:14 -08:00
|
|
|
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_youre_already_in_the_group)));
|
|
|
|
} else {
|
|
|
|
results.add(new Result(recipient, isPush, null));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(List<Result> results) {
|
|
|
|
if (activity.isFinishing()) return;
|
|
|
|
|
|
|
|
for (Result result : results) {
|
|
|
|
if (result.recipient.isPresent()) {
|
|
|
|
activity.getAdapter().add(result.recipient.get(), result.isPush);
|
|
|
|
} else {
|
|
|
|
Toast.makeText(activity, result.reason, Toast.LENGTH_SHORT).show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
activity.updateViewState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-01 08:56:00 -07:00
|
|
|
private static class FillExistingGroupInfoAsyncTask extends ProgressDialogAsyncTask<String,Void,Optional<GroupData>> {
|
2015-11-05 10:41:43 -08:00
|
|
|
private GroupCreateActivity activity;
|
2014-02-20 15:41:52 -08:00
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
public FillExistingGroupInfoAsyncTask(GroupCreateActivity activity) {
|
|
|
|
super(activity,
|
2014-03-15 01:23:39 +01:00
|
|
|
R.string.GroupCreateActivity_loading_group_details,
|
|
|
|
R.string.please_wait);
|
2015-11-05 10:41:43 -08:00
|
|
|
this.activity = activity;
|
2014-02-20 15:41:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-08-01 08:56:00 -07:00
|
|
|
protected Optional<GroupData> doInBackground(String... groupIds) {
|
2017-08-07 16:47:38 -07:00
|
|
|
final GroupDatabase db = DatabaseFactory.getGroupDatabase(activity);
|
|
|
|
final List<Recipient> recipients = db.getGroupMembers(groupIds[0], false);
|
|
|
|
final Optional<GroupRecord> group = db.getGroup(groupIds[0]);
|
|
|
|
final Set<Recipient> existingContacts = new HashSet<>(recipients.size());
|
2017-08-01 08:56:00 -07:00
|
|
|
existingContacts.addAll(recipients);
|
2015-11-05 10:41:43 -08:00
|
|
|
|
2017-08-07 16:47:38 -07:00
|
|
|
if (group.isPresent()) {
|
2019-12-13 10:25:53 +11:00
|
|
|
List<Address> adminList = group.get().getAdmins();
|
|
|
|
final Set<Recipient> admins = new HashSet<>(adminList.size());
|
|
|
|
for (Address admin : adminList) {
|
|
|
|
admins.add(Recipient.from(getContext(), admin, false));
|
|
|
|
}
|
2015-11-05 10:41:43 -08:00
|
|
|
return Optional.of(new GroupData(groupIds[0],
|
|
|
|
existingContacts,
|
2017-08-07 16:47:38 -07:00
|
|
|
BitmapUtil.fromByteArray(group.get().getAvatar()),
|
|
|
|
group.get().getAvatar(),
|
2019-12-13 10:25:53 +11:00
|
|
|
group.get().getTitle(),
|
|
|
|
admins));
|
2015-11-05 10:41:43 -08:00
|
|
|
} else {
|
|
|
|
return Optional.absent();
|
2014-02-20 15:41:52 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-11-05 10:41:43 -08:00
|
|
|
protected void onPostExecute(Optional<GroupData> group) {
|
|
|
|
super.onPostExecute(group);
|
|
|
|
|
|
|
|
if (group.isPresent() && !activity.isFinishing()) {
|
|
|
|
activity.groupToUpdate = group;
|
|
|
|
|
|
|
|
activity.groupName.setText(group.get().name);
|
2015-11-23 17:26:09 +01:00
|
|
|
if (group.get().avatarBmp != null) {
|
|
|
|
activity.setAvatar(group.get().avatarBytes, group.get().avatarBmp);
|
|
|
|
}
|
2015-11-05 10:41:43 -08:00
|
|
|
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(activity, group.get().recipients);
|
|
|
|
adapter.setOnRecipientDeletedListener(activity);
|
|
|
|
activity.lv.setAdapter(adapter);
|
2015-11-12 12:20:14 -08:00
|
|
|
activity.updateViewState();
|
2015-11-05 10:41:43 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-02-20 15:41:52 -08:00
|
|
|
|
2015-11-23 17:26:09 +01:00
|
|
|
private <T> void setAvatar(T model, Bitmap bitmap) {
|
|
|
|
avatarBmp = bitmap;
|
2017-10-11 17:12:46 -07:00
|
|
|
GlideApp.with(this)
|
|
|
|
.load(model)
|
|
|
|
.circleCrop()
|
|
|
|
.skipMemoryCache(true)
|
|
|
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
|
|
.into(avatar);
|
2015-11-23 17:26:09 +01:00
|
|
|
}
|
|
|
|
|
2015-11-05 10:41:43 -08:00
|
|
|
private static class GroupData {
|
2017-08-01 08:56:00 -07:00
|
|
|
String id;
|
2015-11-05 10:41:43 -08:00
|
|
|
Set<Recipient> recipients;
|
2015-11-23 17:26:09 +01:00
|
|
|
Bitmap avatarBmp;
|
|
|
|
byte[] avatarBytes;
|
2015-11-05 10:41:43 -08:00
|
|
|
String name;
|
2019-12-13 10:25:53 +11:00
|
|
|
Set<Recipient> admins;
|
2015-11-05 10:41:43 -08:00
|
|
|
|
2019-12-13 10:25:53 +11:00
|
|
|
public GroupData(String id, Set<Recipient> recipients, Bitmap avatarBmp, byte[] avatarBytes, String name, Set<Recipient> admins) {
|
2015-11-23 17:26:09 +01:00
|
|
|
this.id = id;
|
|
|
|
this.recipients = recipients;
|
|
|
|
this.avatarBmp = avatarBmp;
|
|
|
|
this.avatarBytes = avatarBytes;
|
|
|
|
this.name = name;
|
2019-12-13 10:25:53 +11:00
|
|
|
this.admins = admins;
|
2014-02-20 15:41:52 -08:00
|
|
|
}
|
|
|
|
}
|
2014-01-18 18:17:08 -08:00
|
|
|
}
|