NewConversationActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import java.io.UnsupportedEncodingException;
  4import java.net.URLDecoder;
  5import java.util.ArrayList;
  6import java.util.Collections;
  7import java.util.Comparator;
  8import java.util.List;
  9
 10import eu.siacs.conversations.R;
 11import eu.siacs.conversations.entities.Account;
 12import eu.siacs.conversations.entities.Contact;
 13import eu.siacs.conversations.entities.Conversation;
 14import eu.siacs.conversations.utils.UIHelper;
 15import eu.siacs.conversations.utils.Validator;
 16import android.os.Bundle;
 17import android.text.Editable;
 18import android.text.TextWatcher;
 19import android.view.LayoutInflater;
 20import android.view.Menu;
 21import android.view.MenuItem;
 22import android.view.View;
 23import android.view.ViewGroup;
 24import android.widget.AdapterView;
 25import android.widget.AdapterView.OnItemClickListener;
 26import android.widget.AdapterView.OnItemLongClickListener;
 27import android.widget.ArrayAdapter;
 28import android.widget.EditText;
 29import android.widget.ListView;
 30import android.widget.ProgressBar;
 31import android.widget.TextView;
 32import android.widget.ImageView;
 33import android.annotation.SuppressLint;
 34import android.app.Activity;
 35import android.app.AlertDialog;
 36import android.content.Context;
 37import android.content.DialogInterface;
 38import android.content.DialogInterface.OnClickListener;
 39import android.content.Intent;
 40
 41public class NewConversationActivity extends XmppActivity {
 42
 43	protected List<Contact> rosterContacts = new ArrayList<Contact>();
 44	protected List<Contact> aggregatedContacts = new ArrayList<Contact>();
 45	protected ListView contactsView;
 46	protected ArrayAdapter<Contact> contactsAdapter;
 47
 48	protected EditText search;
 49	protected String searchString = "";
 50	private TextView contactsHeader;
 51	private List<Account> accounts;
 52
 53	protected void updateAggregatedContacts() {
 54
 55		aggregatedContacts.clear();
 56		for (Contact contact : rosterContacts) {
 57			if (contact.match(searchString))
 58				aggregatedContacts.add(contact);
 59		}
 60
 61		Collections.sort(aggregatedContacts, new Comparator<Contact>() {
 62
 63			@SuppressLint("DefaultLocale")
 64			@Override
 65			public int compare(Contact lhs, Contact rhs) {
 66				return lhs.getDisplayName().toLowerCase()
 67						.compareTo(rhs.getDisplayName().toLowerCase());
 68			}
 69		});
 70
 71		if (aggregatedContacts.size() == 0) {
 72
 73			if (Validator.isValidJid(searchString)) {
 74				String name = searchString.split("@")[0];
 75				Contact newContact = new Contact(null, name, searchString, null);
 76				newContact.flagAsNotInRoster();
 77				aggregatedContacts.add(newContact);
 78				contactsHeader.setText("Create new contact");
 79			} else {
 80				contactsHeader.setText("Contacts");
 81			}
 82		} else {
 83			contactsHeader.setText("Contacts");
 84		}
 85
 86		contactsAdapter.notifyDataSetChanged();
 87		contactsView.setScrollX(0);
 88	}
 89
 90	@Override
 91	protected void onCreate(Bundle savedInstanceState) {
 92
 93		super.onCreate(savedInstanceState);
 94
 95		setContentView(R.layout.activity_new_conversation);
 96
 97		contactsHeader = (TextView) findViewById(R.id.contacts_header);
 98
 99		search = (EditText) findViewById(R.id.new_conversation_search);
100		search.addTextChangedListener(new TextWatcher() {
101
102			@Override
103			public void onTextChanged(CharSequence s, int start, int before,
104					int count) {
105				searchString = search.getText().toString();
106				updateAggregatedContacts();
107			}
108
109			@Override
110			public void afterTextChanged(Editable s) {
111				// TODO Auto-generated method stub
112
113			}
114
115			@Override
116			public void beforeTextChanged(CharSequence s, int start, int count,
117					int after) {
118				// TODO Auto-generated method stub
119
120			}
121		});
122
123		contactsView = (ListView) findViewById(R.id.contactList);
124		contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(),
125				R.layout.contact, aggregatedContacts) {
126			@Override
127			public View getView(int position, View view, ViewGroup parent) {
128				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
129				Contact contact = getItem(position);
130				if (view == null) {
131					view = (View) inflater.inflate(R.layout.contact, null);
132				}
133
134				((TextView) view.findViewById(R.id.contact_display_name))
135						.setText(getItem(position).getDisplayName());
136				TextView contactJid = (TextView) view
137						.findViewById(R.id.contact_jid);
138				contactJid.setText(contact.getJid());
139				ImageView imageView = (ImageView) view
140						.findViewById(R.id.contact_photo);
141					imageView.setImageBitmap(UIHelper.getContactPicture(contact,null,90,this.getContext()));
142				return view;
143			}
144		};
145		contactsView.setAdapter(contactsAdapter);
146		final Activity activity = this;
147		contactsView.setOnItemClickListener(new OnItemClickListener() {
148
149			@Override
150			public void onItemClick(AdapterView<?> arg0, final View view,
151					int pos, long arg3) {
152				final Contact clickedContact = aggregatedContacts.get(pos);
153				
154				if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) {
155					getAccountChooser(new OnClickListener() {
156
157						@Override
158						public void onClick(DialogInterface dialog, int which) {
159							clickedContact.setAccount(accounts.get(which));
160							showIsMucDialogIfNeeded(clickedContact);
161						}
162						}).show();
163				} else {
164					if (clickedContact.getAccount()==null) {
165						clickedContact.setAccount(accounts.get(0));
166					}
167					showIsMucDialogIfNeeded(clickedContact);
168				}
169			}
170		});
171		contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
172
173			@Override
174			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
175					int pos, long arg3) {
176				Intent intent = new Intent(activity,ContactDetailsActivity.class);
177				intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
178				intent.putExtra("uuid", aggregatedContacts.get(pos).getUuid());
179				startActivity(intent);
180				return true;
181			}
182		});
183	}
184	
185	protected AlertDialog getAccountChooser(OnClickListener listener) {
186		String[] accountList = new String[accounts.size()];
187		for (int i = 0; i < accounts.size(); ++i) {
188		accountList[i] = accounts.get(i).getJid();
189		}
190
191		AlertDialog.Builder accountChooser = new AlertDialog.Builder(
192		this);
193		accountChooser.setTitle("Choose account");
194		accountChooser.setItems(accountList, listener);
195		return accountChooser.create();
196	}
197	
198	public void showIsMucDialogIfNeeded(final Contact clickedContact) {
199		if (clickedContact.couldBeMuc()) {
200			AlertDialog.Builder dialog = new AlertDialog.Builder(this);
201			dialog.setTitle("Multi User Conference");
202			dialog.setMessage("Are you trying to join a conference?");
203			dialog.setPositiveButton("Yes", new OnClickListener() {
204				
205				@Override
206				public void onClick(DialogInterface dialog, int which) {
207					startConversation(clickedContact, clickedContact.getAccount(),true);
208				}
209			});
210			dialog.setNegativeButton("No", new OnClickListener() {
211				
212				@Override
213				public void onClick(DialogInterface dialog, int which) {
214					startConversation(clickedContact, clickedContact.getAccount(),false);
215				}
216			});
217			dialog.create().show();
218		} else {
219			startConversation(clickedContact, clickedContact.getAccount(),false);
220		}
221	}
222
223	public void startConversation(Contact contact, Account account, boolean muc) {
224		if (!contact.isInRoster()) {
225			xmppConnectionService.createContact(contact);
226		}
227		Conversation conversation = xmppConnectionService
228				.findOrCreateConversation(account, contact.getJid(), muc);
229
230		switchToConversation(conversation,null);
231	}
232
233	@Override
234	void onBackendConnected() {
235		this.accounts = xmppConnectionService.getAccounts();
236		if (Intent.ACTION_SENDTO.equals(getIntent().getAction())) {
237			getActionBar().setDisplayHomeAsUpEnabled(false);
238			getActionBar().setHomeButtonEnabled(false);
239			String jid;
240			try {
241				jid = URLDecoder.decode(getIntent().getData().getEncodedPath(),"UTF-8").split("/")[1];
242			} catch (UnsupportedEncodingException e) {
243				jid = null;
244			}
245			if (jid!=null) {
246				final String finalJid = jid;
247				if (this.accounts.size() > 1) {
248					getAccountChooser(new OnClickListener() {
249						
250						@Override
251						public void onClick(DialogInterface dialog, int which) {
252							Conversation conversation = xmppConnectionService.findOrCreateConversation(accounts.get(which), finalJid, false);
253							switchToConversation(conversation,null);
254							finish();
255						}
256					}).show();
257				} else {
258					Conversation conversation = xmppConnectionService.findOrCreateConversation(this.accounts.get(0), jid, false);
259					switchToConversation(conversation,null);
260					finish();
261				}
262			}
263		}
264		
265		
266		if (xmppConnectionService.getConversationCount() == 0) {
267			getActionBar().setDisplayHomeAsUpEnabled(false);
268			getActionBar().setHomeButtonEnabled(false);
269		}
270		this.rosterContacts.clear();
271		for (int i = 0; i < accounts.size(); ++i) {
272			rosterContacts.addAll(xmppConnectionService.getRoster(accounts.get(i)));
273		}
274		updateAggregatedContacts();
275	}
276
277	@Override
278	public boolean onCreateOptionsMenu(Menu menu) {
279		// Inflate the menu; this adds items to the action bar if it is present.
280		getMenuInflater().inflate(R.menu.newconversation, menu);
281		return true;
282	}
283
284	@Override
285	public boolean onOptionsItemSelected(MenuItem item) {
286		switch (item.getItemId()) {
287		case R.id.action_refresh_contacts:
288			refreshContacts();
289			break;
290		default:
291			break;
292		}
293		return super.onOptionsItemSelected(item);
294	}
295
296	private void refreshContacts() {
297		final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1);
298		final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search);
299		final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header);
300		final ListView contactList = (ListView) findViewById(R.id.contactList);
301		searchBar.setVisibility(View.GONE);
302		contactsHeader.setVisibility(View.GONE);
303		contactList.setVisibility(View.GONE);
304		progress.setVisibility(View.VISIBLE);
305		this.accounts = xmppConnectionService.getAccounts();
306		this.rosterContacts.clear();
307		for (int i = 0; i < accounts.size(); ++i) {
308			if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
309				xmppConnectionService.updateRoster(accounts.get(i),
310						new OnRosterFetchedListener() {
311
312							@Override
313							public void onRosterFetched(
314									final List<Contact> roster) {
315								runOnUiThread(new Runnable() {
316
317									@Override
318									public void run() {
319										rosterContacts.addAll(roster);
320										progress.setVisibility(View.GONE);
321										searchBar.setVisibility(View.VISIBLE);
322										contactList.setVisibility(View.VISIBLE);
323										contactList.setVisibility(View.VISIBLE);
324										updateAggregatedContacts();
325									}
326								});
327							}
328						});
329			}
330		}
331	}
332}