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