package eu.siacs.conversations.ui; import java.util.ArrayList; import java.util.Collections; import java.util.List; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.ActionBar.TabListener; import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentTransaction; import android.app.ListFragment; import android.content.Context; import android.os.Bundle; import android.support.v13.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.text.Editable; import android.text.TextWatcher; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.utils.KnownHostsAdapter; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.Validator; public class StartConversation extends XmppActivity { private Tab mContactsTab; private Tab mConferencesTab; private ViewPager mViewPager; private MyListFragment mContactsListFragment = new MyListFragment(); private List contacts = new ArrayList(); private ArrayAdapter mContactsAdapter; private MyListFragment mConferenceListFragment = new MyListFragment(); private List conferences = new ArrayList(); private ArrayAdapter mConferenceAdapter; private List mActivatedAccounts = new ArrayList(); private List mKnownHosts; private List mKnownConferenceHosts; private EditText mSearchEditText; private TabListener mTabListener = new TabListener() { @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { return; } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { mViewPager.setCurrentItem(tab.getPosition()); onTabChanged(); } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { return; } }; private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { getActionBar().setSelectedNavigationItem(position); onTabChanged(); } }; private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { mSearchEditText.post(new Runnable() { @Override public void run() { mSearchEditText.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mSearchEditText, InputMethodManager.SHOW_IMPLICIT); } }); return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); mSearchEditText.setText(""); filterContacts(null); return true; } }; private TextWatcher mSearchTextWatcher = new TextWatcher() { @Override public void afterTextChanged(Editable editable) { filterContacts(editable.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start_conversation); mViewPager = (ViewPager) findViewById(R.id.start_conversation_view_pager); ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); mContactsTab = actionBar.newTab().setText(R.string.contacts) .setTabListener(mTabListener); mConferencesTab = actionBar.newTab().setText(R.string.conferences) .setTabListener(mTabListener); actionBar.addTab(mContactsTab); actionBar.addTab(mConferencesTab); mViewPager.setOnPageChangeListener(mOnPageChangeListener); mViewPager.setAdapter(new FragmentPagerAdapter(getFragmentManager()) { @Override public int getCount() { return 2; } @Override public Fragment getItem(int position) { if (position == 0) { return mContactsListFragment; } else { return mConferenceListFragment; } } }); mConferenceAdapter = new ListItemAdapter(conferences); mConferenceListFragment.setListAdapter(mConferenceAdapter); mContactsAdapter = new ListItemAdapter(contacts); mContactsListFragment.setListAdapter(mContactsAdapter); mContactsListFragment .setOnListItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView arg0, View arg1, int position, long arg3) { openConversationForContact(position); } }); } protected void openConversationForContact(int position) { Contact contact = (Contact) contacts.get(position); Conversation conversation = xmppConnectionService .findOrCreateConversation(contact.getAccount(), contact.getJid(), false); switchToConversation(conversation, null, false); } protected void openDetailsForContact(int position) { Contact contact = (Contact) contacts.get(position); switchToContactDetails(contact); } protected void deleteContact(int position) { Contact contact = (Contact) contacts.get(position); xmppConnectionService.deleteContactOnServer(contact); filterContacts(mSearchEditText.getText().toString()); } protected void showCreateContactDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.create_contact); View dialogView = getLayoutInflater().inflate( R.layout.create_contact_dialog, null); final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account); final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView .findViewById(R.id.jid); jid.setAdapter(new KnownHostsAdapter(this, android.R.layout.simple_list_item_1, mKnownHosts)); populateAccountSpinner(spinner); builder.setView(dialogView); builder.setNegativeButton(R.string.cancel, null); builder.setPositiveButton(R.string.create, null); final AlertDialog dialog = builder.create(); dialog.show(); dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (Validator.isValidJid(jid.getText().toString())) { String accountJid = (String) spinner .getSelectedItem(); String contactJid = jid.getText().toString(); Account account = xmppConnectionService .findAccountByJid(accountJid); Contact contact = account.getRoster().getContact( contactJid); if (contact.showInRoster()) { jid.setError(getString(R.string.contact_already_exists)); } else { xmppConnectionService.createContact(contact); switchToConversation(contact); dialog.dismiss(); } } else { jid.setError(getString(R.string.invalid_jid)); } } }); } protected void showJoinConferenceDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.join_conference); View dialogView = getLayoutInflater().inflate( R.layout.join_conference_dialog, null); final Spinner spinner = (Spinner) dialogView.findViewById(R.id.account); final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView .findViewById(R.id.jid); jid.setAdapter(new KnownHostsAdapter(this, android.R.layout.simple_list_item_1, mKnownConferenceHosts)); populateAccountSpinner(spinner); builder.setView(dialogView); builder.setNegativeButton(R.string.cancel, null); builder.setPositiveButton(R.string.join, null); final AlertDialog dialog = builder.create(); dialog.show(); dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (Validator.isValidJid(jid.getText().toString())) { String accountJid = (String) spinner .getSelectedItem(); String conferenceJid = jid.getText().toString(); Account account = xmppConnectionService .findAccountByJid(accountJid); Conversation conversation = xmppConnectionService .findOrCreateConversation(account, conferenceJid, true); switchToConversation(conversation); } else { jid.setError(getString(R.string.invalid_jid)); } } }); } protected void switchToConversation(Contact contact) { Conversation conversation = xmppConnectionService .findOrCreateConversation(contact.getAccount(), contact.getJid(), false); switchToConversation(conversation); } private void populateAccountSpinner(Spinner spinner) { ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, mActivatedAccounts); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.start_conversation, menu); MenuItem menuCreateContact = (MenuItem) menu .findItem(R.id.action_create_contact); MenuItem menuCreateConference = (MenuItem) menu .findItem(R.id.action_join_conference); MenuItem menuSearchView = (MenuItem) menu.findItem(R.id.action_search); menuSearchView.setOnActionExpandListener(mOnActionExpandListener); View mSearchView = menuSearchView.getActionView(); mSearchEditText = (EditText) mSearchView .findViewById(R.id.search_field); mSearchEditText.addTextChangedListener(mSearchTextWatcher); if (getActionBar().getSelectedNavigationIndex() == 0) { menuCreateConference.setVisible(false); } else { menuCreateContact.setVisible(false); } return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_create_contact: showCreateContactDialog(); break; case R.id.action_join_conference: showJoinConferenceDialog(); break; } return super.onOptionsItemSelected(item); } @Override void onBackendConnected() { if (mSearchEditText != null) { filterContacts(mSearchEditText.getText().toString()); } else { filterContacts(null); } this.mActivatedAccounts.clear(); for (Account account : xmppConnectionService.getAccounts()) { if (account.getStatus() != Account.STATUS_DISABLED) { this.mActivatedAccounts.add(account.getJid()); } } this.mKnownHosts = xmppConnectionService.getKnownHosts(); this.mKnownConferenceHosts = xmppConnectionService .getKnownConferenceHosts(); } protected void filterContacts(String needle) { this.contacts.clear(); for (Account account : xmppConnectionService.getAccounts()) { if (account.getStatus() != Account.STATUS_DISABLED) { for (Contact contact : account.getRoster().getContacts()) { if (contact.showInRoster() && contact.match(needle)) { this.contacts.add(contact); } } } } Collections.sort(this.contacts); mContactsAdapter.notifyDataSetChanged(); } private void onTabChanged() { invalidateOptionsMenu(); } private class ListItemAdapter extends ArrayAdapter { public ListItemAdapter(List objects) { super(getApplicationContext(), 0, objects); } @Override public View getView(int position, View view, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); ListItem item = getItem(position); if (view == null) { view = (View) inflater.inflate(R.layout.contact, null); } TextView name = (TextView) view .findViewById(R.id.contact_display_name); TextView jid = (TextView) view.findViewById(R.id.contact_jid); ImageView picture = (ImageView) view .findViewById(R.id.contact_photo); jid.setText(item.getJid()); name.setText(item.getDisplayName()); picture.setImageBitmap(UIHelper.getContactPicture(item, 48, this.getContext(), false)); return view; } } public static class MyListFragment extends ListFragment { private AdapterView.OnItemClickListener mOnItemClickListener; private int mContextPosition = -1; @Override public void onListItemClick(ListView l, View v, int position, long id) { if (mOnItemClickListener != null) { mOnItemClickListener.onItemClick(l, v, position, id); } } public void setOnListItemClickListener(AdapterView.OnItemClickListener l) { this.mOnItemClickListener = l; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); registerForContextMenu(getListView()); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); getActivity().getMenuInflater().inflate(R.menu.contact_context, menu); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; this.mContextPosition = acmi.position; } @Override public boolean onContextItemSelected(MenuItem item) { StartConversation activity = (StartConversation) getActivity(); switch (item.getItemId()) { case R.id.context_start_conversation: activity.openConversationForContact(mContextPosition); break; case R.id.context_contact_details: activity.openDetailsForContact(mContextPosition); break; case R.id.context_delete_contact: activity.deleteContact(mContextPosition); break; } return true; } } }