1package eu.siacs.conversations.ui;
2
3import android.annotation.SuppressLint;
4import android.app.ActionBar;
5import android.app.ActionBar.Tab;
6import android.app.ActionBar.TabListener;
7import android.app.AlertDialog;
8import android.app.Fragment;
9import android.app.FragmentTransaction;
10import android.app.ListFragment;
11import android.content.Context;
12import android.content.DialogInterface;
13import android.content.DialogInterface.OnClickListener;
14import android.content.Intent;
15import android.net.Uri;
16import android.nfc.NdefMessage;
17import android.nfc.NdefRecord;
18import android.nfc.NfcAdapter;
19import android.os.Build;
20import android.os.Bundle;
21import android.os.Parcelable;
22import android.support.v13.app.FragmentPagerAdapter;
23import android.support.v4.view.ViewPager;
24import android.text.Editable;
25import android.text.TextWatcher;
26import android.util.Log;
27import android.view.ContextMenu;
28import android.view.ContextMenu.ContextMenuInfo;
29import android.view.KeyEvent;
30import android.view.Menu;
31import android.view.MenuItem;
32import android.view.View;
33import android.view.inputmethod.InputMethodManager;
34import android.widget.AdapterView;
35import android.widget.AdapterView.AdapterContextMenuInfo;
36import android.widget.AdapterView.OnItemClickListener;
37import android.widget.ArrayAdapter;
38import android.widget.AutoCompleteTextView;
39import android.widget.CheckBox;
40import android.widget.EditText;
41import android.widget.ListView;
42import android.widget.Spinner;
43
44import com.google.zxing.integration.android.IntentIntegrator;
45import com.google.zxing.integration.android.IntentResult;
46
47import java.io.UnsupportedEncodingException;
48import java.net.URLDecoder;
49import java.util.ArrayList;
50import java.util.Arrays;
51import java.util.Collections;
52import java.util.List;
53
54import eu.siacs.conversations.Config;
55import eu.siacs.conversations.R;
56import eu.siacs.conversations.entities.Account;
57import eu.siacs.conversations.entities.Bookmark;
58import eu.siacs.conversations.entities.Contact;
59import eu.siacs.conversations.entities.Conversation;
60import eu.siacs.conversations.entities.ListItem;
61import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
62import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
63import eu.siacs.conversations.ui.adapter.ListItemAdapter;
64import eu.siacs.conversations.utils.Validator;
65
66public class StartConversationActivity extends XmppActivity {
67
68 private Tab mContactsTab;
69 private Tab mConferencesTab;
70 private ViewPager mViewPager;
71
72 private MyListFragment mContactsListFragment = new MyListFragment();
73 private List<ListItem> contacts = new ArrayList<ListItem>();
74 private ArrayAdapter<ListItem> mContactsAdapter;
75
76 private MyListFragment mConferenceListFragment = new MyListFragment();
77 private List<ListItem> conferences = new ArrayList<ListItem>();
78 private ArrayAdapter<ListItem> mConferenceAdapter;
79
80 private List<String> mActivatedAccounts = new ArrayList<String>();
81 private List<String> mKnownHosts;
82 private List<String> mKnownConferenceHosts;
83
84 private Invite mPendingInvite = null;
85
86 private Menu mOptionsMenu;
87 private EditText mSearchEditText;
88
89 public int conference_context_id;
90 public int contact_context_id;
91
92 private TabListener mTabListener = new TabListener() {
93
94 @Override
95 public void onTabUnselected(Tab tab, FragmentTransaction ft) {
96 return;
97 }
98
99 @Override
100 public void onTabSelected(Tab tab, FragmentTransaction ft) {
101 mViewPager.setCurrentItem(tab.getPosition());
102 onTabChanged();
103 }
104
105 @Override
106 public void onTabReselected(Tab tab, FragmentTransaction ft) {
107 return;
108 }
109 };
110
111 private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
112 @Override
113 public void onPageSelected(int position) {
114 getActionBar().setSelectedNavigationItem(position);
115 onTabChanged();
116 }
117 };
118
119 private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
120
121 @Override
122 public boolean onMenuItemActionExpand(MenuItem item) {
123 mSearchEditText.post(new Runnable() {
124
125 @Override
126 public void run() {
127 mSearchEditText.requestFocus();
128 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
129 imm.showSoftInput(mSearchEditText,
130 InputMethodManager.SHOW_IMPLICIT);
131 }
132 });
133
134 return true;
135 }
136
137 @Override
138 public boolean onMenuItemActionCollapse(MenuItem item) {
139 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
140 imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(),
141 InputMethodManager.HIDE_IMPLICIT_ONLY);
142 mSearchEditText.setText("");
143 filter(null);
144 return true;
145 }
146 };
147 private TextWatcher mSearchTextWatcher = new TextWatcher() {
148
149 @Override
150 public void afterTextChanged(Editable editable) {
151 filter(editable.toString());
152 }
153
154 @Override
155 public void beforeTextChanged(CharSequence s, int start, int count,
156 int after) {
157 }
158
159 @Override
160 public void onTextChanged(CharSequence s, int start, int before,
161 int count) {
162 }
163 };
164 private OnRosterUpdate onRosterUpdate = new OnRosterUpdate() {
165
166 @Override
167 public void onRosterUpdate() {
168 runOnUiThread(new Runnable() {
169
170 @Override
171 public void run() {
172 if (mSearchEditText != null) {
173 filter(mSearchEditText.getText().toString());
174 }
175 }
176 });
177 }
178 };
179 private MenuItem mMenuSearchView;
180 private String mInitialJid;
181
182 @Override
183 public void onCreate(Bundle savedInstanceState) {
184 super.onCreate(savedInstanceState);
185 setContentView(R.layout.activity_start_conversation);
186 mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager);
187 ActionBar actionBar = getActionBar();
188 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
189
190 mContactsTab = actionBar.newTab().setText(R.string.contacts)
191 .setTabListener(mTabListener);
192 mConferencesTab = actionBar.newTab().setText(R.string.conferences)
193 .setTabListener(mTabListener);
194 actionBar.addTab(mContactsTab);
195 actionBar.addTab(mConferencesTab);
196
197 mViewPager.setOnPageChangeListener(mOnPageChangeListener);
198 mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) {
199
200 @Override
201 public int getCount() {
202 return 2;
203 }
204
205 @Override
206 public Fragment getItem(int position) {
207 if (position == 0) {
208 return mContactsListFragment;
209 } else {
210 return mConferenceListFragment;
211 }
212 }
213 });
214
215 mConferenceAdapter = new ListItemAdapter(this, conferences);
216 mConferenceListFragment.setListAdapter(mConferenceAdapter);
217 mConferenceListFragment.setContextMenu(R.menu.conference_context);
218 mConferenceListFragment
219 .setOnListItemClickListener(new OnItemClickListener() {
220
221 @Override
222 public void onItemClick(AdapterView<?> arg0, View arg1,
223 int position, long arg3) {
224 openConversationForBookmark(position);
225 }
226 });
227
228 mContactsAdapter = new ListItemAdapter(this, contacts);
229 mContactsListFragment.setListAdapter(mContactsAdapter);
230 mContactsListFragment.setContextMenu(R.menu.contact_context);
231 mContactsListFragment
232 .setOnListItemClickListener(new OnItemClickListener() {
233
234 @Override
235 public void onItemClick(AdapterView<?> arg0, View arg1,
236 int position, long arg3) {
237 openConversationForContact(position);
238 }
239 });
240
241 }
242
243 @Override
244 public void onStop() {
245 super.onStop();
246 xmppConnectionService.removeOnRosterUpdateListener();
247 }
248
249 protected void openConversationForContact(int position) {
250 Contact contact = (Contact) contacts.get(position);
251 Conversation conversation = xmppConnectionService
252 .findOrCreateConversation(contact.getAccount(),
253 contact.getJid(), false);
254 switchToConversation(conversation);
255 }
256
257 protected void openConversationForContact() {
258 int position = contact_context_id;
259 openConversationForContact(position);
260 }
261
262 protected void openConversationForBookmark() {
263 openConversationForBookmark(conference_context_id);
264 }
265
266 protected void openConversationForBookmark(int position) {
267 Bookmark bookmark = (Bookmark) conferences.get(position);
268 Conversation conversation = xmppConnectionService
269 .findOrCreateConversation(bookmark.getAccount(),
270 bookmark.getJid(), true);
271 conversation.setBookmark(bookmark);
272 if (!conversation.getMucOptions().online()) {
273 xmppConnectionService.joinMuc(conversation);
274 }
275 if (!bookmark.autojoin()) {
276 bookmark.setAutojoin(true);
277 xmppConnectionService.pushBookmarks(bookmark.getAccount());
278 }
279 switchToConversation(conversation);
280 }
281
282 protected void openDetailsForContact() {
283 int position = contact_context_id;
284 Contact contact = (Contact) contacts.get(position);
285 switchToContactDetails(contact);
286 }
287
288 protected void deleteContact() {
289 int position = contact_context_id;
290 final Contact contact = (Contact) contacts.get(position);
291 AlertDialog.Builder builder = new AlertDialog.Builder(this);
292 builder.setNegativeButton(R.string.cancel, null);
293 builder.setTitle(R.string.action_delete_contact);
294 builder.setMessage(getString(R.string.remove_contact_text,
295 contact.getJid()));
296 builder.setPositiveButton(R.string.delete, new OnClickListener() {
297
298 @Override
299 public void onClick(DialogInterface dialog, int which) {
300 xmppConnectionService.deleteContactOnServer(contact);
301 filter(mSearchEditText.getText().toString());
302 }
303 });
304 builder.create().show();
305
306 }
307
308 protected void deleteConference() {
309 int position = conference_context_id;
310 final Bookmark bookmark = (Bookmark) conferences.get(position);
311
312 AlertDialog.Builder builder = new AlertDialog.Builder(this);
313 builder.setNegativeButton(R.string.cancel, null);
314 builder.setTitle(R.string.delete_bookmark);
315 builder.setMessage(getString(R.string.remove_bookmark_text,
316 bookmark.getJid()));
317 builder.setPositiveButton(R.string.delete, new OnClickListener() {
318
319 @Override
320 public void onClick(DialogInterface dialog, int which) {
321 bookmark.unregisterConversation();
322 Account account = bookmark.getAccount();
323 account.getBookmarks().remove(bookmark);
324 xmppConnectionService.pushBookmarks(account);
325 filter(mSearchEditText.getText().toString());
326 }
327 });
328 builder.create().show();
329
330 }
331
332 @SuppressLint("InflateParams")
333 protected void showCreateContactDialog(String prefilledJid) {
334 AlertDialog.Builder builder = new AlertDialog.Builder(this);
335 builder.setTitle(R.string.create_contact);
336 View dialogView = getLayoutInflater().inflate(
337 R.layout.create_contact_dialog, null);
338 final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
339 final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView
340 .findViewById(R.id.jid);
341 jid.setAdapter(new KnownHostsAdapter(this,
342 android.R.layout.simple_list_item_1, mKnownHosts));
343 if (prefilledJid != null) {
344 jid.append(prefilledJid);
345 }
346 populateAccountSpinner(spinner);
347 builder.setView(dialogView);
348 builder.setNegativeButton(R.string.cancel, null);
349 builder.setPositiveButton(R.string.create, null);
350 final AlertDialog dialog = builder.create();
351 dialog.show();
352 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
353 new View.OnClickListener() {
354
355 @Override
356 public void onClick(View v) {
357 if (!xmppConnectionServiceBound) {
358 return;
359 }
360 if (Validator.isValidJid(jid.getText().toString())) {
361 String accountJid = (String) spinner
362 .getSelectedItem();
363 String contactJid = jid.getText().toString();
364 Account account = xmppConnectionService
365 .findAccountByJid(accountJid);
366 if (account == null) {
367 dialog.dismiss();
368 return;
369 }
370 Contact contact = account.getRoster().getContact(
371 contactJid);
372 if (contact.showInRoster()) {
373 jid.setError(getString(R.string.contact_already_exists));
374 } else {
375 xmppConnectionService.createContact(contact);
376 dialog.dismiss();
377 switchToConversation(contact);
378 }
379 } else {
380 jid.setError(getString(R.string.invalid_jid));
381 }
382 }
383 });
384
385 }
386
387 @SuppressLint("InflateParams")
388 protected void showJoinConferenceDialog(String prefilledJid) {
389 AlertDialog.Builder builder = new AlertDialog.Builder(this);
390 builder.setTitle(R.string.join_conference);
391 View dialogView = getLayoutInflater().inflate(
392 R.layout.join_conference_dialog, null);
393 final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account);
394 final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView
395 .findViewById(R.id.jid);
396 jid.setAdapter(new KnownHostsAdapter(this,
397 android.R.layout.simple_list_item_1, mKnownConferenceHosts));
398 if (prefilledJid != null) {
399 jid.append(prefilledJid);
400 }
401 populateAccountSpinner(spinner);
402 final CheckBox bookmarkCheckBox = (CheckBox) dialogView
403 .findViewById(R.id.bookmark);
404 builder.setView(dialogView);
405 builder.setNegativeButton(R.string.cancel, null);
406 builder.setPositiveButton(R.string.join, null);
407 final AlertDialog dialog = builder.create();
408 dialog.show();
409 dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
410 new View.OnClickListener() {
411
412 @Override
413 public void onClick(View v) {
414 if (!xmppConnectionServiceBound) {
415 return;
416 }
417 if (Validator.isValidJid(jid.getText().toString())) {
418 String accountJid = (String) spinner
419 .getSelectedItem();
420 String conferenceJid = jid.getText().toString();
421 Account account = xmppConnectionService
422 .findAccountByJid(accountJid);
423 if (account == null) {
424 dialog.dismiss();
425 return;
426 }
427 if (bookmarkCheckBox.isChecked()) {
428 if (account.hasBookmarkFor(conferenceJid)) {
429 jid.setError(getString(R.string.bookmark_already_exists));
430 } else {
431 Bookmark bookmark = new Bookmark(account,
432 conferenceJid);
433 bookmark.setAutojoin(true);
434 account.getBookmarks().add(bookmark);
435 xmppConnectionService
436 .pushBookmarks(account);
437 Conversation conversation = xmppConnectionService
438 .findOrCreateConversation(account,
439 conferenceJid, true);
440 conversation.setBookmark(bookmark);
441 if (!conversation.getMucOptions().online()) {
442 xmppConnectionService
443 .joinMuc(conversation);
444 }
445 dialog.dismiss();
446 switchToConversation(conversation);
447 }
448 } else {
449 Conversation conversation = xmppConnectionService
450 .findOrCreateConversation(account,
451 conferenceJid, true);
452 if (!conversation.getMucOptions().online()) {
453 xmppConnectionService.joinMuc(conversation);
454 }
455 dialog.dismiss();
456 switchToConversation(conversation);
457 }
458 } else {
459 jid.setError(getString(R.string.invalid_jid));
460 }
461 }
462 });
463 }
464
465 protected void switchToConversation(Contact contact) {
466 Conversation conversation = xmppConnectionService
467 .findOrCreateConversation(contact.getAccount(),
468 contact.getJid(), false);
469 switchToConversation(conversation);
470 }
471
472 private void populateAccountSpinner(Spinner spinner) {
473 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
474 android.R.layout.simple_spinner_item, mActivatedAccounts);
475 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
476 spinner.setAdapter(adapter);
477 }
478
479 @Override
480 public boolean onCreateOptionsMenu(Menu menu) {
481 this.mOptionsMenu = menu;
482 getMenuInflater().inflate(R.menu.start_conversation, menu);
483 MenuItem menuCreateContact = menu
484 .findItem(R.id.action_create_contact);
485 MenuItem menuCreateConference = menu
486 .findItem(R.id.action_join_conference);
487 mMenuSearchView = menu.findItem(R.id.action_search);
488 mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
489 View mSearchView = mMenuSearchView.getActionView();
490 mSearchEditText = (EditText) mSearchView
491 .findViewById(R.id.search_field);
492 mSearchEditText.addTextChangedListener(mSearchTextWatcher);
493 if (getActionBar().getSelectedNavigationIndex() == 0) {
494 menuCreateConference.setVisible(false);
495 } else {
496 menuCreateContact.setVisible(false);
497 }
498 if (mInitialJid != null) {
499 mMenuSearchView.expandActionView();
500 mSearchEditText.append(mInitialJid);
501 filter(mInitialJid);
502 }
503 return true;
504 }
505
506 @Override
507 public boolean onOptionsItemSelected(MenuItem item) {
508 switch (item.getItemId()) {
509 case R.id.action_create_contact:
510 showCreateContactDialog(null);
511 return true;
512 case R.id.action_join_conference:
513 showJoinConferenceDialog(null);
514 return true;
515 case R.id.action_scan_qr_code:
516 new IntentIntegrator(this).initiateScan();
517 return true;
518 }
519 return super.onOptionsItemSelected(item);
520 }
521
522 @Override
523 public boolean onKeyUp(int keyCode, KeyEvent event) {
524 if (keyCode == KeyEvent.KEYCODE_SEARCH && !event.isLongPress()) {
525 mOptionsMenu.findItem(R.id.action_search).expandActionView();
526 return true;
527 }
528 return super.onKeyUp(keyCode, event);
529 }
530
531 @Override
532 public void onActivityResult(int requestCode, int resultCode, Intent intent) {
533 if ((requestCode & 0xFFFF) == IntentIntegrator.REQUEST_CODE) {
534 IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
535 if (scanResult != null && scanResult.getFormatName() != null) {
536 String data = scanResult.getContents();
537 Invite invite = new Invite(data);
538 if (xmppConnectionServiceBound) {
539 invite.invite();
540 } else if (invite.jid != null) {
541 this.mPendingInvite = invite;
542 } else {
543 this.mPendingInvite = null;
544 }
545 }
546 }
547 super.onActivityResult(requestCode, requestCode, intent);
548 }
549
550 @Override
551 protected void onBackendConnected() {
552 xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate);
553 this.mActivatedAccounts.clear();
554 for (Account account : xmppConnectionService.getAccounts()) {
555 if (account.getStatus() != Account.STATUS_DISABLED) {
556 this.mActivatedAccounts.add(account.getJid());
557 }
558 }
559 this.mKnownHosts = xmppConnectionService.getKnownHosts();
560 this.mKnownConferenceHosts = xmppConnectionService
561 .getKnownConferenceHosts();
562 if (this.mPendingInvite != null) {
563 mPendingInvite.invite();
564 this.mPendingInvite = null;
565 } else if (!handleIntent(getIntent())) {
566 if (mSearchEditText != null) {
567 filter(mSearchEditText.getText().toString());
568 } else {
569 filter(null);
570 }
571 }
572 setIntent(null);
573 }
574
575 protected boolean handleIntent(Intent intent) {
576 if (intent == null || intent.getAction() == null) {
577 return false;
578 }
579 switch (intent.getAction()) {
580 case Intent.ACTION_SENDTO:
581 case Intent.ACTION_VIEW:
582 Log.d(Config.LOGTAG, "received uri=" + intent.getData());
583 return new Invite(intent.getData()).invite();
584 case NfcAdapter.ACTION_NDEF_DISCOVERED:
585 for (Parcelable message : getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) {
586 if (message instanceof NdefMessage) {
587 Log.d(Config.LOGTAG, "received message=" + message);
588 for (NdefRecord record : ((NdefMessage)message).getRecords()) {
589 switch (record.getTnf()) {
590 case NdefRecord.TNF_WELL_KNOWN:
591 if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
592 if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
593 return new Invite(record.toUri()).invite();
594 } else {
595 byte[] payload = record.getPayload();
596 if (payload[0] == 0) {
597 return new Invite(Uri.parse(new String(Arrays.copyOfRange(
598 payload, 1, payload.length)))).invite();
599 }
600 }
601 }
602 }
603 }
604 }
605 }
606 }
607 return false;
608 }
609
610 private boolean handleJid(String jid) {
611 List<Contact> contacts = xmppConnectionService.findContacts(jid);
612 if (contacts.size() == 0) {
613 showCreateContactDialog(jid);
614 return false;
615 } else if (contacts.size() == 1) {
616 switchToConversation(contacts.get(0));
617 return true;
618 } else {
619 if (mMenuSearchView != null) {
620 mMenuSearchView.expandActionView();
621 mSearchEditText.setText("");
622 mSearchEditText.append(jid);
623 filter(jid);
624 } else {
625 mInitialJid = jid;
626 }
627 return true;
628 }
629 }
630
631 protected void filter(String needle) {
632 if (xmppConnectionServiceBound) {
633 this.filterContacts(needle);
634 this.filterConferences(needle);
635 }
636 }
637
638 protected void filterContacts(String needle) {
639 this.contacts.clear();
640 for (Account account : xmppConnectionService.getAccounts()) {
641 if (account.getStatus() != Account.STATUS_DISABLED) {
642 for (Contact contact : account.getRoster().getContacts()) {
643 if (contact.showInRoster() && contact.match(needle)) {
644 this.contacts.add(contact);
645 }
646 }
647 }
648 }
649 Collections.sort(this.contacts);
650 mContactsAdapter.notifyDataSetChanged();
651 }
652
653 protected void filterConferences(String needle) {
654 this.conferences.clear();
655 for (Account account : xmppConnectionService.getAccounts()) {
656 if (account.getStatus() != Account.STATUS_DISABLED) {
657 for (Bookmark bookmark : account.getBookmarks()) {
658 if (bookmark.match(needle)) {
659 this.conferences.add(bookmark);
660 }
661 }
662 }
663 }
664 Collections.sort(this.conferences);
665 mConferenceAdapter.notifyDataSetChanged();
666 }
667
668 private void onTabChanged() {
669 invalidateOptionsMenu();
670 }
671
672 public static class MyListFragment extends ListFragment {
673 private AdapterView.OnItemClickListener mOnItemClickListener;
674 private int mResContextMenu;
675
676 public void setContextMenu(int res) {
677 this.mResContextMenu = res;
678 }
679
680 @Override
681 public void onListItemClick(ListView l, View v, int position, long id) {
682 if (mOnItemClickListener != null) {
683 mOnItemClickListener.onItemClick(l, v, position, id);
684 }
685 }
686
687 public void setOnListItemClickListener(AdapterView.OnItemClickListener l) {
688 this.mOnItemClickListener = l;
689 }
690
691 @Override
692 public void onViewCreated(View view, Bundle savedInstanceState) {
693 super.onViewCreated(view, savedInstanceState);
694 registerForContextMenu(getListView());
695 getListView().setFastScrollEnabled(true);
696 }
697
698 @Override
699 public void onCreateContextMenu(ContextMenu menu, View v,
700 ContextMenuInfo menuInfo) {
701 super.onCreateContextMenu(menu, v, menuInfo);
702 StartConversationActivity activity = (StartConversationActivity) getActivity();
703 activity.getMenuInflater().inflate(mResContextMenu, menu);
704 AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
705 if (mResContextMenu == R.menu.conference_context) {
706 activity.conference_context_id = acmi.position;
707 } else {
708 activity.contact_context_id = acmi.position;
709 }
710 }
711
712 @Override
713 public boolean onContextItemSelected(MenuItem item) {
714 StartConversationActivity activity = (StartConversationActivity) getActivity();
715 switch (item.getItemId()) {
716 case R.id.context_start_conversation:
717 activity.openConversationForContact();
718 break;
719 case R.id.context_contact_details:
720 activity.openDetailsForContact();
721 break;
722 case R.id.context_delete_contact:
723 activity.deleteContact();
724 break;
725 case R.id.context_join_conference:
726 activity.openConversationForBookmark();
727 break;
728 case R.id.context_delete_conference:
729 activity.deleteConference();
730 }
731 return true;
732 }
733 }
734
735 private class Invite {
736 private String jid;
737 private boolean muc;
738
739 Invite(Uri uri) {
740 parse(uri);
741 }
742
743 Invite(String uri) {
744 try {
745 parse(Uri.parse(uri));
746 } catch (IllegalArgumentException e) {
747 jid = null;
748 }
749 }
750
751 boolean invite() {
752 if (jid != null) {
753 if (muc) {
754 showJoinConferenceDialog(jid);
755 } else {
756 return handleJid(jid);
757 }
758 }
759 return false;
760 }
761
762 void parse(Uri uri) {
763 String scheme = uri.getScheme();
764 if ("xmpp".equals(scheme)) {
765 // sample: xmpp:jid@foo.com
766 muc = "join".equalsIgnoreCase(uri.getQuery());
767 if (uri.getAuthority() != null) {
768 jid = uri.getAuthority();
769 } else {
770 jid = uri.getSchemeSpecificPart().split("\\?")[0];
771 }
772 } else if ("imto".equals(scheme)) {
773 // sample: imto://xmpp/jid@foo.com
774 try {
775 jid = URLDecoder.decode(uri.getEncodedPath(), "UTF-8").split("/")[1];
776 } catch (UnsupportedEncodingException e) {
777 }
778 }
779 }
780 }
781}