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				newContact.flagAsNotInRoster();
 83				aggregatedContacts.add(newContact);
 84				contactsHeader.setText("Create new contact");
 85			} else {
 86				contactsHeader.setText("Contacts");
 87			}
 88		} else {
 89			contactsHeader.setText("Contacts");
 90		}
 91
 92		contactsAdapter.notifyDataSetChanged();
 93		contactsView.setScrollX(0);
 94	}
 95
 96	@Override
 97	protected void onCreate(Bundle savedInstanceState) {
 98
 99		super.onCreate(savedInstanceState);
100
101		setContentView(R.layout.activity_new_conversation);
102
103		contactsHeader = (TextView) findViewById(R.id.contacts_header);
104
105		search = (EditText) findViewById(R.id.new_conversation_search);
106		search.addTextChangedListener(new TextWatcher() {
107
108			@Override
109			public void onTextChanged(CharSequence s, int start, int before,
110					int count) {
111				searchString = search.getText().toString();
112				updateAggregatedContacts();
113			}
114
115			@Override
116			public void afterTextChanged(Editable s) {
117				// TODO Auto-generated method stub
118
119			}
120
121			@Override
122			public void beforeTextChanged(CharSequence s, int start, int count,
123					int after) {
124				// TODO Auto-generated method stub
125
126			}
127		});
128
129		contactsView = (ListView) findViewById(R.id.contactList);
130		contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(),
131				R.layout.contact, aggregatedContacts) {
132			@Override
133			public View getView(int position, View view, ViewGroup parent) {
134				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
135				Contact contact = getItem(position);
136				if (view == null) {
137					view = (View) inflater.inflate(R.layout.contact, null);
138				}
139
140				((TextView) view.findViewById(R.id.contact_display_name))
141						.setText(getItem(position).getDisplayName());
142				TextView contactJid = (TextView) view
143						.findViewById(R.id.contact_jid);
144				contactJid.setText(contact.getJid());
145				String profilePhoto = getItem(position).getProfilePhoto();
146				ImageView imageView = (ImageView) view
147						.findViewById(R.id.contact_photo);
148				if (profilePhoto != null) {
149					imageView.setImageURI(Uri.parse(profilePhoto));
150				} else {
151					imageView.setImageBitmap(UIHelper.getUnknownContactPicture(
152							getItem(position).getDisplayName(), 90));
153				}
154				return view;
155			}
156		};
157		contactsView.setAdapter(contactsAdapter);
158		final Activity activity = this;
159		contactsView.setOnItemClickListener(new OnItemClickListener() {
160
161			@Override
162			public void onItemClick(AdapterView<?> arg0, final View view,
163					int pos, long arg3) {
164				final Contact clickedContact = aggregatedContacts.get(pos);
165				
166				if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) {
167					String[] accountList = new String[accounts.size()];
168					for (int i = 0; i < accounts.size(); ++i) {
169					accountList[i] = accounts.get(i).getJid();
170					}
171
172					AlertDialog.Builder accountChooser = new AlertDialog.Builder(
173					activity);
174					accountChooser.setTitle("Choose account");
175					accountChooser.setItems(accountList, new OnClickListener() {
176
177					@Override
178					public void onClick(DialogInterface dialog, int which) {
179						clickedContact.setAccount(accounts.get(which));
180						showIsMucDialogIfNeeded(clickedContact);
181					}
182					});
183					accountChooser.create().show();
184				} else {
185					if (clickedContact.getAccount()==null) {
186						clickedContact.setAccount(accounts.get(0));
187					}
188					showIsMucDialogIfNeeded(clickedContact);
189				}
190			}
191		});
192		contactsView.setOnItemLongClickListener(new OnItemLongClickListener() {
193
194			@Override
195			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
196					int pos, long arg3) {
197				Contact clickedContact = aggregatedContacts.get(pos);
198				DialogContactDetails dialog = new DialogContactDetails();
199				dialog.setContact(clickedContact);
200				dialog.show(getFragmentManager(), "details");
201				return true;
202			}
203		});
204	}
205	
206	public void showIsMucDialogIfNeeded(final Contact clickedContact) {
207		if (clickedContact.couldBeMuc()) {
208			AlertDialog.Builder dialog = new AlertDialog.Builder(this);
209			dialog.setTitle("Multi User Conference");
210			dialog.setMessage("Are you trying to join a conference?");
211			dialog.setPositiveButton("Yes", new OnClickListener() {
212				
213				@Override
214				public void onClick(DialogInterface dialog, int which) {
215					startConversation(clickedContact, clickedContact.getAccount(),true);
216				}
217			});
218			dialog.setNegativeButton("No", new OnClickListener() {
219				
220				@Override
221				public void onClick(DialogInterface dialog, int which) {
222					startConversation(clickedContact, clickedContact.getAccount(),false);
223				}
224			});
225			dialog.create().show();
226		} else {
227			startConversation(clickedContact, clickedContact.getAccount(),false);
228		}
229	}
230
231	public void startConversation(Contact contact, Account account, boolean muc) {
232		if (!contact.isInRoster()) {
233			xmppConnectionService.createContact(contact);
234		}
235		Conversation conversation = xmppConnectionService
236				.findOrCreateConversation(account, contact.getJid(), muc);
237
238		Intent viewConversationIntent = new Intent(this,
239				ConversationActivity.class);
240		viewConversationIntent.setAction(Intent.ACTION_VIEW);
241		viewConversationIntent.putExtra(ConversationActivity.CONVERSATION,
242				conversation.getUuid());
243		viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION);
244		viewConversationIntent.setFlags(viewConversationIntent.getFlags()
245				| Intent.FLAG_ACTIVITY_CLEAR_TOP);
246		startActivity(viewConversationIntent);
247	}
248
249	@Override
250	void onBackendConnected() {
251		if (xmppConnectionService.getConversationCount() == 0) {
252			getActionBar().setDisplayHomeAsUpEnabled(false);
253			getActionBar().setHomeButtonEnabled(false);
254		}
255		this.accounts = xmppConnectionService.getAccounts();
256		this.rosterContacts.clear();
257		for (int i = 0; i < accounts.size(); ++i) {
258				xmppConnectionService.getRoster(accounts.get(i),
259						new OnRosterFetchedListener() {
260
261							@Override
262							public void onRosterFetched(List<Contact> roster) {
263								rosterContacts.addAll(roster);
264								runOnUiThread(new Runnable() {
265
266									@Override
267									public void run() {
268										updateAggregatedContacts();
269									}
270								});
271
272							}
273						});
274			}
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_settings:
288			startActivity(new Intent(this, SettingsActivity.class));
289			break;
290		case R.id.action_accounts:
291			startActivity(new Intent(this, ManageAccountActivity.class));
292			break;
293		case R.id.action_refresh_contacts:
294			refreshContacts();
295			break;
296		default:
297			break;
298		}
299		return super.onOptionsItemSelected(item);
300	}
301
302	private void refreshContacts() {
303		final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1);
304		final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search);
305		final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header);
306		final ListView contactList = (ListView) findViewById(R.id.contactList);
307		searchBar.setVisibility(View.GONE);
308		contactsHeader.setVisibility(View.GONE);
309		contactList.setVisibility(View.GONE);
310		progress.setVisibility(View.VISIBLE);
311		this.accounts = xmppConnectionService.getAccounts();
312		this.rosterContacts.clear();
313		for (int i = 0; i < accounts.size(); ++i) {
314			if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) {
315				xmppConnectionService.updateRoster(accounts.get(i),
316						new OnRosterFetchedListener() {
317
318							@Override
319							public void onRosterFetched(
320									final List<Contact> roster) {
321								runOnUiThread(new Runnable() {
322
323									@Override
324									public void run() {
325										rosterContacts.addAll(roster);
326										progress.setVisibility(View.GONE);
327										searchBar.setVisibility(View.VISIBLE);
328										contactList.setVisibility(View.VISIBLE);
329										contactList.setVisibility(View.VISIBLE);
330										updateAggregatedContacts();
331									}
332								});
333							}
334						});
335			}
336		}
337	}
338}