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}