mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
updates to conversation menu, and updating of group info
// FREEBIE
This commit is contained in:
parent
7667264789
commit
7beab36c6a
@ -25,7 +25,7 @@
|
||||
android:layout_height="70dp"
|
||||
position="bottom_right"
|
||||
android:layout_marginRight="10dp"
|
||||
android:src="@drawable/icon"
|
||||
android:src="@drawable/ic_group_photo"
|
||||
android:contentDescription="@string/GroupCreateActivity_avatar_content_description" />
|
||||
|
||||
<EditText android:id="@+id/group_name"
|
||||
|
12
res/menu/conversation_push_group_options.xml
Normal file
12
res/menu/conversation_push_group_options.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/menu_edit_group"
|
||||
android:title="@string/conversation__menu_update_group"
|
||||
android:showAsAction="collapseActionView" />
|
||||
|
||||
<item android:id="@+id/menu_leave"
|
||||
android:title="@string/conversation__menu_leave_group"
|
||||
android:showAsAction="collapseActionView"/>
|
||||
|
||||
</menu>
|
@ -7,10 +7,6 @@
|
||||
<menu>
|
||||
<item android:title="@string/conversation_secure_verified__menu_verify_recipient"
|
||||
android:id="@+id/menu_verify_recipient"/>
|
||||
|
||||
<item android:title="@string/conversation_secure_verified__menu_abort_secure_session"
|
||||
android:id="@+id/menu_abort_session"/>
|
||||
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
@ -8,10 +8,6 @@
|
||||
<item android:title="@string/conversation_secure_verified__menu_no_identity"
|
||||
android:enabled="false"
|
||||
android:id="@+id/menu_no_identity" />
|
||||
|
||||
<item android:title="@string/conversation_secure_verified__menu_abort_secure_session"
|
||||
android:id="@+id/menu_abort_session"/>
|
||||
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
13
res/menu/conversation_secure_sms.xml
Normal file
13
res/menu/conversation_secure_sms.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:title="@string/conversation_secure_verified__menu_security"
|
||||
android:id="@+id/menu_security"
|
||||
android:icon="?menu_lock_icon"
|
||||
android:showAsAction="ifRoom">
|
||||
<menu>
|
||||
<item android:title="@string/conversation_secure_verified__menu_abort_secure_session"
|
||||
android:id="@+id/menu_abort_session"/>
|
||||
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
@ -124,10 +124,12 @@
|
||||
|
||||
<!-- GroupCreateActivity -->
|
||||
<string name="GroupCreateActivity_actionbar_title">New Group</string>
|
||||
<string name="GroupCreateActivity_actionbar_update_title">Update Group</string>
|
||||
<string name="GroupCreateActivity_group_name_hint">Group Name</string>
|
||||
<string name="GroupCreateActivity_actionbar_mms_title">New MMS Group</string>
|
||||
<string name="GroupCreateActivity_contacts_dont_support_push">You have selected a contact that doesn\'t support TextSecure groups, so this group will be MMS.</string>
|
||||
<string name="GroupCreateActivity_you_dont_support_push">You\'re not registered for using the data channel, so TextSecure groups are disabled.</string>
|
||||
<string name="GroupCreateActivity_you_dont_own_this_group">You\'re not the owner of this group, so you cannot edit the title or picture.</string>
|
||||
<string name="GroupCreateActivity_contacts_mms_exception">An unexpected error happened that has made group creation fail.</string>
|
||||
<string name="GroupCreateActivity_contacts_no_members">You need at least one person in your group!</string>
|
||||
<string name="GroupCreateActivity_contacts_invalid_number">One of the members of your group has a number that can\'t be read correctly. Please fix or remove that contact and try again.</string>
|
||||
@ -563,7 +565,8 @@
|
||||
|
||||
<!-- recipients_panel -->
|
||||
<string name="recipients_panel__to">To</string>
|
||||
|
||||
<string name="recipients_panel__add_member">Add member</string>
|
||||
|
||||
<!-- review_identities -->
|
||||
<string name="review_identities__you_don_t_currently_have_any_identity_keys_in_your_trust_database">You don\'t currently have any identity keys in your trust database.</string>
|
||||
|
||||
@ -725,6 +728,8 @@
|
||||
|
||||
<!-- conversation -->
|
||||
<string name="conversation__menu_add_attachment">Add attachment</string>
|
||||
<string name="conversation__menu_update_group">Update Group</string>
|
||||
<string name="conversation__menu_leave_group">Leave Group</string>
|
||||
<string name="conversation__menu_add_contact_info">Add contact info</string>
|
||||
<string name="conversation__menu_delete_thread">Delete thread</string>
|
||||
|
||||
|
@ -75,6 +75,7 @@ import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.protocol.Tag;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
@ -132,6 +133,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
private static final int PICK_VIDEO = 3;
|
||||
private static final int PICK_AUDIO = 4;
|
||||
private static final int PICK_CONTACT_INFO = 5;
|
||||
private static final int GROUP_EDIT = 6;
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
private RecipientsPanel recipientsPanel;
|
||||
@ -234,6 +236,10 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
case PICK_CONTACT_INFO:
|
||||
addContactInfo(data.getData());
|
||||
break;
|
||||
case GROUP_EDIT:
|
||||
this.recipients = RecipientFactory.getRecipientsForIds(this, String.valueOf(getRecipients().getPrimaryRecipient().getRecipientId()), false);
|
||||
initializeTitleBar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,13 +248,18 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
MenuInflater inflater = this.getSupportMenuInflater();
|
||||
menu.clear();
|
||||
|
||||
boolean pushRegistered = TextSecurePreferences.isPushRegistered(this);
|
||||
|
||||
if (isSingleConversation() && isEncryptedConversation) {
|
||||
if (isAuthenticatedConversation) {
|
||||
inflater.inflate(R.menu.conversation_secure_identity, menu);
|
||||
} else {
|
||||
inflater.inflate(R.menu.conversation_secure_no_identity, menu);
|
||||
}
|
||||
} else if (isSingleConversation()) {
|
||||
if (!pushRegistered) {
|
||||
inflater.inflate(R.menu.conversation_secure_sms, menu);
|
||||
}
|
||||
} else if (isSingleConversation() && !pushRegistered) {
|
||||
inflater.inflate(R.menu.conversation_insecure, menu);
|
||||
}
|
||||
|
||||
@ -264,6 +275,8 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
} else {
|
||||
menu.findItem(R.id.menu_distribution_conversation).setChecked(true);
|
||||
}
|
||||
} else {
|
||||
inflater.inflate(R.menu.conversation_push_group_options, menu);
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,12 +299,25 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
|
||||
case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
|
||||
case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
|
||||
case R.id.menu_edit_group: handleEditPushGroup(); return true;
|
||||
case R.id.menu_leave: handleLeavePushGroup(); return true;
|
||||
case android.R.id.home: handleReturnToConversationList(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleLeavePushGroup() {
|
||||
Toast.makeText(getApplicationContext(), "not yet implemented", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void handleEditPushGroup() {
|
||||
Intent intent = new Intent(ConversationActivity.this, GroupCreateActivity.class);
|
||||
intent.putExtra(GroupCreateActivity.MASTER_SECRET_EXTRA, masterSecret);
|
||||
intent.putExtra(GroupCreateActivity.GROUP_RECIPIENT_EXTRA, recipients);
|
||||
startActivityForResult(intent, GROUP_EDIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
if (isEncryptedConversation) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
@ -11,6 +12,7 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
@ -28,12 +30,14 @@ import com.google.protobuf.ByteString;
|
||||
|
||||
import org.thoughtcrime.securesms.components.PushRecipientsPanel;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
import org.thoughtcrime.securesms.contacts.RecipientsEditor;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientProvider;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
@ -49,6 +53,7 @@ import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.directory.Directory;
|
||||
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
||||
import org.whispersystems.textsecure.util.InvalidNumberException;
|
||||
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@ -70,8 +75,9 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
|
||||
private final static String TAG = GroupCreateActivity.class.getSimpleName();
|
||||
|
||||
|
||||
public static final String MASTER_SECRET_EXTRA = "master_secret";
|
||||
public static final String GROUP_RECIPIENT_EXTRA = "group_recipient";
|
||||
public static final String GROUP_THREAD_EXTRA = "group_thread";
|
||||
public static final String MASTER_SECRET_EXTRA = "master_secret";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
@ -80,17 +86,24 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
|
||||
private static final int PICK_CONTACT = 1;
|
||||
private static final int PICK_AVATAR = 2;
|
||||
public static final int AVATAR_SIZE = 210;
|
||||
public static final int AVATAR_SIZE = 210;
|
||||
|
||||
private EditText groupName;
|
||||
private ListView lv;
|
||||
private PushRecipientsPanel recipientsPanel;
|
||||
private ImageView avatar;
|
||||
private TextView creatingText;
|
||||
private ProgressDialog pd;
|
||||
|
||||
private Recipients groupRecipient = null;
|
||||
private long groupThread = -1;
|
||||
private byte[] groupId = null;
|
||||
private Set<Recipient> existingContacts = null;
|
||||
private String existingTitle = null;
|
||||
private Bitmap existingAvatarBmp = null;
|
||||
|
||||
private MasterSecret masterSecret;
|
||||
private Bitmap avatarBmp;
|
||||
|
||||
private Set<Recipient> selectedContacts;
|
||||
|
||||
@Override
|
||||
@ -124,10 +137,9 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
private void disableWhisperGroupUi(int reasonResId) {
|
||||
View pushDisabled = findViewById(R.id.push_disabled);
|
||||
pushDisabled.setVisibility(View.VISIBLE);
|
||||
((TextView)findViewById(R.id.push_disabled_reason)).setText(reasonResId);
|
||||
((TextView) findViewById(R.id.push_disabled_reason)).setText(reasonResId);
|
||||
avatar.setEnabled(false);
|
||||
groupName.setEnabled(false);
|
||||
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
|
||||
}
|
||||
|
||||
private void enableWhisperGroupUi() {
|
||||
@ -135,7 +147,7 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
avatar.setEnabled(true);
|
||||
groupName.setEnabled(true);
|
||||
final CharSequence groupNameText = groupName.getText();
|
||||
if (groupNameText.length() > 0)
|
||||
if (groupNameText != null && groupNameText.length() > 0)
|
||||
getSupportActionBar().setTitle(groupNameText);
|
||||
else
|
||||
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_title);
|
||||
@ -155,8 +167,12 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
}
|
||||
|
||||
private void addSelectedContact(Recipient contact) {
|
||||
selectedContacts.add(contact);
|
||||
if (!isActiveInDirectory(this, contact)) disableWhisperGroupUi(R.string.GroupCreateActivity_contacts_dont_support_push);
|
||||
if (!selectedContacts.contains(contact) && (existingContacts == null || !existingContacts.contains(contact)))
|
||||
selectedContacts.add(contact);
|
||||
if (!isActiveInDirectory(this, contact)) {
|
||||
disableWhisperGroupUi(R.string.GroupCreateActivity_contacts_dont_support_push);
|
||||
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_mms_title);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAllSelectedContacts(Collection<Recipient> contacts) {
|
||||
@ -177,6 +193,23 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
}
|
||||
|
||||
private void initializeResources() {
|
||||
groupRecipient = getIntent().getParcelableExtra(GROUP_RECIPIENT_EXTRA);
|
||||
groupThread = getIntent().getLongExtra(GROUP_THREAD_EXTRA, -1);
|
||||
if (groupRecipient != null) {
|
||||
final String encodedGroupId = groupRecipient.getPrimaryRecipient().getNumber();
|
||||
if (encodedGroupId != null) {
|
||||
try {
|
||||
groupId = GroupUtil.getDecodedId(encodedGroupId);
|
||||
} catch (IOException ioe) {
|
||||
Log.w(TAG, "Couldn't decode the encoded groupId passed in via intent", ioe);
|
||||
groupId = null;
|
||||
}
|
||||
if (groupId != null) {
|
||||
new FillExistingGroupInfoAsyncTask().execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
|
||||
|
||||
lv = (ListView) findViewById(R.id.selected_contacts_list);
|
||||
@ -192,14 +225,18 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { }
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (editable.length() > 0)
|
||||
getSupportActionBar().setTitle(getString(R.string.GroupCreateActivity_actionbar_title) + ": " + editable.toString());
|
||||
else
|
||||
if (editable.length() > 0) {
|
||||
final int prefixResId = (groupId != null)
|
||||
? R.string.GroupCreateActivity_actionbar_update_title
|
||||
: R.string.GroupCreateActivity_actionbar_title;
|
||||
getSupportActionBar().setTitle(getString(prefixResId) + ": " + editable.toString());
|
||||
} else {
|
||||
getSupportActionBar().setTitle(R.string.GroupCreateActivity_actionbar_title);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(this, android.R.id.text1, new ArrayList<Recipient>());
|
||||
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(this, android.R.id.text1, new ArrayList<SelectedRecipientsAdapter.RecipientWrapper>());
|
||||
adapter.setOnRecipientDeletedListener(new SelectedRecipientsAdapter.OnRecipientDeletedListener() {
|
||||
@Override
|
||||
public void onRecipientDeleted(Recipient recipient) {
|
||||
@ -235,6 +272,8 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
startActivityForResult(photoPickerIntent, PICK_AVATAR);
|
||||
}
|
||||
});
|
||||
|
||||
((RecipientsEditor)findViewById(R.id.recipients_text)).setHint(R.string.recipients_panel__add_member);
|
||||
}
|
||||
|
||||
private Uri getTempUri() {
|
||||
@ -276,7 +315,8 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
finish();
|
||||
return true;
|
||||
case R.id.menu_create_group:
|
||||
handleGroupCreate();
|
||||
if (groupId == null) handleGroupCreate();
|
||||
else handleGroupUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -297,6 +337,75 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> recipientsToNormalizedStrings(Collection<Recipient> recipients, String localNumber) {
|
||||
final List<String> e164numbers = new ArrayList<String>(recipients.size());
|
||||
for (Recipient contact : recipients) {
|
||||
try {
|
||||
e164numbers.add(PhoneNumberFormatter.formatNumber(contact.getNumber(), localNumber));
|
||||
} catch (InvalidNumberException ine) {
|
||||
Log.w(TAG, "Failed to format number for added group member.", ine);
|
||||
}
|
||||
}
|
||||
return e164numbers;
|
||||
}
|
||||
|
||||
private void handleGroupUpdate() {
|
||||
Log.i(TAG, "Updating group info.");
|
||||
GroupDatabase db = DatabaseFactory.getGroupDatabase(this);
|
||||
final String localNumber = TextSecurePreferences.getLocalNumber(this);
|
||||
List<String> e164numbers = recipientsToNormalizedStrings(selectedContacts, localNumber);
|
||||
if (selectedContacts.size() > 0) {
|
||||
db.add(groupId, localNumber, e164numbers);
|
||||
GroupContext context = GroupContext.newBuilder()
|
||||
.setId(ByteString.copyFrom(groupId))
|
||||
.setType(GroupContext.Type.ADD)
|
||||
.addAllMembers(e164numbers)
|
||||
.build();
|
||||
OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(this, groupRecipient, context, null);
|
||||
try {
|
||||
MessageSender.send(this, masterSecret, outgoingMessage, groupThread);
|
||||
} catch (MmsException me) {
|
||||
Log.w(TAG, "MmsException encountered when trying to add members to group.", me);
|
||||
}
|
||||
}
|
||||
|
||||
GroupContext.Builder builder = GroupContext.newBuilder()
|
||||
.setId(ByteString.copyFrom(groupId))
|
||||
.setType(GroupContext.Type.MODIFY);
|
||||
boolean shouldSendUpdate = false;
|
||||
final String title = groupName.getText().toString();
|
||||
if (existingTitle == null || (groupName.getText() != null && !existingTitle.equals(title))) {
|
||||
builder.setName(title);
|
||||
db.updateTitle(groupId, title);
|
||||
shouldSendUpdate = true;
|
||||
}
|
||||
byte[] avatarBytes = null;
|
||||
if (existingAvatarBmp == null || !existingAvatarBmp.equals(avatarBmp)) {
|
||||
if (avatarBmp != null) {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
avatarBmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
avatarBytes = stream.toByteArray();
|
||||
}
|
||||
db.updateAvatar(groupId, avatarBytes);
|
||||
shouldSendUpdate = true;
|
||||
}
|
||||
|
||||
if (shouldSendUpdate) {
|
||||
GroupContext context = builder.build();
|
||||
OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(this, groupRecipient, context, avatarBytes);
|
||||
try {
|
||||
MessageSender.send(this, masterSecret, outgoingMessage, groupThread);
|
||||
} catch (MmsException me) {
|
||||
Log.w(TAG, "MmsException encountered when trying to add members to group.", me);
|
||||
}
|
||||
}
|
||||
|
||||
RecipientFactory.clearCache(groupRecipient.getPrimaryRecipient());
|
||||
|
||||
setResult(RESULT_OK, getIntent());
|
||||
finish();
|
||||
}
|
||||
|
||||
private void enableWhisperGroupCreatingUi() {
|
||||
findViewById(R.id.group_details_layout).setVisibility(View.GONE);
|
||||
findViewById(R.id.creating_group_layout).setVisibility(View.VISIBLE);
|
||||
@ -315,7 +424,12 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
SelectedRecipientsAdapter adapter = (SelectedRecipientsAdapter)lv.getAdapter();
|
||||
adapter.clear();
|
||||
for (Recipient contact : selectedContacts) {
|
||||
adapter.add(contact);
|
||||
adapter.add(new SelectedRecipientsAdapter.RecipientWrapper(contact, true));
|
||||
}
|
||||
if (existingContacts != null) {
|
||||
for (Recipient contact : existingContacts) {
|
||||
adapter.add(new SelectedRecipientsAdapter.RecipientWrapper(contact, false));
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
@ -336,7 +450,8 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
Recipient recipient = RecipientFactory.getRecipientsFromString(this, numberData.number, false)
|
||||
.getPrimaryRecipient();
|
||||
|
||||
if (!selectedContacts.contains(recipient)) {
|
||||
if (!selectedContacts.contains(recipient)
|
||||
&& (existingContacts == null || !existingContacts.contains(recipient))) {
|
||||
addSelectedContact(recipient);
|
||||
}
|
||||
} catch (RecipientFormattingException e) {
|
||||
@ -347,14 +462,8 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
syncAdapterWithSelectedContacts();
|
||||
break;
|
||||
case PICK_AVATAR:
|
||||
if(resultCode == RESULT_OK) {
|
||||
|
||||
new DecodeCropAndSetAsyncTask().execute();
|
||||
|
||||
break;
|
||||
} else {
|
||||
Log.i(TAG, "Avatar selection result was not RESULT_OK.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,6 +520,14 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
ThreadDatabase.DistributionTypes.CONVERSATION);
|
||||
}
|
||||
|
||||
private static <T> ArrayList<T> setToArrayList(Set<T> set) {
|
||||
ArrayList<T> arrayList = new ArrayList<T>(set.size());
|
||||
for (T item : set) {
|
||||
arrayList.add(item);
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
private List<String> getE164Numbers(Set<Recipient> recipients)
|
||||
throws InvalidNumberException
|
||||
{
|
||||
@ -455,10 +572,7 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, resultThread.longValue());
|
||||
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
|
||||
|
||||
ArrayList<Recipient> selectedContactsList = new ArrayList<Recipient>(selectedContacts.size());
|
||||
for (Recipient recipient : selectedContacts) {
|
||||
selectedContactsList.add(recipient);
|
||||
}
|
||||
ArrayList<Recipient> selectedContactsList = setToArrayList(selectedContacts);
|
||||
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, new Recipients(selectedContactsList));
|
||||
startActivity(intent);
|
||||
finish();
|
||||
@ -525,4 +639,58 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
|
||||
super.onProgressUpdate(values);
|
||||
}
|
||||
}
|
||||
|
||||
private class FillExistingGroupInfoAsyncTask extends AsyncTask<Void,Void,Boolean> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
pd = new ProgressDialog(GroupCreateActivity.this);
|
||||
pd.setTitle("Loading group details...");
|
||||
pd.setMessage("Please wait.");
|
||||
pd.setCancelable(false);
|
||||
pd.setIndeterminate(true);
|
||||
pd.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
final GroupDatabase db = DatabaseFactory.getGroupDatabase(GroupCreateActivity.this);
|
||||
final Recipients recipients = db.getGroupMembers(groupId);
|
||||
if (recipients != null) {
|
||||
final List<Recipient> recipientList = recipients.getRecipientsList();
|
||||
if (recipientList != null) {
|
||||
if (existingContacts == null)
|
||||
existingContacts = new HashSet<Recipient>(recipientList.size());
|
||||
existingContacts.addAll(recipientList);
|
||||
}
|
||||
}
|
||||
final GroupDatabase.Reader groupReader = db.getGroup(groupId);
|
||||
GroupDatabase.GroupRecord group = groupReader.getNext();
|
||||
if (group != null) {
|
||||
existingTitle = group.getTitle();
|
||||
final byte[] existingAvatar = group.getAvatar();
|
||||
if (existingAvatar != null) {
|
||||
existingAvatarBmp = BitmapUtil.getCircleCroppedBitmap(
|
||||
BitmapFactory.decodeByteArray(existingAvatar, 0, existingAvatar.length));
|
||||
}
|
||||
return (group.getOwner() != null && group.getOwner().equals(TextSecurePreferences.getLocalNumber(GroupCreateActivity.this)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean isOwner) {
|
||||
super.onPostExecute(isOwner);
|
||||
|
||||
if (pd != null) pd.dismiss();
|
||||
if (existingTitle != null) groupName.setText(existingTitle);
|
||||
if (existingAvatarBmp != null) avatar.setImageBitmap(existingAvatarBmp);
|
||||
if (existingContacts != null) syncAdapterWithSelectedContacts();
|
||||
if (!isOwner) {
|
||||
disableWhisperGroupUi(R.string.GroupCreateActivity_you_dont_own_this_group);
|
||||
getSupportActionBar().setTitle(getString(R.string.GroupCreateActivity_actionbar_update_title)
|
||||
+ (TextUtils.isEmpty(existingTitle) ? "" : ": " + existingTitle));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
import java.io.InputStream;
|
||||
@ -73,6 +74,11 @@ public class ContactPhotoFactory {
|
||||
localUserContactPhotoCache.clear();
|
||||
}
|
||||
|
||||
public static void clearCache(Recipient recipient) {
|
||||
if (localUserContactPhotoCache.containsKey(recipient.getContactUri()))
|
||||
localUserContactPhotoCache.remove(recipient.getContactUri());
|
||||
}
|
||||
|
||||
private static Bitmap getContactPhoto(Context context, Uri uri) {
|
||||
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);
|
||||
|
||||
|
@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.database;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
@ -21,6 +22,8 @@ import org.whispersystems.textsecure.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -138,6 +141,13 @@ public class GroupDatabase extends Database {
|
||||
new String[] {GroupUtil.getEncodedId(groupId), source});
|
||||
}
|
||||
|
||||
public void updateTitle(byte[] groupId, String title) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(TITLE, title);
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?",
|
||||
new String[] {GroupUtil.getEncodedId(groupId)});
|
||||
}
|
||||
|
||||
public void updateAvatar(byte[] groupId, Bitmap avatar) {
|
||||
updateAvatar(groupId, BitmapUtil.toByteArray(avatar));
|
||||
}
|
||||
@ -198,6 +208,28 @@ public class GroupDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public String getOwner(byte[] id) {
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
SQLiteDatabase readableDatabase = databaseHelper.getReadableDatabase();
|
||||
if (readableDatabase == null)
|
||||
return null;
|
||||
|
||||
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {OWNER},
|
||||
GROUP_ID + " = ?",
|
||||
new String[] {GroupUtil.getEncodedId(id)},
|
||||
null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getString(cursor.getColumnIndexOrThrow(OWNER));
|
||||
}
|
||||
return null;
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] allocateGroupId() {
|
||||
try {
|
||||
byte[] groupId = new byte[16];
|
||||
@ -224,6 +256,7 @@ public class GroupDatabase extends Database {
|
||||
|
||||
return new GroupRecord(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(TITLE)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(OWNER)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)),
|
||||
cursor.getBlob(cursor.getColumnIndexOrThrow(AVATAR)),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(AVATAR_ID)),
|
||||
@ -242,6 +275,7 @@ public class GroupDatabase extends Database {
|
||||
|
||||
private final String id;
|
||||
private final String title;
|
||||
private final String owner;
|
||||
private final List<String> members;
|
||||
private final byte[] avatar;
|
||||
private final long avatarId;
|
||||
@ -249,12 +283,13 @@ public class GroupDatabase extends Database {
|
||||
private final String avatarContentType;
|
||||
private final String relay;
|
||||
|
||||
public GroupRecord(String id, String title, String members, byte[] avatar,
|
||||
public GroupRecord(String id, String title, String owner, String members, byte[] avatar,
|
||||
long avatarId, byte[] avatarKey, String avatarContentType,
|
||||
String relay)
|
||||
{
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.owner = owner;
|
||||
this.members = Util.split(members, ",");
|
||||
this.avatar = avatar;
|
||||
this.avatarId = avatarId;
|
||||
@ -275,6 +310,10 @@ public class GroupDatabase extends Database {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public List<String> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
@ -138,4 +138,9 @@ public class RecipientFactory {
|
||||
provider.clearCache();
|
||||
}
|
||||
|
||||
public static void clearCache(Recipient recipient) {
|
||||
ContactPhotoFactory.clearCache(recipient);
|
||||
provider.clearCache(recipient);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -116,6 +116,11 @@ public class RecipientProvider {
|
||||
recipientCache.clear();
|
||||
}
|
||||
|
||||
public void clearCache(Recipient recipient) {
|
||||
if (recipientCache.containsKey(recipient.getRecipientId()))
|
||||
recipientCache.remove(recipient.getRecipientId());
|
||||
}
|
||||
|
||||
private RecipientDetails getRecipientDetails(Context context, String number) {
|
||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
|
||||
Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION,
|
||||
|
@ -12,18 +12,17 @@ import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SelectedRecipientsAdapter extends ArrayAdapter<Recipient> {
|
||||
public class SelectedRecipientsAdapter extends ArrayAdapter<SelectedRecipientsAdapter.RecipientWrapper> {
|
||||
|
||||
private ArrayList<Recipient> recipients;
|
||||
private ArrayList<RecipientWrapper> recipients;
|
||||
private OnRecipientDeletedListener onRecipientDeletedListener;
|
||||
|
||||
public SelectedRecipientsAdapter(Context context, int textViewResourceId) {
|
||||
super(context, textViewResourceId);
|
||||
}
|
||||
|
||||
public SelectedRecipientsAdapter(Context context, int resource, ArrayList<Recipient> recipients) {
|
||||
public SelectedRecipientsAdapter(Context context, int resource, ArrayList<RecipientWrapper> recipients) {
|
||||
super(context, resource, recipients);
|
||||
this.recipients = recipients;
|
||||
}
|
||||
@ -41,7 +40,9 @@ public class SelectedRecipientsAdapter extends ArrayAdapter<Recipient> {
|
||||
|
||||
}
|
||||
|
||||
Recipient p = getItem(position);
|
||||
final RecipientWrapper rw = getItem(position);
|
||||
final Recipient p = rw.getRecipient();
|
||||
final boolean modifiable = rw.isModifiable();
|
||||
|
||||
if (p != null) {
|
||||
|
||||
@ -53,20 +54,25 @@ public class SelectedRecipientsAdapter extends ArrayAdapter<Recipient> {
|
||||
name.setText(p.getName());
|
||||
}
|
||||
if (phone != null) {
|
||||
|
||||
phone.setText(p.getNumber());
|
||||
}
|
||||
if (delete != null) {
|
||||
delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (onRecipientDeletedListener != null) {
|
||||
onRecipientDeletedListener.onRecipientDeleted(recipients.get(position));
|
||||
if (modifiable) {
|
||||
delete.setVisibility(View.VISIBLE);
|
||||
delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (onRecipientDeletedListener != null) {
|
||||
onRecipientDeletedListener.onRecipientDeleted(recipients.get(position).getRecipient());
|
||||
}
|
||||
recipients.remove(position);
|
||||
SelectedRecipientsAdapter.this.notifyDataSetChanged();
|
||||
}
|
||||
recipients.remove(position);
|
||||
SelectedRecipientsAdapter.this.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
delete.setVisibility(View.INVISIBLE);
|
||||
delete.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,4 +86,22 @@ public class SelectedRecipientsAdapter extends ArrayAdapter<Recipient> {
|
||||
public interface OnRecipientDeletedListener {
|
||||
public void onRecipientDeleted(Recipient recipient);
|
||||
}
|
||||
|
||||
public static class RecipientWrapper {
|
||||
private final Recipient recipient;
|
||||
private final boolean modifiable;
|
||||
|
||||
public RecipientWrapper(final Recipient recipient, final boolean modifiable) {
|
||||
this.recipient = recipient;
|
||||
this.modifiable = modifiable;
|
||||
}
|
||||
|
||||
public Recipient getRecipient() {
|
||||
return recipient;
|
||||
}
|
||||
|
||||
public boolean isModifiable() {
|
||||
return modifiable;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user