StartConversation.java

  1package eu.siacs.conversations.ui;
  2
  3import java.util.ArrayList;
  4import java.util.Collections;
  5import java.util.List;
  6
  7import android.app.ActionBar;
  8import android.app.ActionBar.Tab;
  9import android.app.ActionBar.TabListener;
 10import android.app.AlertDialog;
 11import android.app.Fragment;
 12import android.app.FragmentTransaction;
 13import android.app.ListFragment;
 14import android.content.Context;
 15import android.content.DialogInterface;
 16import android.database.DataSetObserver;
 17import android.graphics.Color;
 18import android.os.Bundle;
 19import android.support.v13.app.FragmentPagerAdapter;
 20import android.support.v4.view.ViewPager;
 21import android.view.ContextMenu;
 22import android.view.ContextMenu.ContextMenuInfo;
 23import android.view.LayoutInflater;
 24import android.view.Menu;
 25import android.view.MenuItem;
 26import android.view.View;
 27import android.view.ViewGroup;
 28import android.widget.AdapterView;
 29import android.widget.AdapterView.AdapterContextMenuInfo;
 30import android.widget.AdapterView.OnItemClickListener;
 31import android.widget.ArrayAdapter;
 32import android.widget.EditText;
 33import android.widget.ImageView;
 34import android.widget.ListView;
 35import android.widget.SearchView;
 36import android.widget.SpinnerAdapter;
 37import android.widget.SearchView.OnQueryTextListener;
 38import android.widget.Spinner;
 39import android.widget.TextView;
 40import eu.siacs.conversations.R;
 41import eu.siacs.conversations.entities.Account;
 42import eu.siacs.conversations.entities.Contact;
 43import eu.siacs.conversations.entities.Conversation;
 44import eu.siacs.conversations.entities.ListItem;
 45import eu.siacs.conversations.utils.UIHelper;
 46import eu.siacs.conversations.utils.Validator;
 47
 48public class StartConversation extends XmppActivity {
 49
 50	private Tab mContactsTab;
 51	private Tab mConferencesTab;
 52	private ViewPager mViewPager;
 53	private SearchView mSearchView;
 54
 55	private MyListFragment mContactsListFragment = new MyListFragment();
 56	private List<ListItem> contacts = new ArrayList<ListItem>();
 57	private ArrayAdapter<ListItem> mContactsAdapter;
 58
 59	private MyListFragment mConferenceListFragment = new MyListFragment();
 60	private List<ListItem> conferences = new ArrayList<ListItem>();
 61	private ArrayAdapter<ListItem> mConferenceAdapter;
 62	
 63	private List<String> mActivatedAccounts = new ArrayList<String>();
 64
 65	private TabListener mTabListener = new TabListener() {
 66
 67		@Override
 68		public void onTabUnselected(Tab tab, FragmentTransaction ft) {
 69			return;
 70		}
 71
 72		@Override
 73		public void onTabSelected(Tab tab, FragmentTransaction ft) {
 74			mViewPager.setCurrentItem(tab.getPosition());
 75			onTabChanged();
 76		}
 77
 78		@Override
 79		public void onTabReselected(Tab tab, FragmentTransaction ft) {
 80			return;
 81		}
 82	};
 83
 84	private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
 85		@Override
 86		public void onPageSelected(int position) {
 87			getActionBar().setSelectedNavigationItem(position);
 88			onTabChanged();
 89		}
 90	};
 91	private OnQueryTextListener mOnQueryTextListener = new OnQueryTextListener() {
 92
 93		@Override
 94		public boolean onQueryTextSubmit(String query) {
 95			return true;
 96		}
 97
 98		@Override
 99		public boolean onQueryTextChange(String newText) {
100			filterContacts(newText);
101			return true;
102		}
103	};
104
105	@Override
106	public void onCreate(Bundle savedInstanceState) {
107		super.onCreate(savedInstanceState);
108		setContentView(R.layout.activity_start_conversation);
109		mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager);
110		ActionBar actionBar = getActionBar();
111		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
112
113		mContactsTab = actionBar.newTab().setText(R.string.contacts)
114				.setTabListener(mTabListener);
115		mConferencesTab = actionBar.newTab().setText(R.string.conferences)
116				.setTabListener(mTabListener);
117		actionBar.addTab(mContactsTab);
118		actionBar.addTab(mConferencesTab);
119
120		mViewPager.setOnPageChangeListener(mOnPageChangeListener);
121		mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) {
122
123			@Override
124			public int getCount() {
125				return 2;
126			}
127
128			@Override
129			public Fragment getItem(int position) {
130				if (position == 0) {
131					return mContactsListFragment;
132				} else {
133					return mConferenceListFragment;
134				}
135			}
136		});
137
138		mConferenceAdapter = new ListItemAdapter(conferences);
139		mConferenceListFragment.setListAdapter(mConferenceAdapter);
140
141		mContactsAdapter = new ListItemAdapter(contacts);
142		mContactsListFragment.setListAdapter(mContactsAdapter);
143		mContactsListFragment
144				.setOnListItemClickListener(new OnItemClickListener() {
145
146					@Override
147					public void onItemClick(AdapterView<?> arg0, View arg1,
148							int position, long arg3) {
149						openConversationForContact(position);
150					}
151				});
152
153	}
154
155	protected void openConversationForContact(int position) {
156		Contact contact = (Contact) contacts.get(position);
157		Conversation conversation = xmppConnectionService
158				.findOrCreateConversation(contact.getAccount(),
159						contact.getJid(), false);
160		switchToConversation(conversation, null, false);
161	}
162	
163	protected void openDetailsForContact(int position) {
164		Contact contact = (Contact) contacts.get(position);
165		switchToContactDetails(contact);
166	}
167	
168	protected void deleteContact(int position) {
169		Contact contact = (Contact) contacts.get(position);
170		xmppConnectionService.deleteContactOnServer(contact);
171		filterContacts(null);
172	}
173	
174	protected void showCreateContactDialog() {
175		AlertDialog.Builder builder = new AlertDialog.Builder(this);
176		builder.setTitle(R.string.create_contact);
177		View dialogView = getLayoutInflater().inflate(R.layout.create_contact_dialog, null);
178		final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
179		final EditText jid = (EditText) dialogView.findViewById(R.id.jid);
180		populateAccountSpinner(spinner);
181		builder.setView(dialogView);
182		builder.setNegativeButton(R.string.cancel, null);
183		builder.setPositiveButton(R.string.create, null);
184		final AlertDialog dialog = builder.create();
185		dialog.show();
186		dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
187			
188			@Override
189			public void onClick(View v) {
190				if (Validator.isValidJid(jid.getText().toString())) {
191					String accountJid = (String) spinner.getSelectedItem();
192					String contactJid = jid.getText().toString();
193					Account account = xmppConnectionService.findAccountByJid(accountJid);
194					Contact contact = account.getRoster().getContact(contactJid);
195					if (contact.showInRoster()) {
196						jid.setError(getString(R.string.contact_already_exists));
197					} else {
198						xmppConnectionService.createContact(contact);
199						switchToConversation(contact);
200						dialog.dismiss();
201					}
202				} else {
203					jid.setError(getString(R.string.invalid_jid));
204				}
205			}
206		});
207		
208	}
209	
210	protected void switchToConversation(Contact contact) {
211		Conversation conversation = xmppConnectionService.findOrCreateConversation(contact.getAccount(), contact.getJid(), false);
212		switchToConversation(conversation, null, false);
213	}
214	
215	private void populateAccountSpinner(Spinner spinner) {
216		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mActivatedAccounts);
217		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
218		spinner.setAdapter(adapter);
219	}
220
221	@Override
222	public boolean onCreateOptionsMenu(Menu menu) {
223		getMenuInflater().inflate(R.menu.start_conversation, menu);
224		MenuItem menuCreateContact = (MenuItem) menu
225				.findItem(R.id.action_create_contact);
226		MenuItem menuCreateConference = (MenuItem) menu
227				.findItem(R.id.action_create_conference);
228		MenuItem menuSearch = (MenuItem) menu.findItem(R.id.action_search);
229		if (getActionBar().getSelectedNavigationIndex() == 0) {
230			menuCreateConference.setVisible(false);
231		} else {
232			menuCreateContact.setVisible(false);
233		}
234		mSearchView = (SearchView) menuSearch.getActionView();
235		int id = mSearchView.getContext().getResources()
236				.getIdentifier("android:id/search_src_text", null, null);
237		TextView textView = (TextView) mSearchView.findViewById(id);
238		textView.setTextColor(Color.WHITE);
239		mSearchView.setOnQueryTextListener(this.mOnQueryTextListener);
240		return true;
241	}
242
243	@Override
244	public boolean onOptionsItemSelected(MenuItem item) {
245		switch (item.getItemId()) {
246		case R.id.action_create_contact:
247			showCreateContactDialog();
248			break;
249		}
250		return super.onOptionsItemSelected(item);
251	}
252
253	@Override
254	void onBackendConnected() {
255		filterContacts(null);
256		this.mActivatedAccounts.clear();
257		for (Account account : xmppConnectionService.getAccounts()) {
258			if (account.getStatus() != Account.STATUS_DISABLED) {
259				this.mActivatedAccounts.add(account.getJid());
260			}
261		}
262	}
263
264	protected void filterContacts(String needle) {
265		this.contacts.clear();
266		for (Account account : xmppConnectionService.getAccounts()) {
267			if (account.getStatus() != Account.STATUS_DISABLED) {
268				for (Contact contact : account.getRoster().getContacts()) {
269					if (contact.showInRoster() && contact.match(needle)) {
270						this.contacts.add(contact);
271					}
272				}
273			}
274		}
275		Collections.sort(this.contacts);
276		mContactsAdapter.notifyDataSetChanged();
277	}
278
279	private void onTabChanged() {
280		invalidateOptionsMenu();
281	}
282
283	private class ListItemAdapter extends ArrayAdapter<ListItem> {
284
285		public ListItemAdapter(List<ListItem> objects) {
286			super(getApplicationContext(), 0, objects);
287		}
288
289		@Override
290		public View getView(int position, View view, ViewGroup parent) {
291			LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
292			ListItem item = getItem(position);
293			if (view == null) {
294				view = (View) inflater.inflate(R.layout.contact, null);
295			}
296			TextView name = (TextView) view
297					.findViewById(R.id.contact_display_name);
298			TextView jid = (TextView) view.findViewById(R.id.contact_jid);
299			ImageView picture = (ImageView) view
300					.findViewById(R.id.contact_photo);
301
302			jid.setText(item.getJid());
303			name.setText(item.getDisplayName());
304			picture.setImageBitmap(UIHelper.getContactPicture(item, 48,
305					this.getContext(), false));
306			return view;
307		}
308
309	}
310
311	public static class MyListFragment extends ListFragment {
312		private AdapterView.OnItemClickListener mOnItemClickListener;
313		private int mContextPosition = -1;
314
315		@Override
316		public void onListItemClick(ListView l, View v, int position, long id) {
317			if (mOnItemClickListener != null) {
318				mOnItemClickListener.onItemClick(l, v, position, id);
319			}
320		}
321
322		public void setOnListItemClickListener(AdapterView.OnItemClickListener l) {
323			this.mOnItemClickListener = l;
324		}
325
326		@Override
327		public void onViewCreated(View view, Bundle savedInstanceState) {
328			super.onViewCreated(view, savedInstanceState);
329			registerForContextMenu(getListView());
330		}
331
332		@Override
333		public void onCreateContextMenu(ContextMenu menu, View v,
334				ContextMenuInfo menuInfo) {
335			super.onCreateContextMenu(menu, v, menuInfo);
336			getActivity().getMenuInflater().inflate(R.menu.contact_context,
337					menu);
338			AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
339			this.mContextPosition = acmi.position;
340		}
341
342		@Override
343		public boolean onContextItemSelected(MenuItem item) {
344			StartConversation activity = (StartConversation) getActivity();
345			switch(item.getItemId()) {
346			case R.id.context_start_conversation:
347				activity.openConversationForContact(mContextPosition);
348				break;
349			case R.id.context_contact_details:
350				activity.openDetailsForContact(mContextPosition);
351				break;
352			case R.id.context_delete_contact:
353				activity.deleteContact(mContextPosition);
354				break;
355			}
356			return true;
357		}
358	}
359}