NewConversationActivity.java

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