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.graphics.Color;
 16import android.os.Bundle;
 17import android.support.v13.app.FragmentPagerAdapter;
 18import android.support.v4.view.ViewPager;
 19import android.view.ContextMenu;
 20import android.view.ContextMenu.ContextMenuInfo;
 21import android.view.LayoutInflater;
 22import android.view.Menu;
 23import android.view.MenuItem;
 24import android.view.View;
 25import android.view.ViewGroup;
 26import android.widget.AdapterView;
 27import android.widget.AdapterView.AdapterContextMenuInfo;
 28import android.widget.AdapterView.OnItemClickListener;
 29import android.widget.ArrayAdapter;
 30import android.widget.AutoCompleteTextView;
 31import android.widget.ImageView;
 32import android.widget.ListView;
 33import android.widget.SearchView;
 34import android.widget.SearchView.OnQueryTextListener;
 35import android.widget.Spinner;
 36import android.widget.TextView;
 37import eu.siacs.conversations.R;
 38import eu.siacs.conversations.entities.Account;
 39import eu.siacs.conversations.entities.Contact;
 40import eu.siacs.conversations.entities.Conversation;
 41import eu.siacs.conversations.entities.ListItem;
 42import eu.siacs.conversations.utils.KnownHostsAdapter;
 43import eu.siacs.conversations.utils.UIHelper;
 44import eu.siacs.conversations.utils.Validator;
 45
 46public class StartConversation extends XmppActivity {
 47
 48	private Tab mContactsTab;
 49	private Tab mConferencesTab;
 50	private ViewPager mViewPager;
 51	private SearchView mSearchView;
 52
 53	private MyListFragment mContactsListFragment = new MyListFragment();
 54	private List<ListItem> contacts = new ArrayList<ListItem>();
 55	private ArrayAdapter<ListItem> mContactsAdapter;
 56
 57	private MyListFragment mConferenceListFragment = new MyListFragment();
 58	private List<ListItem> conferences = new ArrayList<ListItem>();
 59	private ArrayAdapter<ListItem> mConferenceAdapter;
 60	
 61	private List<String> mActivatedAccounts = new ArrayList<String>();
 62	private List<String> mKnownHosts;
 63
 64	private TabListener mTabListener = new TabListener() {
 65
 66		@Override
 67		public void onTabUnselected(Tab tab, FragmentTransaction ft) {
 68			return;
 69		}
 70
 71		@Override
 72		public void onTabSelected(Tab tab, FragmentTransaction ft) {
 73			mViewPager.setCurrentItem(tab.getPosition());
 74			onTabChanged();
 75		}
 76
 77		@Override
 78		public void onTabReselected(Tab tab, FragmentTransaction ft) {
 79			return;
 80		}
 81	};
 82
 83	private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
 84		@Override
 85		public void onPageSelected(int position) {
 86			getActionBar().setSelectedNavigationItem(position);
 87			onTabChanged();
 88		}
 89	};
 90	private OnQueryTextListener mOnQueryTextListener = new OnQueryTextListener() {
 91
 92		@Override
 93		public boolean onQueryTextSubmit(String query) {
 94			return true;
 95		}
 96
 97		@Override
 98		public boolean onQueryTextChange(String newText) {
 99			filterContacts(newText);
100			return true;
101		}
102	};
103
104	@Override
105	public void onCreate(Bundle savedInstanceState) {
106		super.onCreate(savedInstanceState);
107		setContentView(R.layout.activity_start_conversation);
108		mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager);
109		ActionBar actionBar = getActionBar();
110		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
111
112		mContactsTab = actionBar.newTab().setText(R.string.contacts)
113				.setTabListener(mTabListener);
114		mConferencesTab = actionBar.newTab().setText(R.string.conferences)
115				.setTabListener(mTabListener);
116		actionBar.addTab(mContactsTab);
117		actionBar.addTab(mConferencesTab);
118
119		mViewPager.setOnPageChangeListener(mOnPageChangeListener);
120		mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) {
121
122			@Override
123			public int getCount() {
124				return 2;
125			}
126
127			@Override
128			public Fragment getItem(int position) {
129				if (position == 0) {
130					return mContactsListFragment;
131				} else {
132					return mConferenceListFragment;
133				}
134			}
135		});
136
137		mConferenceAdapter = new ListItemAdapter(conferences);
138		mConferenceListFragment.setListAdapter(mConferenceAdapter);
139
140		mContactsAdapter = new ListItemAdapter(contacts);
141		mContactsListFragment.setListAdapter(mContactsAdapter);
142		mContactsListFragment
143				.setOnListItemClickListener(new OnItemClickListener() {
144
145					@Override
146					public void onItemClick(AdapterView<?> arg0, View arg1,
147							int position, long arg3) {
148						openConversationForContact(position);
149					}
150				});
151
152	}
153
154	protected void openConversationForContact(int position) {
155		Contact contact = (Contact) contacts.get(position);
156		Conversation conversation = xmppConnectionService
157				.findOrCreateConversation(contact.getAccount(),
158						contact.getJid(), false);
159		switchToConversation(conversation, null, false);
160	}
161	
162	protected void openDetailsForContact(int position) {
163		Contact contact = (Contact) contacts.get(position);
164		switchToContactDetails(contact);
165	}
166	
167	protected void deleteContact(int position) {
168		Contact contact = (Contact) contacts.get(position);
169		xmppConnectionService.deleteContactOnServer(contact);
170		filterContacts(null);
171	}
172	
173	protected void showCreateContactDialog() {
174		AlertDialog.Builder builder = new AlertDialog.Builder(this);
175		builder.setTitle(R.string.create_contact);
176		View dialogView = getLayoutInflater().inflate(R.layout.create_contact_dialog, null);
177		final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
178		final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView.findViewById(R.id.jid);
179		jid.setAdapter(new KnownHostsAdapter(this, android.R.layout.simple_list_item_1, mKnownHosts));
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		this.mKnownHosts = xmppConnectionService.getKnownHosts();
263	}
264
265	protected void filterContacts(String needle) {
266		this.contacts.clear();
267		for (Account account : xmppConnectionService.getAccounts()) {
268			if (account.getStatus() != Account.STATUS_DISABLED) {
269				for (Contact contact : account.getRoster().getContacts()) {
270					if (contact.showInRoster() && contact.match(needle)) {
271						this.contacts.add(contact);
272					}
273				}
274			}
275		}
276		Collections.sort(this.contacts);
277		mContactsAdapter.notifyDataSetChanged();
278	}
279
280	private void onTabChanged() {
281		invalidateOptionsMenu();
282	}
283
284	private class ListItemAdapter extends ArrayAdapter<ListItem> {
285
286		public ListItemAdapter(List<ListItem> objects) {
287			super(getApplicationContext(), 0, objects);
288		}
289
290		@Override
291		public View getView(int position, View view, ViewGroup parent) {
292			LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
293			ListItem item = getItem(position);
294			if (view == null) {
295				view = (View) inflater.inflate(R.layout.contact, null);
296			}
297			TextView name = (TextView) view
298					.findViewById(R.id.contact_display_name);
299			TextView jid = (TextView) view.findViewById(R.id.contact_jid);
300			ImageView picture = (ImageView) view
301					.findViewById(R.id.contact_photo);
302
303			jid.setText(item.getJid());
304			name.setText(item.getDisplayName());
305			picture.setImageBitmap(UIHelper.getContactPicture(item, 48,
306					this.getContext(), false));
307			return view;
308		}
309
310	}
311
312	public static class MyListFragment extends ListFragment {
313		private AdapterView.OnItemClickListener mOnItemClickListener;
314		private int mContextPosition = -1;
315
316		@Override
317		public void onListItemClick(ListView l, View v, int position, long id) {
318			if (mOnItemClickListener != null) {
319				mOnItemClickListener.onItemClick(l, v, position, id);
320			}
321		}
322
323		public void setOnListItemClickListener(AdapterView.OnItemClickListener l) {
324			this.mOnItemClickListener = l;
325		}
326
327		@Override
328		public void onViewCreated(View view, Bundle savedInstanceState) {
329			super.onViewCreated(view, savedInstanceState);
330			registerForContextMenu(getListView());
331		}
332
333		@Override
334		public void onCreateContextMenu(ContextMenu menu, View v,
335				ContextMenuInfo menuInfo) {
336			super.onCreateContextMenu(menu, v, menuInfo);
337			getActivity().getMenuInflater().inflate(R.menu.contact_context,
338					menu);
339			AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
340			this.mContextPosition = acmi.position;
341		}
342
343		@Override
344		public boolean onContextItemSelected(MenuItem item) {
345			StartConversation activity = (StartConversation) getActivity();
346			switch(item.getItemId()) {
347			case R.id.context_start_conversation:
348				activity.openConversationForContact(mContextPosition);
349				break;
350			case R.id.context_contact_details:
351				activity.openDetailsForContact(mContextPosition);
352				break;
353			case R.id.context_delete_contact:
354				activity.deleteContact(mContextPosition);
355				break;
356			}
357			return true;
358		}
359	}
360}