create groups and verified groups

create groups and verified groups
This commit is contained in:
B. Petersen
2018-09-17 17:22:31 +02:00
parent aa0c4b57ea
commit c5786488e8
8 changed files with 112 additions and 141 deletions
+2 -2
View File
@@ -434,9 +434,9 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_createGroupChat(JNIEnv *env, jo
}
JNIEXPORT jint Java_com_b44t_messenger_DcContext_isContactInChat(JNIEnv *env, jobject obj, jint chat_id, jint contact_id)
JNIEXPORT jboolean Java_com_b44t_messenger_DcContext_isContactInChat(JNIEnv *env, jobject obj, jint chat_id, jint contact_id)
{
return (jint)dc_is_contact_in_chat(get_dc_context(env, obj), chat_id, contact_id);
return (jboolean)dc_is_contact_in_chat(get_dc_context(env, obj), chat_id, contact_id);
}
+2
View File
@@ -316,6 +316,7 @@
<!-- GroupCreateActivity -->
<string name="GroupCreateActivity_actionbar_title">New group</string>
<string name="GroupCreateActivity_actionbar_verified_title">New verified group</string>
<string name="GroupCreateActivity_actionbar_edit_title">Edit group</string>
<string name="GroupCreateActivity_group_name_hint">Group name</string>
<string name="GroupCreateActivity_actionbar_mms_title">New MMS group</string>
@@ -1427,5 +1428,6 @@
<string name="contact_selection_list__type_email_above">Type email address above</string>
<string name="text_secure_normal__menu_new_chat">New chat</string>
<string name="help_url">https://delta.chat/en/help</string>
<string name="GroupCreateActivity_please_enter_group_name">Please enter a name for the group.</string>
</resources>
+1 -1
View File
@@ -119,7 +119,7 @@ public class DcContext {
public native int createChatByContactId(int contact_id);
public native int createChatByMsgId (int msg_id);
public native int createGroupChat (boolean verified, String name);
public native int isContactInChat (int chat_id, int contact_id);
public native boolean isContactInChat (int chat_id, int contact_id);
public native int addContactToChat (int chat_id, int contact_id);
public native int removeContactFromChat(int chat_id, int contact_id);
public native void setDraft (int chat_id, String draft/*null=delete*/);
@@ -38,6 +38,7 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.b44t.messenger.DcContext;
import com.pnikosis.materialishprogress.ProgressWheel;
import org.thoughtcrime.securesms.components.RecyclerViewFastScroller;
@@ -68,10 +69,11 @@ public class ContactSelectionListFragment extends Fragment
@SuppressWarnings("unused")
private static final String TAG = ContactSelectionListFragment.class.getSimpleName();
public static final String DISPLAY_MODE = "display_mode";
public static final String MULTI_SELECT = "multi_select";
public static final String REFRESHABLE = "refreshable";
public static final String RECENTS = "recents";
public static final String DISPLAY_MODE = "display_mode";
public static final String MULTI_SELECT = "multi_select";
public static final String REFRESHABLE = "refreshable";
public static final String RECENTS = "recents";
public static final String SELECT_VERIFIED_EXTRA = "select_verified";
private TextView emptyText;
private Set<String> selectedContacts;
@@ -156,6 +158,10 @@ public class ContactSelectionListFragment extends Fragment
return getActivity().getIntent().getBooleanExtra(MULTI_SELECT, false);
}
private boolean isSelectVerfied() {
return getActivity().getIntent().getBooleanExtra(SELECT_VERIFIED_EXTRA, false);
}
private void initializeCursor() {
ContactSelectionListAdapter adapter = new ContactSelectionListAdapter(getActivity(),
GlideApp.with(this),
@@ -212,7 +218,12 @@ public class ContactSelectionListFragment extends Fragment
@Override
public Loader<DcContactsLoader.Ret> onCreateLoader(int id, Bundle args) {
return new DcContactsLoader(getActivity(), 0, cursorFilter);
boolean addCreateGroupLinks = !isMulti();
int listflags = 0;
if(isSelectVerfied()) {
listflags = DcContext.DC_GCL_VERIFIED_ONLY;
}
return new DcContactsLoader(getActivity(), listflags, cursorFilter, addCreateGroupLinks);
}
@Override
@@ -25,8 +25,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -44,6 +42,8 @@ import com.soundcloud.android.crop.Crop;
import org.thoughtcrime.securesms.components.PushRecipientsPanel;
import org.thoughtcrime.securesms.components.PushRecipientsPanel.RecipientsPanelChangedListener;
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.contacts.ContactsCursorLoader.DisplayMode;
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
@@ -53,8 +53,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.groups.GroupManager;
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.BitmapUtil;
@@ -65,7 +63,6 @@ import org.thoughtcrime.securesms.util.SelectedRecipientsAdapter.OnRecipientDele
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.io.File;
import java.util.Collection;
@@ -88,6 +85,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
public static final String GROUP_ADDRESS_EXTRA = "group_recipient";
public static final String GROUP_THREAD_EXTRA = "group_thread";
public static final String GROUP_CREATE_VERIFIED_EXTRA = "group_create_verified";
private final DynamicTheme dynamicTheme = new DynamicTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
@@ -95,6 +93,9 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
private static final int PICK_CONTACT = 1;
public static final int AVATAR_SIZE = 210;
private ApplicationDcContext dcContext;
private boolean createVerified;
private EditText groupName;
private ListView lv;
private ImageView avatar;
@@ -111,8 +112,10 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
@Override
protected void onCreate(Bundle state, boolean ready) {
dcContext = DcHelper.getContext(this);
setContentView(R.layout.group_create_activity);
//noinspection ConstantConditions
createVerified = getIntent().getBooleanExtra(GROUP_CREATE_VERIFIED_EXTRA, false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
initializeResources();
initializeExistingGroup();
@@ -130,9 +133,18 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
private void updateViewState() {
avatar.setEnabled(true);
groupName.setEnabled(true);
getSupportActionBar().setTitle(groupToUpdate.isPresent()
? R.string.GroupCreateActivity_actionbar_edit_title
: R.string.GroupCreateActivity_actionbar_title);
String title;
if(groupToUpdate.isPresent()) {
title = getString(R.string.GroupCreateActivity_actionbar_edit_title);
}
else if(createVerified) {
title = getString(R.string.GroupCreateActivity_actionbar_verified_title);
}
else {
title = getString(R.string.GroupCreateActivity_actionbar_title);
}
getSupportActionBar().setTitle(title);
}
private void addSelectedContacts(@NonNull Recipient... recipients) {
@@ -206,25 +218,47 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
}
private void handleGroupCreate() {
if (getAdapter().getCount() < 1) {
Log.i(TAG, getString(R.string.GroupCreateActivity_contacts_no_members));
Toast.makeText(getApplicationContext(), R.string.GroupCreateActivity_contacts_no_members, Toast.LENGTH_SHORT).show();
String groupName = getGroupName();
if(groupName==null) {
Toast.makeText(this, getString(R.string.GroupCreateActivity_please_enter_group_name), Toast.LENGTH_LONG).show();
return;
}
new CreateSignalGroupTask(this, avatarBmp, getGroupName(), getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
int chatId = dcContext.createGroupChat(createVerified, groupName);
Set<Recipient> members = getAdapter().getRecipients();
for(Recipient member : members) {
Address address = member.getAddress();
if(address.isDcContact()) {
int contactId = address.getDcContactId();
dcContext.addContactToChat(chatId, contactId);
}
}
// TODO: handle avatarBmp
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, (long)chatId);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, Address.fromChat(dcContext.getChat((int)chatId)));
startActivity(intent);
finish();
}
private void handleGroupUpdate() {
new UpdateSignalGroupTask(this, groupToUpdate.get().id, avatarBmp,
getGroupName(), getAdapter().getRecipients()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
int chatId = 0;// TODO: get correct id from groupToUpdate.get().id; or so
String groupName = getGroupName();
if(groupName!=null) {
dcContext.setChatName(chatId, groupName);
}
// TODO: compare dcContext.getChatContacts(chatId); against getAdapter().getRecipients();
// and add/remove contacts
// TODO: handle avatarBmp
private void handleOpenConversation(long threadId, Recipient recipient) {
Intent intent = new Intent(this, ConversationActivity.class);
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, recipient.getAddress());
startActivity(intent);
finish();
}
@@ -233,7 +267,14 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
}
private @Nullable String getGroupName() {
return groupName.getText() != null ? groupName.getText().toString() : null;
String ret = groupName.getText() != null ? groupName.getText().toString() : null;
if(ret!=null) {
ret = ret.trim();
if(ret.isEmpty()) {
ret = null;
}
}
return ret;
}
@Override
@@ -280,6 +321,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
@Override
public void onClick(View v) {
Intent intent = new Intent(GroupCreateActivity.this, PushContactSelectionActivity.class);
intent.putExtra(ContactSelectionListFragment.SELECT_VERIFIED_EXTRA, createVerified);
if (groupToUpdate.isPresent()) {
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_PUSH);
} else {
@@ -289,105 +331,6 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
}
}
private abstract static class SignalGroupTask extends AsyncTask<Void,Void,Optional<GroupActionResult>> {
protected GroupCreateActivity activity;
protected Bitmap avatar;
protected Set<Recipient> members;
protected String name;
public SignalGroupTask(GroupCreateActivity activity,
Bitmap avatar,
String name,
Set<Recipient> members)
{
this.activity = activity;
this.avatar = avatar;
this.name = name;
this.members = members;
}
@Override
protected void onPreExecute() {
activity.findViewById(R.id.group_details_layout).setVisibility(View.GONE);
activity.findViewById(R.id.creating_group_layout).setVisibility(View.VISIBLE);
activity.findViewById(R.id.menu_create_group).setVisibility(View.GONE);
final int titleResId = activity.groupToUpdate.isPresent()
? R.string.GroupCreateActivity_updating_group
: R.string.GroupCreateActivity_creating_group;
activity.creatingText.setText(activity.getString(titleResId, activity.getGroupName()));
}
@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);
activity.findViewById(R.id.menu_create_group).setVisibility(View.VISIBLE);
}
}
private static class CreateSignalGroupTask extends SignalGroupTask {
public CreateSignalGroupTask(GroupCreateActivity activity, Bitmap avatar, String name, Set<Recipient> members) {
super(activity, avatar, name, members);
}
@Override
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
return Optional.of(GroupManager.createGroup(activity, members, avatar, name, false));
}
@Override
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();
}
}
}
private static class UpdateSignalGroupTask extends SignalGroupTask {
private String groupId;
public UpdateSignalGroupTask(GroupCreateActivity activity, String groupId,
Bitmap avatar, String name, Set<Recipient> members)
{
super(activity, avatar, name, members);
this.groupId = groupId;
}
@Override
protected Optional<GroupActionResult> doInBackground(Void... aVoid) {
try {
return Optional.of(GroupManager.updateGroup(activity, groupId, members, avatar, name));
} catch (InvalidNumberException e) {
return Optional.absent();
}
}
@Override
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());
intent.putExtra(GROUP_ADDRESS_EXTRA, result.get().getGroupRecipient().getAddress());
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();
}
}
}
private static class AddMembersTask extends AsyncTask<Recipient,Void,List<AddMembersTask.Result>> {
static class Result {
Optional<Recipient> recipient;
@@ -418,12 +361,17 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
@Override
protected void onPostExecute(List<Result> results) {
if (activity.isFinishing()) return;
ApplicationDcContext dcContext = DcHelper.getContext(activity);
for (Result result : results) {
if (result.recipient.isPresent()) {
activity.getAdapter().add(result.recipient.get(), true);
} else {
Toast.makeText(activity, result.reason, Toast.LENGTH_SHORT).show();
Recipient recipient = result.recipient.get();
Address address = recipient.getAddress();
if(address.isDcContact()) {
activity.getAdapter().add(recipient, true);
}
else if(dcContext.mayBeValidAddr(address.toString())) {
int contactId = DcHelper.getContext(activity).createContact(null, address.toString());
activity.getAdapter().add(dcContext.getRecipient(dcContext.getContact(contactId)), true);
}
}
activity.updateViewState();
@@ -59,6 +59,7 @@ public class NewConversationActivity extends ContactSelectionActivity {
final DcContext dcContext = DcHelper.getContext(this);
if(specialId==DcContact.DC_CONTACT_ID_NEW_GROUP || specialId==DcContact.DC_CONTACT_ID_NEW_VERIFIED_GROUP) {
Intent intent = new Intent(this, GroupCreateActivity.class);
intent.putExtra(GroupCreateActivity.GROUP_CREATE_VERIFIED_EXTRA, specialId==DcContact.DC_CONTACT_ID_NEW_VERIFIED_GROUP);
startActivity(intent);
finish();
}
@@ -15,13 +15,15 @@ public class DcContactsLoader extends AsyncLoader<DcContactsLoader.Ret> {
private static final String TAG = DcContactsLoader.class.getName();
private final int listflags;
private final String query;
private final int listflags;
private final String query;
private final boolean addCreateGroupLinks;
public DcContactsLoader(Context context, int listflags, String query) {
public DcContactsLoader(Context context, int listflags, String query, boolean addCreateGroupLinks) {
super(context);
this.listflags = listflags;
this.query = (query==null||query.isEmpty())? null : query;
this.listflags = listflags;
this.query = (query==null||query.isEmpty())? null : query;
this.addCreateGroupLinks = addCreateGroupLinks;
}
@Override
@@ -31,12 +33,12 @@ public class DcContactsLoader extends AsyncLoader<DcContactsLoader.Ret> {
int[] contact_ids = dcContext.getContacts(listflags, query);
if(query!=null) {
// show the "new contact" link also for partly typed e-mail addresses, so that the user knows he can continue
if( dcContext.lookupContactIdByAddr(query)==0) {
if (dcContext.lookupContactIdByAddr(query)==0 && (listflags&DcContext.DC_GCL_VERIFIED_ONLY)==0) {
contact_ids = ArrayUtils.appendInt(contact_ids, DcContact.DC_CONTACT_ID_NEW_CONTACT);
}
return new DcContactsLoader.Ret(contact_ids, query);
}
else {
else if(addCreateGroupLinks) {
// add "new group" and "new verified group" links
final int additional_items = 2; // if someone knows an easier way to prepend sth. to int[] please pr :)
int all_ids[] = new int[contact_ids.length+additional_items];
@@ -47,6 +49,9 @@ public class DcContactsLoader extends AsyncLoader<DcContactsLoader.Ret> {
}
return new DcContactsLoader.Ret(all_ids, query);
}
else {
return new DcContactsLoader.Ret(contact_ids, query);
}
}
public class Ret {
@@ -99,7 +99,11 @@ public class SelectedRecipientsAdapter extends BaseAdapter {
final RecipientWrapper rw = (RecipientWrapper)getItem(position);
final Recipient p = rw.getRecipient();
final boolean modifiable = rw.isModifiable();
final DcContact dcContact = dcContext.getContact(p.getAddress().getDcContactId());
DcContact dcContact = new DcContact(0);
if(p.getAddress().isDcContact()) {
dcContact = dcContext.getContact(p.getAddress().getDcContactId());
}
TextView name = (TextView) v.findViewById(R.id.name);
TextView phone = (TextView) v.findViewById(R.id.phone);