Merge pull request #1043 from strb/choose_contact_multiple_squashed

Daniel Gultsch created

Added multiple select to Choose Contact Activity (squashed)

Change summary

src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java | 94 
src/main/java/eu/siacs/conversations/ui/XmppActivity.java          | 33 
src/main/res/menu/select_multiple.xml                              |  9 
src/main/res/values/strings.xml                                    |  4 
4 files changed, 134 insertions(+), 6 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/ui/ChooseContactActivity.java 🔗

@@ -3,20 +3,100 @@ package eu.siacs.conversations.ui;
 import android.content.Context;
 import android.content.Intent;
 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.inputmethod.InputMethodManager;
+import android.widget.AbsListView.MultiChoiceModeListener;
 import android.widget.AdapterView;
+import android.widget.ListView;
 
+import java.util.Set;
+import java.util.HashSet;
 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.Contact;
 import eu.siacs.conversations.entities.ListItem;
 
 public class ChooseContactActivity extends AbstractSearchableListItemActivity {
+
+	private Set<Contact> selected;
+	private Set<String> filterContacts;
+
 	@Override
 	public void onCreate(final Bundle 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() {
 
 			@Override
@@ -36,6 +116,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
 				data.putExtra("account", account);
 				data.putExtra("conversation",
 						request.getStringExtra("conversation"));
+				data.putExtra("multiple", false);
 				setResult(RESULT_OK, data);
 				finish();
 			}
@@ -48,7 +129,9 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
 		for (final Account account : xmppConnectionService.getAccounts()) {
 			if (account.getStatus() != Account.State.DISABLED) {
 				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);
 					}
 				}
@@ -57,4 +140,13 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
 		Collections.sort(getListItems());
 		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()]);
+	}
+
 }

src/main/java/eu/siacs/conversations/ui/XmppActivity.java 🔗

@@ -69,6 +69,7 @@ import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.entities.Presences;
 import eu.siacs.conversations.services.AvatarService;
 import eu.siacs.conversations.services.XmppConnectionService;
@@ -409,7 +410,20 @@ public abstract class XmppActivity extends Activity {
 	protected void inviteToConversation(Conversation conversation) {
 		Intent intent = new Intent(getApplicationContext(),
 				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("multiple", true);
 		startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION);
 	}
 
@@ -652,22 +666,31 @@ public abstract class XmppActivity extends Activity {
 		if (requestCode == REQUEST_INVITE_TO_CONVERSATION
 				&& resultCode == RESULT_OK) {
 			try {
-				Jid jid = Jid.fromString(data.getStringExtra("contact"));
 				String conversationUuid = data.getStringExtra("conversation");
 				Conversation conversation = xmppConnectionService
 					.findConversationByUuid(conversationUuid);
+				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) {
-					xmppConnectionService.invite(conversation, jid);
+					for (Jid jid : jids) {
+						xmppConnectionService.invite(conversation, jid);
+					}
 				} else {
-					List<Jid> jids = new ArrayList<Jid>();
 					jids.add(conversation.getJid().toBareJid());
-					jids.add(jid);
 					xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback);
 				}
 			} catch (final InvalidJidException ignored) {
 
 			}
-				}
+		}
 	}
 
 	private UiCallback<Conversation> adhocCallback = new UiCallback<Conversation>() {

src/main/res/menu/select_multiple.xml 🔗

@@ -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>

src/main/res/values/strings.xml 🔗

@@ -454,4 +454,8 @@
     <string name="no_application_found_to_display_location">No application found to display location</string>
     <string name="location">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>