Added multiple select to Choose Contact Activity
When passing the Choose Contact Activity a boolean called "multiple" set to true, it now allows the user to select multiple contacts. Long pressing a contact enters multiple selection mode and the selection is confirmed using a button in the CAB. The Activity returns whether or not multiple contacts were selected using the same boolean. If multiple contacts were selected, an array of JID strings called "contacts" is returned. The Choose Contact Activity now also honors "filter_contacts", an array of strings containing JIDs that should not be displayed in the picker. The invite to conference dialog now uses this feature to enable inviting multiple contacts at once. Additionally, Invite Contact uses "filter_contacts" to only display contacts that are not yet participating in the conversation
This commit is contained in:
parent
4aab45533a
commit
f76baa5658
|
@ -3,20 +3,100 @@ package eu.siacs.conversations.ui;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.ActionMode;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.AbsListView.MultiChoiceModeListener;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.ListItem;
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
|
|
||||||
public class ChooseContactActivity extends AbstractSearchableListItemActivity {
|
public class ChooseContactActivity extends AbstractSearchableListItemActivity {
|
||||||
|
|
||||||
|
private Set<Contact> selected;
|
||||||
|
private Set<String> filterContacts;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(final Bundle savedInstanceState) {
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
filterContacts = new HashSet<>();
|
||||||
|
String[] contacts = getIntent().getStringArrayExtra("filter_contacts");
|
||||||
|
if (contacts != null) {
|
||||||
|
Collections.addAll(filterContacts, contacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getIntent().getBooleanExtra("multiple", false)) {
|
||||||
|
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
|
||||||
|
getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||||
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(),
|
||||||
|
InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.select_multiple, menu);
|
||||||
|
selected = new HashSet<Contact>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyActionMode(ActionMode mode) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||||
|
switch(item.getItemId()) {
|
||||||
|
case R.id.selection_submit:
|
||||||
|
final Intent request = getIntent();
|
||||||
|
final Intent data = new Intent();
|
||||||
|
data.putExtra("conversation",
|
||||||
|
request.getStringExtra("conversation"));
|
||||||
|
String[] selection = getSelectedContactJids();
|
||||||
|
data.putExtra("contacts", selection);
|
||||||
|
data.putExtra("multiple", true);
|
||||||
|
setResult(RESULT_OK, data);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
|
||||||
|
Contact item = (Contact) getListItems().get(position);
|
||||||
|
if (checked) {
|
||||||
|
selected.add(item);
|
||||||
|
} else {
|
||||||
|
selected.remove(item);
|
||||||
|
}
|
||||||
|
int numSelected = selected.size();
|
||||||
|
MenuItem selectButton = mode.getMenu().findItem(R.id.selection_submit);
|
||||||
|
String buttonText = getResources().getQuantityString(R.plurals.select_contact,
|
||||||
|
numSelected, numSelected);
|
||||||
|
selectButton.setTitle(buttonText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,6 +116,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
|
||||||
data.putExtra("account", account);
|
data.putExtra("account", account);
|
||||||
data.putExtra("conversation",
|
data.putExtra("conversation",
|
||||||
request.getStringExtra("conversation"));
|
request.getStringExtra("conversation"));
|
||||||
|
data.putExtra("multiple", false);
|
||||||
setResult(RESULT_OK, data);
|
setResult(RESULT_OK, data);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
@ -48,7 +129,9 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
|
||||||
for (final Account account : xmppConnectionService.getAccounts()) {
|
for (final Account account : xmppConnectionService.getAccounts()) {
|
||||||
if (account.getStatus() != Account.State.DISABLED) {
|
if (account.getStatus() != Account.State.DISABLED) {
|
||||||
for (final Contact contact : account.getRoster().getContacts()) {
|
for (final Contact contact : account.getRoster().getContacts()) {
|
||||||
if (contact.showInRoster() && contact.match(needle)) {
|
if (contact.showInRoster() &&
|
||||||
|
!filterContacts.contains(contact.getJid().toBareJid().toString())
|
||||||
|
&& contact.match(needle)) {
|
||||||
getListItems().add(contact);
|
getListItems().add(contact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,4 +140,13 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
|
||||||
Collections.sort(getListItems());
|
Collections.sort(getListItems());
|
||||||
getListItemAdapter().notifyDataSetChanged();
|
getListItemAdapter().notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String[] getSelectedContactJids() {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
for (Contact contact : selected) {
|
||||||
|
result.add(contact.getJid().toString());
|
||||||
|
}
|
||||||
|
return result.toArray(new String[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
import eu.siacs.conversations.entities.Presences;
|
import eu.siacs.conversations.entities.Presences;
|
||||||
import eu.siacs.conversations.services.AvatarService;
|
import eu.siacs.conversations.services.AvatarService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
@ -409,7 +410,20 @@ public abstract class XmppActivity extends Activity {
|
||||||
protected void inviteToConversation(Conversation conversation) {
|
protected void inviteToConversation(Conversation conversation) {
|
||||||
Intent intent = new Intent(getApplicationContext(),
|
Intent intent = new Intent(getApplicationContext(),
|
||||||
ChooseContactActivity.class);
|
ChooseContactActivity.class);
|
||||||
|
List<String> contacts = new ArrayList<>();
|
||||||
|
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
||||||
|
for (MucOptions.User user : conversation.getMucOptions().getUsers()) {
|
||||||
|
Jid jid = user.getJid();
|
||||||
|
if (jid != null) {
|
||||||
|
contacts.add(jid.toBareJid().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
contacts.add(conversation.getJid().toBareJid().toString());
|
||||||
|
}
|
||||||
|
intent.putExtra("filter_contacts", contacts.toArray(new String[contacts.size()]));
|
||||||
intent.putExtra("conversation", conversation.getUuid());
|
intent.putExtra("conversation", conversation.getUuid());
|
||||||
|
intent.putExtra("multiple", true);
|
||||||
startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION);
|
startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,16 +666,25 @@ public abstract class XmppActivity extends Activity {
|
||||||
if (requestCode == REQUEST_INVITE_TO_CONVERSATION
|
if (requestCode == REQUEST_INVITE_TO_CONVERSATION
|
||||||
&& resultCode == RESULT_OK) {
|
&& resultCode == RESULT_OK) {
|
||||||
try {
|
try {
|
||||||
Jid jid = Jid.fromString(data.getStringExtra("contact"));
|
|
||||||
String conversationUuid = data.getStringExtra("conversation");
|
String conversationUuid = data.getStringExtra("conversation");
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findConversationByUuid(conversationUuid);
|
.findConversationByUuid(conversationUuid);
|
||||||
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
|
||||||
xmppConnectionService.invite(conversation, jid);
|
|
||||||
} else {
|
|
||||||
List<Jid> jids = new ArrayList<Jid>();
|
List<Jid> jids = new ArrayList<Jid>();
|
||||||
|
if (data.getBooleanExtra("multiple", false)) {
|
||||||
|
String[] toAdd = data.getStringArrayExtra("contacts");
|
||||||
|
for (String item : toAdd) {
|
||||||
|
jids.add(Jid.fromString(item));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jids.add(Jid.fromString(data.getStringExtra("contact")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
||||||
|
for (Jid jid : jids) {
|
||||||
|
xmppConnectionService.invite(conversation, jid);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
jids.add(conversation.getJid().toBareJid());
|
jids.add(conversation.getJid().toBareJid());
|
||||||
jids.add(jid);
|
|
||||||
xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback);
|
xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback);
|
||||||
}
|
}
|
||||||
} catch (final InvalidJidException ignored) {
|
} catch (final InvalidJidException ignored) {
|
||||||
|
|
9
src/main/res/menu/select_multiple.xml
Normal file
9
src/main/res/menu/select_multiple.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/selection_submit"
|
||||||
|
android:title="@string/invite_contact"
|
||||||
|
android:showAsAction="always" />
|
||||||
|
|
||||||
|
</menu>
|
|
@ -454,4 +454,8 @@
|
||||||
<string name="no_application_found_to_display_location">No application found to display location</string>
|
<string name="no_application_found_to_display_location">No application found to display location</string>
|
||||||
<string name="location">Location</string>
|
<string name="location">Location</string>
|
||||||
<string name="received_location">Received location</string>
|
<string name="received_location">Received location</string>
|
||||||
|
<plurals name="select_contact">
|
||||||
|
<item quantity="one">Select %d contact</item>
|
||||||
|
<item quantity="other">Select %d contacts</item>
|
||||||
|
</plurals>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue