Prevent UUID-only contacts from being added to GV1 groups.
This commit is contained in:
parent
cc84901a49
commit
550b121990
10 changed files with 94 additions and 33 deletions
|
@ -113,7 +113,9 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActivit
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {}
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactDeselected(Optional<RecipientId> recipientId, String number) {}
|
public void onContactDeselected(Optional<RecipientId> recipientId, String number) {}
|
||||||
|
|
|
@ -473,11 +473,15 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||||
if (uuid.isPresent()) {
|
if (uuid.isPresent()) {
|
||||||
Recipient recipient = Recipient.externalUsername(requireContext(), uuid.get(), contact.getNumber());
|
Recipient recipient = Recipient.externalUsername(requireContext(), uuid.get(), contact.getNumber());
|
||||||
SelectedContact selected = SelectedContact.forUsername(recipient.getId(), contact.getNumber());
|
SelectedContact selected = SelectedContact.forUsername(recipient.getId(), contact.getNumber());
|
||||||
markContactSelected(selected);
|
|
||||||
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
|
|
||||||
|
|
||||||
if (onContactSelectedListener != null) {
|
if (onContactSelectedListener != null) {
|
||||||
onContactSelectedListener.onContactSelected(Optional.of(recipient.getId()), null);
|
if (onContactSelectedListener.onContactSelected(Optional.of(recipient.getId()), null)) {
|
||||||
|
markContactSelected(selected);
|
||||||
|
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
markContactSelected(selected);
|
||||||
|
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new AlertDialog.Builder(requireContext())
|
new AlertDialog.Builder(requireContext())
|
||||||
|
@ -487,12 +491,15 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (onContactSelectedListener != null) {
|
||||||
|
if (onContactSelectedListener.onContactSelected(contact.getRecipientId(), contact.getNumber())) {
|
||||||
|
markContactSelected(selectedContact);
|
||||||
|
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
markContactSelected(selectedContact);
|
markContactSelected(selectedContact);
|
||||||
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
|
cursorRecyclerViewAdapter.notifyItemChanged(recyclerView.getChildAdapterPosition(contact), ContactSelectionListAdapter.PAYLOAD_SELECTION_CHANGE);
|
||||||
|
|
||||||
if (onContactSelectedListener != null) {
|
|
||||||
onContactSelectedListener.onContactSelected(contact.getRecipientId(), contact.getNumber());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -624,7 +631,8 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnContactSelectedListener {
|
public interface OnContactSelectedListener {
|
||||||
void onContactSelected(Optional<RecipientId> recipientId, String number);
|
/** @return True if the contact is allowed to be selected, otherwise false. */
|
||||||
|
boolean onContactSelected(Optional<RecipientId> recipientId, String number);
|
||||||
void onContactDeselected(Optional<RecipientId> recipientId, String number);
|
void onContactDeselected(Optional<RecipientId> recipientId, String number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,8 +121,9 @@ public class InviteActivity extends PassphraseRequiredActivity implements Contac
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
updateSmsButtonText();
|
updateSmsButtonText();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class NewConversationActivity extends ContactSelectionActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
if (recipientId.isPresent()) {
|
if (recipientId.isPresent()) {
|
||||||
launch(Recipient.resolved(recipientId.get()));
|
launch(Recipient.resolved(recipientId.get()));
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,6 +92,8 @@ public class NewConversationActivity extends ContactSelectionActivity
|
||||||
launch(Recipient.external(this, number));
|
launch(Recipient.external(this, number));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launch(Recipient recipient) {
|
private void launch(Recipient recipient) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.groups.ui.addmembers;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
@ -58,14 +59,19 @@ public class AddMembersActivity extends PushContactSelectionActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
|
if (getGroupId().isV1() && recipientId.isPresent() && !Recipient.resolved(recipientId.get()).hasE164()) {
|
||||||
|
Toast.makeText(this, R.string.AddMembersActivity__this_person_cant_be_added_to_legacy_groups, Toast.LENGTH_SHORT).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (contactsFragment.hasQueryFilter()) {
|
if (contactsFragment.hasQueryFilter()) {
|
||||||
getToolbar().clear();
|
getToolbar().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contactsFragment.getSelectedContactsCount() >= 1) {
|
|
||||||
enableDone();
|
enableDone();
|
||||||
}
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -39,13 +39,18 @@ public final class AddToGroupViewModel extends ViewModel {
|
||||||
events.postValue(new Event.CloseEvent());
|
events.postValue(new Event.CloseEvent());
|
||||||
} else if (groupRecipientIds.size() == 1) {
|
} else if (groupRecipientIds.size() == 1) {
|
||||||
SignalExecutors.BOUNDED.execute(() -> {
|
SignalExecutors.BOUNDED.execute(() -> {
|
||||||
|
Recipient recipient = Recipient.resolved(recipientId);
|
||||||
Recipient groupRecipient = Recipient.resolved(groupRecipientIds.get(0));
|
Recipient groupRecipient = Recipient.resolved(groupRecipientIds.get(0));
|
||||||
String recipientName = Recipient.resolved(recipientId).getDisplayName(context);
|
String recipientName = recipient.getDisplayName(context);
|
||||||
String groupName = groupRecipient.getDisplayName(context);
|
String groupName = groupRecipient.getDisplayName(context);
|
||||||
|
|
||||||
|
if (groupRecipient.getGroupId().get().isV1() && !recipient.hasE164()) {
|
||||||
|
events.postValue(new Event.LegacyGroupDenialEvent());
|
||||||
|
} else {
|
||||||
events.postValue(new Event.AddToSingleGroupConfirmationEvent(context.getResources().getString(R.string.AddToGroupActivity_add_member),
|
events.postValue(new Event.AddToSingleGroupConfirmationEvent(context.getResources().getString(R.string.AddToGroupActivity_add_member),
|
||||||
context.getResources().getString(R.string.AddToGroupActivity_add_s_to_s, recipientName, groupName),
|
context.getResources().getString(R.string.AddToGroupActivity_add_s_to_s, recipientName, groupName),
|
||||||
groupRecipient, recipientName, groupName));
|
groupRecipient, recipientName, groupName));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new AssertionError("Does not support multi-select");
|
throw new AssertionError("Does not support multi-select");
|
||||||
|
@ -107,6 +112,9 @@ public final class AddToGroupViewModel extends ViewModel {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class LegacyGroupDenialEvent extends Event {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Factory implements ViewModelProvider.Factory {
|
public static class Factory implements ViewModelProvider.Factory {
|
||||||
|
|
|
@ -91,6 +91,8 @@ public final class AddToGroupsActivity extends ContactSelectionActivity {
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> viewModel.onAddToGroupsConfirmed(addEvent))
|
.setPositiveButton(android.R.string.ok, (dialog, which) -> viewModel.onAddToGroupsConfirmed(addEvent))
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.show();
|
.show();
|
||||||
|
} else if (event instanceof Event.LegacyGroupDenialEvent) {
|
||||||
|
Toast.makeText(this, R.string.AddToGroupActivity_this_person_cant_be_added_to_legacy_groups, Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
@ -112,20 +114,23 @@ public final class AddToGroupsActivity extends ContactSelectionActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
if (contactsFragment.isMulti()) {
|
if (contactsFragment.isMulti()) {
|
||||||
if (contactsFragment.hasQueryFilter()) {
|
throw new UnsupportedOperationException("Not yet built to handle multi-select.");
|
||||||
getToolbar().clear();
|
// if (contactsFragment.hasQueryFilter()) {
|
||||||
}
|
// getToolbar().clear();
|
||||||
|
// }
|
||||||
if (contactsFragment.getSelectedContactsCount() >= MINIMUM_GROUP_SELECT_SIZE) {
|
//
|
||||||
enableNext();
|
// if (contactsFragment.getSelectedContactsCount() >= MINIMUM_GROUP_SELECT_SIZE) {
|
||||||
}
|
// enableNext();
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
if (recipientId.isPresent()) {
|
if (recipientId.isPresent()) {
|
||||||
viewModel.onContinueWithSelection(Collections.singletonList(recipientId.get()));
|
viewModel.onContinueWithSelection(Collections.singletonList(recipientId.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
@ -30,6 +31,8 @@ import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CreateGroupActivity extends ContactSelectionActivity {
|
public class CreateGroupActivity extends ContactSelectionActivity {
|
||||||
|
@ -90,14 +93,14 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
if (contactsFragment.hasQueryFilter()) {
|
if (contactsFragment.hasQueryFilter()) {
|
||||||
getToolbar().clear();
|
getToolbar().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contactsFragment.getSelectedContactsCount() >= MINIMUM_GROUP_SIZE) {
|
|
||||||
enableNext();
|
enableNext();
|
||||||
}
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -160,13 +163,31 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
||||||
|
|
||||||
stopwatch.split("capabilities");
|
stopwatch.split("capabilities");
|
||||||
|
|
||||||
|
resolved = Recipient.resolvedList(ids);
|
||||||
|
|
||||||
|
if (Stream.of(resolved).anyMatch(r -> r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED) &&
|
||||||
|
Stream.of(resolved).anyMatch(r -> !r.hasE164()))
|
||||||
|
{
|
||||||
|
Log.w(TAG, "Invalid GV1 group...");
|
||||||
|
ids = Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
stopwatch.split("gv1-check");
|
||||||
|
|
||||||
return ids;
|
return ids;
|
||||||
}, ids -> {
|
}, ids -> {
|
||||||
dismissibleDialog.dismiss();
|
dismissibleDialog.dismiss();
|
||||||
|
|
||||||
stopwatch.stop(TAG);
|
stopwatch.stop(TAG);
|
||||||
|
|
||||||
|
if (ids.isEmpty()) {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setMessage(R.string.CreateGroupActivity_some_contacts_cannot_be_in_legacy_groups)
|
||||||
|
.setPositiveButton(android.R.string.ok, (d, w) -> d.dismiss())
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
startActivityForResult(AddGroupDetailsActivity.newIntent(this, ids), REQUEST_CODE_ADD_DETAILS);
|
startActivityForResult(AddGroupDetailsActivity.newIntent(this, ids), REQUEST_CODE_ADD_DETAILS);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,8 +148,9 @@ public class ShareActivity extends PassphraseRequiredActivity
|
||||||
else super.onBackPressed();
|
else super.onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactSelected(Optional<RecipientId> recipientId, String number) {
|
public boolean onContactSelected(Optional<RecipientId> recipientId, String number) {
|
||||||
SimpleTask.run(this.getLifecycle(), () -> {
|
SimpleTask.run(this.getLifecycle(), () -> {
|
||||||
Recipient recipient;
|
Recipient recipient;
|
||||||
if (recipientId.isPresent()) {
|
if (recipientId.isPresent()) {
|
||||||
|
@ -162,6 +163,8 @@ public class ShareActivity extends PassphraseRequiredActivity
|
||||||
long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient);
|
long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient);
|
||||||
return new Pair<>(existingThread, recipient);
|
return new Pair<>(existingThread, recipient);
|
||||||
}, result -> onDestinationChosen(result.first(), result.second().getId()));
|
}, result -> onDestinationChosen(result.first(), result.second().getId()));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -365,6 +365,9 @@
|
||||||
<string name="ConversationTitleView_verified">Verified</string>
|
<string name="ConversationTitleView_verified">Verified</string>
|
||||||
<string name="ConversationTitleView_you">You</string>
|
<string name="ConversationTitleView_you">You</string>
|
||||||
|
|
||||||
|
<!-- CreateGroupActivity -->
|
||||||
|
<string name="CreateGroupActivity_some_contacts_cannot_be_in_legacy_groups">Some contacts cannot be in legacy groups.</string>
|
||||||
|
|
||||||
<!-- CreateProfileActivity -->
|
<!-- CreateProfileActivity -->
|
||||||
<string name="CreateProfileActivity__profile">Profile</string>
|
<string name="CreateProfileActivity__profile">Profile</string>
|
||||||
<string name="CreateProfileActivity_error_setting_profile_photo">Error setting profile photo</string>
|
<string name="CreateProfileActivity_error_setting_profile_photo">Error setting profile photo</string>
|
||||||
|
@ -444,6 +447,7 @@
|
||||||
<string name="AddToGroupActivity_s_added_to_s">\"%1$s\" added to \"%2$s\".</string>
|
<string name="AddToGroupActivity_s_added_to_s">\"%1$s\" added to \"%2$s\".</string>
|
||||||
<string name="AddToGroupActivity_add_to_group">Add to group</string>
|
<string name="AddToGroupActivity_add_to_group">Add to group</string>
|
||||||
<string name="AddToGroupActivity_add_to_groups">Add to groups</string>
|
<string name="AddToGroupActivity_add_to_groups">Add to groups</string>
|
||||||
|
<string name="AddToGroupActivity_this_person_cant_be_added_to_legacy_groups">This person can\'t be added to legacy groups.</string>
|
||||||
|
|
||||||
<!-- ChooseNewAdminActivity -->
|
<!-- ChooseNewAdminActivity -->
|
||||||
<string name="ChooseNewAdminActivity_choose_new_admin">Choose new admin</string>
|
<string name="ChooseNewAdminActivity_choose_new_admin">Choose new admin</string>
|
||||||
|
@ -502,6 +506,7 @@
|
||||||
|
|
||||||
<!-- AddMembersActivity -->
|
<!-- AddMembersActivity -->
|
||||||
<string name="AddMembersActivity__done">Done</string>
|
<string name="AddMembersActivity__done">Done</string>
|
||||||
|
<string name="AddMembersActivity__this_person_cant_be_added_to_legacy_groups">This person can\'t be added to legacy groups.</string>
|
||||||
<plurals name="AddMembersActivity__add_d_members_to_s">
|
<plurals name="AddMembersActivity__add_d_members_to_s">
|
||||||
<item quantity="one">Add \"%1$s\" to \"%2$s\"?</item>
|
<item quantity="one">Add \"%1$s\" to \"%2$s\"?</item>
|
||||||
<item quantity="other">Add %3$d members to \"%2$s\"?</item>
|
<item quantity="other">Add %3$d members to \"%2$s\"?</item>
|
||||||
|
|
Loading…
Add table
Reference in a new issue