ChooseContactActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.Activity;
  4import android.content.Context;
  5import android.content.Intent;
  6import android.os.Bundle;
  7import android.support.annotation.StringRes;
  8import android.support.v7.app.ActionBar;
  9import android.view.ActionMode;
 10import android.view.Menu;
 11import android.view.MenuInflater;
 12import android.view.MenuItem;
 13import android.view.View;
 14import android.view.inputmethod.InputMethodManager;
 15import android.widget.AbsListView.MultiChoiceModeListener;
 16import android.widget.ListView;
 17
 18import java.util.ArrayList;
 19import java.util.Collections;
 20import java.util.HashSet;
 21import java.util.List;
 22import java.util.Set;
 23
 24import eu.siacs.conversations.Config;
 25import eu.siacs.conversations.R;
 26import eu.siacs.conversations.entities.Account;
 27import eu.siacs.conversations.entities.Contact;
 28import eu.siacs.conversations.entities.Conversation;
 29import eu.siacs.conversations.entities.ListItem;
 30import eu.siacs.conversations.entities.MucOptions;
 31import rocks.xmpp.addr.Jid;
 32
 33public class ChooseContactActivity extends AbstractSearchableListItemActivity {
 34	public static final String EXTRA_TITLE_RES_ID = "extra_title_res_id";
 35	private List<String> mActivatedAccounts = new ArrayList<>();
 36	private List<String> mKnownHosts;
 37	private Set<Contact> selected;
 38	private Set<String> filterContacts;
 39
 40	public static Intent create(Activity activity, Conversation conversation) {
 41		final Intent intent = new Intent(activity, ChooseContactActivity.class);
 42		List<String> contacts = new ArrayList<>();
 43		if (conversation.getMode() == Conversation.MODE_MULTI) {
 44			for (MucOptions.User user : conversation.getMucOptions().getUsers(false)) {
 45				Jid jid = user.getRealJid();
 46				if (jid != null) {
 47					contacts.add(jid.asBareJid().toString());
 48				}
 49			}
 50		} else {
 51			contacts.add(conversation.getJid().asBareJid().toString());
 52		}
 53		intent.putExtra("filter_contacts", contacts.toArray(new String[contacts.size()]));
 54		intent.putExtra("conversation", conversation.getUuid());
 55		intent.putExtra("multiple", true);
 56		intent.putExtra("show_enter_jid", true);
 57		intent.putExtra(EXTRA_ACCOUNT, conversation.getAccount().getJid().asBareJid().toString());
 58		return intent;
 59	}
 60
 61	@Override
 62	public void onCreate(final Bundle savedInstanceState) {
 63		super.onCreate(savedInstanceState);
 64		filterContacts = new HashSet<>();
 65		String[] contacts = getIntent().getStringArrayExtra("filter_contacts");
 66		if (contacts != null) {
 67			Collections.addAll(filterContacts, contacts);
 68		}
 69
 70		if (getIntent().getBooleanExtra("multiple", false)) {
 71			getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
 72			getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() {
 73
 74				@Override
 75				public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
 76					return false;
 77				}
 78
 79				@Override
 80				public boolean onCreateActionMode(ActionMode mode, Menu menu) {
 81					final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
 82					imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
 83					MenuInflater inflater = getMenuInflater();
 84					inflater.inflate(R.menu.select_multiple, menu);
 85					selected = new HashSet<>();
 86					return true;
 87				}
 88
 89				@Override
 90				public void onDestroyActionMode(ActionMode mode) {
 91				}
 92
 93				@Override
 94				public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
 95					switch (item.getItemId()) {
 96						case R.id.selection_submit:
 97							final Intent request = getIntent();
 98							final Intent data = new Intent();
 99							data.putExtra("conversation",
100									request.getStringExtra("conversation"));
101							String[] selection = getSelectedContactJids();
102							data.putExtra("contacts", selection);
103							data.putExtra("multiple", true);
104							data.putExtra(EXTRA_ACCOUNT, request.getStringExtra(EXTRA_ACCOUNT));
105							data.putExtra("subject", request.getStringExtra("subject"));
106							setResult(RESULT_OK, data);
107							finish();
108							return true;
109					}
110					return false;
111				}
112
113				@Override
114				public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
115					Contact item = (Contact) getListItems().get(position);
116					if (checked) {
117						selected.add(item);
118					} else {
119						selected.remove(item);
120					}
121					int numSelected = selected.size();
122					MenuItem selectButton = mode.getMenu().findItem(R.id.selection_submit);
123					String buttonText = getResources().getQuantityString(R.plurals.select_contact,
124							numSelected, numSelected);
125					selectButton.setTitle(buttonText);
126				}
127			});
128		}
129
130		getListView().setOnItemClickListener((parent, view, position, id) -> {
131			final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
132			imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
133			final Intent request = getIntent();
134			final Intent data = new Intent();
135			final ListItem mListItem = getListItems().get(position);
136			data.putExtra("contact", mListItem.getJid().toString());
137			String account = request.getStringExtra(EXTRA_ACCOUNT);
138			if (account == null && mListItem instanceof Contact) {
139				account = ((Contact) mListItem).getAccount().getJid().asBareJid().toString();
140			}
141			data.putExtra(EXTRA_ACCOUNT, account);
142			data.putExtra("conversation", request.getStringExtra("conversation"));
143			data.putExtra("multiple", false);
144			data.putExtra("subject", request.getStringExtra("subject"));
145			setResult(RESULT_OK, data);
146			finish();
147		});
148		final Intent i = getIntent();
149		boolean showEnterJid = i != null && i.getBooleanExtra("show_enter_jid", false);
150		if (showEnterJid) {
151			this.binding.fab.setOnClickListener((v) -> showEnterJidDialog());
152		} else {
153			this.binding.fab.setVisibility(View.GONE);
154		}
155	}
156
157	@Override
158	public void onStart() {
159		super.onStart();
160		Intent intent = getIntent();
161		@StringRes
162		int res = intent != null ? intent.getIntExtra(EXTRA_TITLE_RES_ID, R.string.title_activity_choose_contact) : R.string.title_activity_choose_contact;
163		ActionBar bar = getSupportActionBar();
164		if (bar != null) {
165			try {
166				bar.setTitle(res);
167			} catch (Exception e) {
168				bar.setTitle(R.string.title_activity_choose_contact);
169			}
170		}
171	}
172
173	@Override
174	public boolean onCreateOptionsMenu(final Menu menu) {
175		super.onCreateOptionsMenu(menu);
176		final Intent i = getIntent();
177		boolean showEnterJid = i != null && i.getBooleanExtra("show_enter_jid", false);
178		menu.findItem(R.id.action_scan_qr_code).setVisible(showEnterJid);
179		return true;
180	}
181
182	protected void filterContacts(final String needle) {
183		getListItems().clear();
184		if (xmppConnectionService == null) {
185			getListItemAdapter().notifyDataSetChanged();
186			return;
187		}
188		for (final Account account : xmppConnectionService.getAccounts()) {
189			if (account.getStatus() != Account.State.DISABLED) {
190				for (final Contact contact : account.getRoster().getContacts()) {
191					if (contact.showInRoster() &&
192							!filterContacts.contains(contact.getJid().asBareJid().toString())
193							&& contact.match(this, needle)) {
194						getListItems().add(contact);
195					}
196				}
197			}
198		}
199		Collections.sort(getListItems());
200		getListItemAdapter().notifyDataSetChanged();
201	}
202
203	private String[] getSelectedContactJids() {
204		List<String> result = new ArrayList<>();
205		for (Contact contact : selected) {
206			result.add(contact.getJid().toString());
207		}
208		return result.toArray(new String[result.size()]);
209	}
210
211	public void refreshUiReal() {
212		//nothing to do. This Activity doesn't implement any listeners
213	}
214
215	@Override
216	public boolean onOptionsItemSelected(MenuItem item) {
217		switch (item.getItemId()) {
218			case R.id.action_scan_qr_code:
219				ScanActivity.scan(this);
220				return true;
221		}
222		return super.onOptionsItemSelected(item);
223	}
224
225	protected void showEnterJidDialog() {
226		EnterJidDialog dialog = new EnterJidDialog(
227				this, mKnownHosts, mActivatedAccounts,
228				getString(R.string.enter_contact), getString(R.string.select),
229				null, getIntent().getStringExtra(EXTRA_ACCOUNT), true
230		);
231
232		dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid) -> {
233			final Intent request = getIntent();
234			final Intent data = new Intent();
235			data.putExtra("contact", contactJid.toString());
236			data.putExtra(EXTRA_ACCOUNT, accountJid.toString());
237			data.putExtra("conversation",
238					request.getStringExtra("conversation"));
239			data.putExtra("multiple", false);
240			data.putExtra("subject", request.getStringExtra("subject"));
241			setResult(RESULT_OK, data);
242			finish();
243
244			return true;
245		});
246
247		dialog.show();
248	}
249
250	@Override
251	void onBackendConnected() {
252		filterContacts();
253		this.mActivatedAccounts.clear();
254		for (Account account : xmppConnectionService.getAccounts()) {
255			if (account.getStatus() != Account.State.DISABLED) {
256				if (Config.DOMAIN_LOCK != null) {
257					this.mActivatedAccounts.add(account.getJid().getLocal());
258				} else {
259					this.mActivatedAccounts.add(account.getJid().asBareJid().toString());
260				}
261			}
262		}
263		this.mKnownHosts = xmppConnectionService.getKnownHosts();
264	}
265}