diff options
Diffstat (limited to 'src/eu/siacs/conversations/ui')
17 files changed, 1775 insertions, 1318 deletions
diff --git a/src/eu/siacs/conversations/ui/ChooseContactActivity.java b/src/eu/siacs/conversations/ui/ChooseContactActivity.java new file mode 100644 index 00000000..4236ea70 --- /dev/null +++ b/src/eu/siacs/conversations/ui/ChooseContactActivity.java @@ -0,0 +1,140 @@ +package eu.siacs.conversations.ui; + +import java.util.ArrayList; +import java.util.Collections; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.entities.ListItem; +import eu.siacs.conversations.ui.adapter.ListItemAdapter; + +public class ChooseContactActivity extends XmppActivity { + + private ListView mListView; + private ArrayList<ListItem> contacts = new ArrayList<ListItem>(); + private ArrayAdapter<ListItem> mContactsAdapter; + + private EditText mSearchEditText; + + 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) { + } + }; + + 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; + } + }; + + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_choose_contact); + mListView = (ListView) findViewById(R.id.choose_contact_list); + mContactsAdapter = new ListItemAdapter(getApplicationContext(), contacts); + mListView.setAdapter(mContactsAdapter); + mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, int position, + long arg3) { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), + InputMethodManager.HIDE_IMPLICIT_ONLY); + Intent request = getIntent(); + Intent data = new Intent(); + data.putExtra("contact",contacts.get(position).getJid()); + data.putExtra("account",request.getStringExtra("account")); + data.putExtra("conversation",request.getStringExtra("conversation")); + setResult(RESULT_OK, data); + finish(); + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.choose_contact, menu); + MenuItem menuSearchView = (MenuItem) menu.findItem(R.id.action_search); + View mSearchView = menuSearchView.getActionView(); + mSearchEditText = (EditText) mSearchView + .findViewById(R.id.search_field); + mSearchEditText.addTextChangedListener(mSearchTextWatcher); + menuSearchView.setOnActionExpandListener(mOnActionExpandListener); + return true; + } + + @Override + void onBackendConnected() { + filterContacts(null); + } + + 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(); + } + +} diff --git a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java new file mode 100644 index 00000000..56903da8 --- /dev/null +++ b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -0,0 +1,268 @@ +package eu.siacs.conversations.ui; + +import java.util.ArrayList; +import java.util.List; + +import org.openintents.openpgp.util.OpenPgpUtils; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.crypto.PgpEngine; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.MucOptions; +import eu.siacs.conversations.entities.MucOptions.OnRenameListener; +import eu.siacs.conversations.entities.MucOptions.User; +import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; +import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xmpp.stanzas.MessagePacket; +import android.app.PendingIntent; +import android.content.Context; +import android.content.IntentSender.SendIntentException; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +public class ConferenceDetailsActivity extends XmppActivity { + public static final String ACTION_VIEW_MUC = "view_muc"; + private Conversation conversation; + private TextView mYourNick; + private ImageView mYourPhoto; + private ImageButton mEditNickButton; + private TextView mRoleAffiliaton; + private TextView mFullJid; + private LinearLayout membersView; + private LinearLayout mMoreDetails; + private Button mInviteButton; + private String uuid = null; + + private OnClickListener inviteListener = new OnClickListener() { + + @Override + public void onClick(View v) { + inviteToConversation(conversation); + } + }; + + private List<User> users = new ArrayList<MucOptions.User>(); + private OnConversationUpdate onConvChanged = new OnConversationUpdate() { + + @Override + public void onConversationUpdate() { + runOnUiThread(new Runnable() { + + @Override + public void run() { + populateView(); + } + }); + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_muc_details); + mYourNick = (TextView) findViewById(R.id.muc_your_nick); + mYourPhoto = (ImageView) findViewById(R.id.your_photo); + mEditNickButton = (ImageButton) findViewById(R.id.edit_nick_button); + mFullJid = (TextView) findViewById(R.id.muc_jabberid); + membersView = (LinearLayout) findViewById(R.id.muc_members); + mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details); + mMoreDetails.setVisibility(View.GONE); + mInviteButton = (Button) findViewById(R.id.invite); + mInviteButton.setOnClickListener(inviteListener); + getActionBar().setHomeButtonEnabled(true); + getActionBar().setDisplayHomeAsUpEnabled(true); + mEditNickButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + quickEdit(conversation.getMucOptions().getActualNick(), + new OnValueEdited() { + + @Override + public void onValueEdited(String value) { + xmppConnectionService.renameInMuc(conversation, + value); + } + }); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case android.R.id.home: + finish(); + break; + case R.id.action_edit_subject: + if (conversation != null) { + quickEdit(conversation.getName(true), new OnValueEdited() { + + @Override + public void onValueEdited(String value) { + MessagePacket packet = xmppConnectionService + .getMessageGenerator().conferenceSubject( + conversation, value); + xmppConnectionService.sendMessagePacket( + conversation.getAccount(), packet); + } + }); + } + break; + } + return super.onOptionsItemSelected(menuItem); + } + + public String getReadableRole(int role) { + switch (role) { + case User.ROLE_MODERATOR: + return getString(R.string.moderator); + case User.ROLE_PARTICIPANT: + return getString(R.string.participant); + case User.ROLE_VISITOR: + return getString(R.string.visitor); + default: + return ""; + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.muc_details, menu); + return true; + } + + @Override + void onBackendConnected() { + registerListener(); + if (getIntent().getAction().equals(ACTION_VIEW_MUC)) { + this.uuid = getIntent().getExtras().getString("uuid"); + } + if (uuid != null) { + this.conversation = xmppConnectionService.findConversationByUuid(uuid); + if (this.conversation != null) { + populateView(); + } + } + } + + @Override + protected void onStop() { + if (xmppConnectionServiceBound) { + xmppConnectionService.removeOnConversationListChangedListener(); + } + super.onStop(); + } + + protected void registerListener() { + if (xmppConnectionServiceBound) { + xmppConnectionService + .setOnConversationListChangedListener(this.onConvChanged); + xmppConnectionService.setOnRenameListener(new OnRenameListener() { + + @Override + public void onRename(final boolean success) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + populateView(); + if (success) { + Toast.makeText(ConferenceDetailsActivity.this, + getString(R.string.your_nick_has_been_changed), + Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(ConferenceDetailsActivity.this, + getString(R.string.nick_in_use), + Toast.LENGTH_SHORT).show(); + } + } + }); + } + }); + } + } + + private void populateView() { + mYourPhoto.setImageBitmap(UIHelper.getContactPicture(conversation + .getMucOptions().getActualNick(), 48, this, false)); + setTitle(conversation.getName(true)); + mFullJid.setText(conversation.getContactJid().split("/")[0]); + mYourNick.setText(conversation.getMucOptions().getActualNick()); + mRoleAffiliaton = (TextView) findViewById(R.id.muc_role); + if (conversation.getMucOptions().online()) { + mMoreDetails.setVisibility(View.VISIBLE); + User self = conversation.getMucOptions().getSelf(); + switch (self.getAffiliation()) { + case User.AFFILIATION_ADMIN: + mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " (" + + getString(R.string.admin) + ")"); + break; + case User.AFFILIATION_OWNER: + mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " (" + + getString(R.string.owner) + ")"); + break; + default: + mRoleAffiliaton.setText(getReadableRole(self.getRole())); + break; + } + } + this.users.clear(); + this.users.addAll(conversation.getMucOptions().getUsers()); + LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + membersView.removeAllViews(); + for (final User contact : conversation.getMucOptions().getUsers()) { + View view = (View) inflater.inflate(R.layout.contact, null); + TextView displayName = (TextView) view + .findViewById(R.id.contact_display_name); + TextView key = (TextView) view.findViewById(R.id.key); + displayName.setText(contact.getName()); + TextView role = (TextView) view.findViewById(R.id.contact_jid); + role.setText(getReadableRole(contact.getRole())); + if (contact.getPgpKeyId() != 0) { + key.setVisibility(View.VISIBLE); + key.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + viewPgpKey(contact); + } + }); + key.setText(OpenPgpUtils.convertKeyIdToHex(contact + .getPgpKeyId())); + } + Bitmap bm = UIHelper.getContactPicture(contact.getName(), 48, this, + false); + ImageView iv = (ImageView) view.findViewById(R.id.contact_photo); + iv.setImageBitmap(bm); + membersView.addView(view); + } + } + + private void viewPgpKey(User user) { + PgpEngine pgp = xmppConnectionService.getPgpEngine(); + if (pgp != null) { + PendingIntent intent = pgp.getIntentForKey( + conversation.getAccount(), user.getPgpKeyId()); + if (intent != null) { + try { + startIntentSenderForResult(intent.getIntentSender(), 0, + null, 0, 0, 0); + } catch (SendIntentException e) { + + } + } + } + } +} diff --git a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java index bee93713..7c13c518 100644 --- a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -21,16 +21,18 @@ import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.CheckBox; -import android.widget.EditText; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.QuickContactBadge; import android.widget.TextView; -import android.widget.Toast; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Presences; +import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; +import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.utils.UIHelper; public class ContactDetailsActivity extends XmppActivity { @@ -39,15 +41,13 @@ public class ContactDetailsActivity extends XmppActivity { protected ContactDetailsActivity activity = this; private Contact contact; - + private String accountJid; private String contactJid; - - private EditText name; + private TextView contactJidTv; private TextView accountJidTv; private TextView status; - private TextView askAgain; private TextView lastseen; private CheckBox send; private CheckBox receive; @@ -62,16 +62,6 @@ public class ContactDetailsActivity extends XmppActivity { } }; - private DialogInterface.OnClickListener editContactNameListener = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - contact.setServerName(name.getText().toString()); - activity.xmppConnectionService.pushContactToServer(contact); - populateView(); - } - }; - private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() { @Override @@ -91,7 +81,8 @@ public class ContactDetailsActivity extends XmppActivity { public void onClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(getString(R.string.action_add_phone_book)); - builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid())); + builder.setMessage(getString(R.string.add_phone_book_text, + contact.getJid())); builder.setNegativeButton(getString(R.string.cancel), null); builder.setPositiveButton(getString(R.string.add), addToPhonebook); builder.create().show(); @@ -100,6 +91,74 @@ public class ContactDetailsActivity extends XmppActivity { private LinearLayout keys; + private OnRosterUpdate rosterUpdate = new OnRosterUpdate() { + + @Override + public void onRosterUpdate() { + runOnUiThread(new Runnable() { + + @Override + public void run() { + populateView(); + } + }); + } + }; + + private OnCheckedChangeListener mOnSendCheckedChange = new OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + if (isChecked) { + if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { + xmppConnectionService.sendPresencePacket(contact + .getAccount(), + xmppConnectionService.getPresenceGenerator() + .sendPresenceUpdatesTo(contact)); + } else { + contact.setOption(Contact.Options.PREEMPTIVE_GRANT); + } + } else { + contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); + xmppConnectionService.sendPresencePacket(contact.getAccount(), + xmppConnectionService.getPresenceGenerator() + .stopPresenceUpdatesTo(contact)); + } + } + }; + + private OnCheckedChangeListener mOnReceiveCheckedChange = new OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + if (isChecked) { + xmppConnectionService.sendPresencePacket(contact.getAccount(), + xmppConnectionService.getPresenceGenerator() + .requestPresenceUpdatesFrom(contact)); + } else { + xmppConnectionService.sendPresencePacket(contact.getAccount(), + xmppConnectionService.getPresenceGenerator() + .stopPresenceUpdatesFrom(contact)); + } + } + }; + + private OnAccountUpdate accountUpdate = new OnAccountUpdate() { + + @Override + public void onAccountUpdate() { + runOnUiThread(new Runnable() { + + @Override + public void run() { + populateView(); + } + }); + } + }; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -115,7 +174,6 @@ public class ContactDetailsActivity extends XmppActivity { lastseen = (TextView) findViewById(R.id.details_lastseen); send = (CheckBox) findViewById(R.id.details_send_presence); receive = (CheckBox) findViewById(R.id.details_receive_presence); - askAgain = (TextView) findViewById(R.id.ask_again); badge = (QuickContactBadge) findViewById(R.id.details_contact_badge); keys = (LinearLayout) findViewById(R.id.details_contact_keys); getActionBar().setHomeButtonEnabled(true); @@ -136,20 +194,21 @@ public class ContactDetailsActivity extends XmppActivity { .setMessage( getString(R.string.remove_contact_text, contact.getJid())) - .setPositiveButton(getString(R.string.delete), removeFromRoster).create() - .show(); + .setPositiveButton(getString(R.string.delete), + removeFromRoster).create().show(); break; case R.id.action_edit_contact: if (contact.getSystemAccount() == null) { + quickEdit(contact.getDisplayName(), new OnValueEdited() { - View view = (View) getLayoutInflater().inflate( - R.layout.edit_contact_name, null); - name = (EditText) view.findViewById(R.id.editText1); - name.setText(contact.getDisplayName()); - builder.setView(view).setTitle(contact.getJid()) - .setPositiveButton(getString(R.string.edit), editContactNameListener) - .create().show(); - + @Override + public void onValueEdited(String value) { + contact.setServerName(value); + activity.xmppConnectionService + .pushContactToServer(contact); + populateView(); + } + }); } else { Intent intent = new Intent(Intent.ACTION_EDIT); String[] systemAccount = contact.getSystemAccount().split("#"); @@ -171,41 +230,48 @@ public class ContactDetailsActivity extends XmppActivity { } private void populateView() { + send.setOnCheckedChangeListener(null); + receive.setOnCheckedChangeListener(null); setTitle(contact.getDisplayName()); if (contact.getOption(Contact.Options.FROM)) { + send.setText(R.string.send_presence_updates); send.setChecked(true); + } else if (contact + .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { + send.setChecked(false); + send.setText(R.string.send_presence_updates); } else { send.setText(R.string.preemptively_grant); - if (contact - .getOption(Contact.Options.PREEMPTIVE_GRANT)) { + if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { send.setChecked(true); } else { send.setChecked(false); } } if (contact.getOption(Contact.Options.TO)) { + receive.setText(R.string.receive_presence_updates); receive.setChecked(true); } else { receive.setText(R.string.ask_for_presence_updates); - askAgain.setVisibility(View.VISIBLE); - askAgain.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - Toast.makeText(getApplicationContext(), getString(R.string.asked_for_presence_updates), - Toast.LENGTH_SHORT).show(); - xmppConnectionService.requestPresenceUpdatesFrom(contact); - - } - }); if (contact.getOption(Contact.Options.ASKING)) { receive.setChecked(true); } else { receive.setChecked(false); } } + if (contact.getAccount().getStatus() == Account.STATUS_ONLINE) { + receive.setEnabled(true); + send.setEnabled(true); + } else { + receive.setEnabled(false); + send.setEnabled(false); + } + + send.setOnCheckedChangeListener(this.mOnSendCheckedChange); + receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange); - lastseen.setText(UIHelper.lastseen(getApplicationContext(),contact.lastseen.time)); + lastseen.setText(UIHelper.lastseen(getApplicationContext(), + contact.lastseen.time)); switch (contact.getMostAvailableStatus()) { case Presences.CHAT: @@ -238,13 +304,15 @@ public class ContactDetailsActivity extends XmppActivity { break; } if (contact.getPresences().size() > 1) { - contactJidTv.setText(contact.getJid()+" ("+contact.getPresences().size()+")"); + contactJidTv.setText(contact.getJid() + " (" + + contact.getPresences().size() + ")"); } else { contactJidTv.setText(contact.getJid()); } accountJidTv.setText(contact.getAccount().getJid()); - UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext()); + UIHelper.prepareContactBadge(this, badge, contact, + getApplicationContext()); if (contact.getSystemAccount() == null) { badge.setOnClickListener(onBadgeClick); @@ -269,17 +337,20 @@ public class ContactDetailsActivity extends XmppActivity { keyType.setText("PGP Key ID"); key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId())); view.setOnClickListener(new OnClickListener() { - + @Override public void onClick(View v) { - PgpEngine pgp = activity.xmppConnectionService.getPgpEngine(); - if (pgp!=null) { + PgpEngine pgp = activity.xmppConnectionService + .getPgpEngine(); + if (pgp != null) { PendingIntent intent = pgp.getIntentForKey(contact); - if (intent!=null) { + if (intent != null) { try { - startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0); + startIntentSenderForResult( + intent.getIntentSender(), 0, null, 0, + 0, 0); } catch (SendIntentException e) { - + } } } @@ -291,9 +362,12 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onBackendConnected() { - if ((accountJid != null)&&(contactJid != null)) { - Account account = xmppConnectionService.findAccountByJid(accountJid); - if (account==null) { + xmppConnectionService.setOnRosterUpdateListener(this.rosterUpdate); + xmppConnectionService.setOnAccountListChangedListener(this.accountUpdate ); + if ((accountJid != null) && (contactJid != null)) { + Account account = xmppConnectionService + .findAccountByJid(accountJid); + if (account == null) { return; } this.contact = account.getRoster().getContact(contactJid); @@ -304,73 +378,8 @@ public class ContactDetailsActivity extends XmppActivity { @Override protected void onStop() { super.onStop(); - boolean updated = false; - if (contact!=null) { - boolean online = contact.getAccount().getStatus() == Account.STATUS_ONLINE; - if (contact.getOption(Contact.Options.FROM)) { - if (!send.isChecked()) { - if (online) { - contact.resetOption(Contact.Options.FROM); - contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); - activity.xmppConnectionService.stopPresenceUpdatesTo(contact); - } - updated = true; - } - } else { - if (contact - .getOption(Contact.Options.PREEMPTIVE_GRANT)) { - if (!send.isChecked()) { - if (online) { - contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); - } - updated = true; - } - } else { - if (send.isChecked()) { - if (online) { - contact.setOption(Contact.Options.PREEMPTIVE_GRANT); - } - updated = true; - } - } - } - if (contact.getOption(Contact.Options.TO)) { - if (!receive.isChecked()) { - if (online) { - contact.resetOption(Contact.Options.TO); - activity.xmppConnectionService.stopPresenceUpdatesFrom(contact); - } - updated = true; - } - } else { - if (contact.getOption(Contact.Options.ASKING)) { - if (!receive.isChecked()) { - if (online) { - contact.resetOption(Contact.Options.ASKING); - activity.xmppConnectionService - .stopPresenceUpdatesFrom(contact); - } - updated = true; - } - } else { - if (receive.isChecked()) { - if (online) { - contact.setOption(Contact.Options.ASKING); - activity.xmppConnectionService - .requestPresenceUpdatesFrom(contact); - } - updated = true; - } - } - } - if (updated) { - if (online) { - Toast.makeText(getApplicationContext(), getString(R.string.subscription_updated), Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(getApplicationContext(), getString(R.string.subscription_not_updated_offline), Toast.LENGTH_SHORT).show(); - } - } - } + xmppConnectionService.removeOnRosterUpdateListener(); + xmppConnectionService.removeOnAccountListChangedListener(); } } diff --git a/src/eu/siacs/conversations/ui/ContactsActivity.java b/src/eu/siacs/conversations/ui/ContactsActivity.java deleted file mode 100644 index fee3de7a..00000000 --- a/src/eu/siacs/conversations/ui/ContactsActivity.java +++ /dev/null @@ -1,598 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -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.utils.CryptoHelper; -import eu.siacs.conversations.utils.UIHelper; -import eu.siacs.conversations.utils.Validator; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.SparseBooleanArray; -import android.view.ActionMode; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.ImageView; -import android.widget.Toast; -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; - -public class ContactsActivity extends XmppActivity { - - protected List<Contact> rosterContacts = new ArrayList<Contact>(); - protected List<Contact> aggregatedContacts = new ArrayList<Contact>(); - protected ListView contactsView; - protected ArrayAdapter<Contact> contactsAdapter; - - protected EditText search; - protected String searchString = ""; - private TextView contactsHeader; - private List<Account> accounts; - private List<Contact> selectedContacts = new ArrayList<Contact>(); - - private ContactsActivity activity = this; - - private boolean useSubject = true; - private boolean isActionMode = false; - private boolean inviteIntent = false; - private ActionMode actionMode = null; - private AbsListView.MultiChoiceModeListener actionModeCallback = new AbsListView.MultiChoiceModeListener() { - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - menu.clear(); - MenuInflater inflater = mode.getMenuInflater(); - inflater.inflate(R.menu.newconversation_context, menu); - SparseBooleanArray checkedItems = contactsView - .getCheckedItemPositions(); - selectedContacts.clear(); - for (int i = 0; i < aggregatedContacts.size(); ++i) { - if (checkedItems.get(i, false)) { - selectedContacts.add(aggregatedContacts.get(i)); - } - } - if (selectedContacts.size() == 0) { - menu.findItem(R.id.action_start_conversation).setVisible(false); - menu.findItem(R.id.action_contact_details).setVisible(false); - menu.findItem(R.id.action_invite).setVisible(false); - menu.findItem(R.id.action_invite_to_existing).setVisible(false); - } else if ((selectedContacts.size() == 1) && (!inviteIntent)) { - menu.findItem(R.id.action_start_conversation).setVisible(true); - menu.findItem(R.id.action_contact_details).setVisible(true); - menu.findItem(R.id.action_invite).setVisible(false); - menu.findItem(R.id.action_invite_to_existing).setVisible(true); - } else if (!inviteIntent) { - menu.findItem(R.id.action_start_conversation).setVisible(true); - menu.findItem(R.id.action_contact_details).setVisible(false); - menu.findItem(R.id.action_invite).setVisible(false); - menu.findItem(R.id.action_invite_to_existing).setVisible(true); - } else { - menu.findItem(R.id.action_invite).setVisible(true); - menu.findItem(R.id.action_start_conversation).setVisible(false); - menu.findItem(R.id.action_contact_details).setVisible(false); - menu.findItem(R.id.action_invite_to_existing).setVisible(false); - } - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - // TODO Auto-generated method stub - - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - switch (item.getItemId()) { - case R.id.action_start_conversation: - if (selectedContacts.size() == 1) { - startConversation(selectedContacts.get(0)); - } else { - startConference(); - } - break; - case R.id.action_contact_details: - Intent intent = new Intent(getApplicationContext(), - ContactDetailsActivity.class); - intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT); - intent.putExtra("account", selectedContacts.get(0).getAccount().getJid()); - intent.putExtra("contact",selectedContacts.get(0).getJid()); - startActivity(intent); - finish(); - break; - case R.id.action_invite: - invite(); - break; - case R.id.action_invite_to_existing: - final List<Conversation> mucs = new ArrayList<Conversation>(); - for(Conversation conv : xmppConnectionService.getConversations()) { - if (conv.getMode() == Conversation.MODE_MULTI) { - mucs.add(conv); - } - } - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(getString(R.string.invite_contacts_to_existing)); - if (mucs.size() >= 1) { - String[] options = new String[mucs.size()]; - for(int i = 0; i < options.length; ++i) { - options[i] = mucs.get(i).getName(useSubject); - } - builder.setItems(options, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Conversation conversation = mucs.get(which); - if (isOnline(conversation.getAccount())) { - xmppConnectionService.inviteToConference(conversation, selectedContacts); - Toast.makeText(activity, getString(R.string.invitation_sent), Toast.LENGTH_SHORT).show(); - actionMode.finish(); - } - } - }); - } else { - builder.setMessage(getString(R.string.no_open_mucs)); - } - builder.setNegativeButton(getString(R.string.cancel),null); - builder.create().show(); - break; - default: - break; - } - return false; - } - - @Override - public void onItemCheckedStateChanged(ActionMode mode, int position, - long id, boolean checked) { - } - }; - - private boolean isOnline(Account account) { - if (account.getStatus() == Account.STATUS_ONLINE) { - return true; - } else { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.account_offline)); - builder.setMessage(getString(R.string.cant_invite_while_offline)); - builder.setNegativeButton(getString(R.string.ok), null); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.create().show(); - return false; - } - } - - private void invite() { - List<Conversation> conversations = xmppConnectionService - .getConversations(); - Conversation conversation = null; - for (Conversation tmpConversation : conversations) { - if (tmpConversation.getUuid().equals( - getIntent().getStringExtra("uuid"))) { - conversation = tmpConversation; - break; - } - } - if (conversation != null) { - xmppConnectionService.inviteToConference(conversation, - selectedContacts); - } - finish(); - } - - private void startConference() { - if (accounts.size() > 1) { - getAccountChooser(new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - startConference(accounts.get(which)); - } - }).show(); - } else { - startConference(accounts.get(0)); - } - - } - - private void startConference(final Account account) { - if (isOnline(account)) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.new_conference)); - builder.setMessage(getString(R.string.new_conference_explained)); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.create_invite), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - String mucName = CryptoHelper.randomMucName(xmppConnectionService.getRNG()); - String serverName = account.getXmppConnection() - .getMucServer(); - if (serverName==null) { - List<String> servers = getMucServers(); - if (servers.size() >= 1) { - serverName = servers.get(0); - } else { - displayErrorDialog(R.string.no_muc_server_found); - return; - } - } - String jid = mucName + "@" + serverName; - Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, jid, true); - StringBuilder subject = new StringBuilder(); - subject.append(account.getUsername() + ", "); - for (int i = 0; i < selectedContacts.size(); ++i) { - if (i + 1 != selectedContacts.size()) { - subject.append(selectedContacts.get(i) - .getDisplayName() + ", "); - } else { - subject.append(selectedContacts.get(i) - .getDisplayName()); - } - } - xmppConnectionService.sendConversationSubject( - conversation, subject.toString()); - xmppConnectionService.inviteToConference(conversation, - selectedContacts); - switchToConversation(conversation, null,false); - } - }); - builder.create().show(); - } - } - - protected void updateAggregatedContacts() { - - aggregatedContacts.clear(); - for (Contact contact : rosterContacts) { - if (contact.match(searchString)&&(contact.showInRoster())) - aggregatedContacts.add(contact); - } - - Collections.sort(aggregatedContacts, new Comparator<Contact>() { - - @SuppressLint("DefaultLocale") - @Override - public int compare(Contact lhs, Contact rhs) { - return lhs.getDisplayName().toLowerCase() - .compareTo(rhs.getDisplayName().toLowerCase()); - } - }); - - if (aggregatedContacts.size() == 0) { - - if (Validator.isValidJid(searchString)) { - Contact newContact = new Contact(searchString); - newContact.resetOption(Contact.Options.IN_ROSTER); - aggregatedContacts.add(newContact); - contactsHeader.setText(getString(R.string.new_contact)); - } else { - contactsHeader.setText(getString(R.string.contacts)); - } - } else { - contactsHeader.setText(getString(R.string.contacts)); - } - - contactsAdapter.notifyDataSetChanged(); - contactsView.setScrollX(0); - } - - private OnItemLongClickListener onLongClickListener = new OnItemLongClickListener() { - - @Override - public boolean onItemLongClick(AdapterView<?> arg0, View view, - int position, long arg3) { - if (!isActionMode) { - contactsView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - contactsView.setItemChecked(position, true); - actionMode = contactsView.startActionMode(actionModeCallback); - } - return true; - } - }; - - @Override - protected void onStart() { - super.onStart(); - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - this.useSubject = preferences.getBoolean("use_subject_in_muc", true); - inviteIntent = "invite".equals(getIntent().getAction()); - if (inviteIntent) { - contactsHeader.setVisibility(View.GONE); - actionMode = contactsView.startActionMode(actionModeCallback); - search.setVisibility(View.GONE); - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_new_conversation); - - contactsHeader = (TextView) findViewById(R.id.contacts_header); - - search = (EditText) findViewById(R.id.new_conversation_search); - search.addTextChangedListener(new TextWatcher() { - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - searchString = search.getText().toString(); - updateAggregatedContacts(); - } - - @Override - public void afterTextChanged(Editable s) { - // TODO Auto-generated method stub - - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - // TODO Auto-generated method stub - - } - }); - - contactsView = (ListView) findViewById(R.id.contactList); - contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(), - R.layout.contact, aggregatedContacts) { - @Override - public View getView(int position, View view, ViewGroup parent) { - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - Contact contact = getItem(position); - if (view == null) { - view = (View) inflater.inflate(R.layout.contact, null); - } - - ((TextView) view.findViewById(R.id.contact_display_name)) - .setText(getItem(position).getDisplayName()); - TextView contactJid = (TextView) view - .findViewById(R.id.contact_jid); - contactJid.setText(contact.getJid()); - ImageView imageView = (ImageView) view - .findViewById(R.id.contact_photo); - imageView.setImageBitmap(UIHelper.getContactPicture(contact, 48, this.getContext(), false)); - return view; - } - }; - contactsView.setAdapter(contactsAdapter); - contactsView.setMultiChoiceModeListener(actionModeCallback); - contactsView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, final View view, - int pos, long arg3) { - if (!isActionMode) { - Contact clickedContact = aggregatedContacts.get(pos); - startConversation(clickedContact); - - } else { - actionMode.invalidate(); - } - } - }); - contactsView.setOnItemLongClickListener(this.onLongClickListener); - } - - public void startConversation(final Contact contact) { - if ((contact.getAccount() == null) && (accounts.size() > 1)) { - getAccountChooser(new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - contact.setAccount(accounts.get(which)); - showIsMucDialogIfNeeded(contact); - } - }).show(); - } else { - if (contact.getAccount() == null) { - contact.setAccount(accounts.get(0)); - } - showIsMucDialogIfNeeded(contact); - } - } - - protected AlertDialog getAccountChooser(OnClickListener listener) { - String[] accountList = new String[accounts.size()]; - for (int i = 0; i < accounts.size(); ++i) { - accountList[i] = accounts.get(i).getJid(); - } - - AlertDialog.Builder accountChooser = new AlertDialog.Builder(this); - accountChooser.setTitle(getString(R.string.choose_account)); - accountChooser.setItems(accountList, listener); - return accountChooser.create(); - } - - public void showIsMucDialogIfNeeded(final Contact clickedContact) { - if (isMuc(clickedContact)) { - startConversation(clickedContact,clickedContact.getAccount(), true); - } else if (clickedContact.couldBeMuc()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(this); - dialog.setTitle(getString(R.string.multi_user_conference)); - dialog.setMessage(getString(R.string.trying_join_conference)); - dialog.setPositiveButton(getString(R.string.yes), new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - startConversation(clickedContact, - clickedContact.getAccount(), true); - } - }); - dialog.setNegativeButton(getString(R.string.no), new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - startConversation(clickedContact, - clickedContact.getAccount(), false); - } - }); - dialog.create().show(); - } else { - startConversation(clickedContact, clickedContact.getAccount(), - false); - } - } - - private List<String> getMucServers() { - ArrayList<String> mucServers = new ArrayList<String>(); - for(Account account : accounts) { - if (account.getXmppConnection()!=null) { - String server = account.getXmppConnection().getMucServer(); - if (server!=null) { - mucServers.add(server); - } - } - } - return mucServers; - } - - private boolean isMuc(Contact contact) { - String[] parts = contact.getJid().split("@"); - if (parts.length != 2) { - return false; - } - return getMucServers().contains(parts[1]); - } - - public void startConversation(Contact contact, Account account, boolean muc) { - if (!contact.getOption(Contact.Options.IN_ROSTER)&&(!muc)) { - xmppConnectionService.createContact(contact); - } - Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, contact.getJid(), muc); - - switchToConversation(conversation, null,false); - } - - @Override - void onBackendConnected() { - this.accounts = xmppConnectionService.getAccounts(); - if (Intent.ACTION_SENDTO.equals(getIntent().getAction())) { - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - String jid; - try { - jid = URLDecoder.decode(getIntent().getData().getEncodedPath(), - "UTF-8").split("/")[1]; - } catch (UnsupportedEncodingException e) { - jid = null; - } - if (jid != null) { - final String finalJid = jid; - if (this.accounts.size() > 1) { - getAccountChooser(new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Conversation conversation = xmppConnectionService - .findOrCreateConversation( - accounts.get(which), finalJid, - false); - switchToConversation(conversation, null,false); - finish(); - } - }).show(); - } else { - Conversation conversation = xmppConnectionService - .findOrCreateConversation(this.accounts.get(0), - jid, false); - switchToConversation(conversation, null,false); - finish(); - } - } - } - - if (xmppConnectionService.getConversationCount() == 0) { - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - } - this.rosterContacts.clear(); - for(Account account : accounts) { - if (account.getStatus() != Account.STATUS_DISABLED) { - rosterContacts.addAll(account.getRoster().getContacts()); - } - } - updateAggregatedContacts(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.newconversation, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - default: - break; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onActionModeStarted(ActionMode mode) { - super.onActionModeStarted(mode); - this.isActionMode = true; - search.setEnabled(false); - } - - @Override - public void onActionModeFinished(ActionMode mode) { - super.onActionModeFinished(mode); - if (inviteIntent) { - finish(); - } else { - this.isActionMode = false; - contactsView.clearChoices(); - contactsView.requestLayout(); - contactsView.post(new Runnable() { - @Override - public void run() { - contactsView.setChoiceMode(ListView.CHOICE_MODE_NONE); - } - }); - search.setEnabled(true); - } - } - -} diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 03ced289..05b7cb4a 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -10,6 +10,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.ImageProvider; +import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.UIHelper; import android.net.Uri; @@ -83,10 +84,10 @@ public class ConversationActivity extends XmppActivity { private boolean showLastseen = false; private ArrayAdapter<Conversation> listAdapter; - private OnConversationListChangedListener onConvChanged = new OnConversationListChangedListener() { - + private OnConversationUpdate onConvChanged = new OnConversationUpdate() { + @Override - public void onConversationListChanged() { + public void onConversationUpdate() { runOnUiThread(new Runnable() { @Override @@ -97,7 +98,7 @@ public class ConversationActivity extends XmppActivity { swapConversationFragment(); } else { startActivity(new Intent(getApplicationContext(), - ContactsActivity.class)); + StartConversationActivity.class)); finish(); } } @@ -305,23 +306,26 @@ public class ConversationActivity extends XmppActivity { .findItem(R.id.action_muc_details); MenuItem menuContactDetails = (MenuItem) menu .findItem(R.id.action_contact_details); - MenuItem menuInviteContacts = (MenuItem) menu - .findItem(R.id.action_invite); MenuItem menuAttach = (MenuItem) menu.findItem(R.id.action_attach_file); MenuItem menuClearHistory = (MenuItem) menu .findItem(R.id.action_clear_history); + MenuItem menuManageAccounts = (MenuItem) menu.findItem(R.id.action_accounts); + MenuItem menuSettings = (MenuItem) menu.findItem(R.id.action_settings); + MenuItem menuAdd = (MenuItem) menu.findItem(R.id.action_add); + MenuItem menuInviteContact = (MenuItem) menu.findItem(R.id.action_invite); if ((spl.isOpen() && (spl.isSlideable()))) { menuArchive.setVisible(false); menuMucDetails.setVisible(false); menuContactDetails.setVisible(false); menuSecure.setVisible(false); - menuInviteContacts.setVisible(false); + menuInviteContact.setVisible(false); menuAttach.setVisible(false); menuClearHistory.setVisible(false); } else { - ((MenuItem) menu.findItem(R.id.action_add)).setVisible(!spl - .isSlideable()); + menuAdd.setVisible(!spl.isSlideable()); + menuSettings.setVisible(!spl.isSlideable()); + menuManageAccounts.setVisible(!spl.isSlideable()); if (this.getSelectedConversation() != null) { if (this.getSelectedConversation().getLatestMessage() .getEncryption() != Message.ENCRYPTION_NONE) { @@ -332,7 +336,7 @@ public class ConversationActivity extends XmppActivity { menuAttach.setVisible(false); } else { menuMucDetails.setVisible(false); - menuInviteContacts.setVisible(false); + menuInviteContact.setVisible(false); } } } @@ -419,37 +423,6 @@ public class ConversationActivity extends XmppActivity { selectPresenceToAttachFile(attachmentChoice); } else { selectPresenceToAttachFile(attachmentChoice); - /*AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.otr_file_transfer)); - builder.setMessage(getString(R.string.otr_file_transfer_msg)); - builder.setNegativeButton(getString(R.string.cancel), null); - if (conversation.getContact().getPgpKeyId() == 0) { - builder.setPositiveButton(getString(R.string.send_unencrypted), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation - .setNextEncryption(Message.ENCRYPTION_NONE); - attachFile(attachmentChoice); - } - }); - } else { - builder.setPositiveButton( - getString(R.string.use_pgp_encryption), - new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation - .setNextEncryption(Message.ENCRYPTION_PGP); - attachFile(attachmentChoice); - } - }); - } - builder.create().show();*/ } } @@ -488,7 +461,7 @@ public class ConversationActivity extends XmppActivity { attachFilePopup.show(); break; case R.id.action_add: - startActivity(new Intent(this, ContactsActivity.class)); + startActivity(new Intent(this, StartConversationActivity.class)); break; case R.id.action_archive: this.endConversation(getSelectedConversation()); @@ -496,28 +469,19 @@ public class ConversationActivity extends XmppActivity { case R.id.action_contact_details: Contact contact = this.getSelectedConversation().getContact(); if (contact.showInRoster()) { - Intent intent = new Intent(this, ContactDetailsActivity.class); - intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT); - intent.putExtra("account", this.getSelectedConversation() - .getAccount().getJid()); - intent.putExtra("contact", contact.getJid()); - startActivity(intent); + switchToContactDetails(contact); } else { showAddToRosterDialog(getSelectedConversation()); } break; case R.id.action_muc_details: - Intent intent = new Intent(this, MucDetailsActivity.class); - intent.setAction(MucDetailsActivity.ACTION_VIEW_MUC); + Intent intent = new Intent(this, ConferenceDetailsActivity.class); + intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); intent.putExtra("uuid", getSelectedConversation().getUuid()); startActivity(intent); break; case R.id.action_invite: - Intent inviteIntent = new Intent(getApplicationContext(), - ContactsActivity.class); - inviteIntent.setAction("invite"); - inviteIntent.putExtra("uuid", getSelectedConversation().getUuid()); - startActivity(inviteIntent); + inviteToConversation(getSelectedConversation()); break; case R.id.action_security: final Conversation conversation = getSelectedConversation(); @@ -604,7 +568,7 @@ public class ConversationActivity extends XmppActivity { return super.onOptionsItemSelected(item); } - private void endConversation(Conversation conversation) { + public void endConversation(Conversation conversation) { conversation.setStatus(Conversation.STATUS_ARCHIVED); paneShouldBeOpen = true; spl.openPane(); @@ -691,7 +655,7 @@ public class ConversationActivity extends XmppActivity { this.onBackendConnected(); } if (conversationList.size() >= 1) { - onConvChanged.onConversationListChanged(); + onConvChanged.onConversationUpdate(); } } @@ -734,7 +698,7 @@ public class ConversationActivity extends XmppActivity { finish(); } else if (conversationList.size() <= 0) { // add no history - startActivity(new Intent(this, ContactsActivity.class)); + startActivity(new Intent(this, StartConversationActivity.class)); finish(); } else { spl.openPane(); @@ -768,7 +732,7 @@ public class ConversationActivity extends XmppActivity { ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() .findFragmentByTag("conversation"); if (selectedFragment != null) { - selectedFragment.hidePgpPassphraseBox(); + selectedFragment.hideSnackbar(); } } else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) { attachImageToConversation(getSelectedConversation(), @@ -841,8 +805,7 @@ public class ConversationActivity extends XmppActivity { } public void updateConversationList() { - conversationList.clear(); - conversationList.addAll(xmppConnectionService.getConversations()); + xmppConnectionService.populateWithOrderedConversations(conversationList); listView.invalidateViews(); } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 1e703b48..2a306529 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -8,13 +8,14 @@ import java.util.Set; import net.java.otr4j.session.SessionStatus; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.entities.MucOptions.OnRenameListener; import eu.siacs.conversations.services.ImageProvider; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jingle.JingleConnection; import android.app.AlertDialog; @@ -48,6 +49,7 @@ import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -61,10 +63,16 @@ public class ConversationFragment extends Fragment { protected Contact contact; protected BitmapCache mBitmapCache = new BitmapCache(); + protected int mPrimaryTextColor; + protected int mSecondaryTextColor; + protected String queuedPqpMessage = null; private EditText chatMsg; private String pastedText = null; + private RelativeLayout snackbar; + private TextView snackbarMessage; + private TextView snackbarAction; protected Bitmap selfBitmap; @@ -107,20 +115,26 @@ public class ConversationFragment extends Fragment { } }; - private LinearLayout pgpInfo; - private LinearLayout mucError; - private TextView mucErrorText; private OnClickListener clickToMuc = new OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(getActivity(), MucDetailsActivity.class); - intent.setAction(MucDetailsActivity.ACTION_VIEW_MUC); + Intent intent = new Intent(getActivity(), + ConferenceDetailsActivity.class); + intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC); intent.putExtra("uuid", conversation.getUuid()); startActivity(intent); } }; + private OnClickListener leaveMuc = new OnClickListener() { + + @Override + public void onClick(View v) { + activity.endConversation(conversation); + } + }; + private OnScrollListener mOnScrollListener = new OnScrollListener() { @Override @@ -149,10 +163,6 @@ public class ConversationFragment extends Fragment { private ConversationActivity activity; - public void hidePgpPassphraseBox() { - pgpInfo.setVisibility(View.GONE); - } - public void updateChatMsgHint() { switch (conversation.getNextEncryption()) { case Message.ENCRYPTION_NONE: @@ -177,19 +187,29 @@ public class ConversationFragment extends Fragment { this.inflater = inflater; + mPrimaryTextColor = getResources().getColor(R.color.primarytext); + mSecondaryTextColor = getResources().getColor(R.color.secondarytext); + final View view = inflater.inflate(R.layout.fragment_conversation, container, false); chatMsg = (EditText) view.findViewById(R.id.textinput); + chatMsg.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + if (activity.getSlidingPaneLayout().isSlideable()) { + activity.getSlidingPaneLayout().closePane(); + } + } + }); ImageButton sendButton = (ImageButton) view .findViewById(R.id.textSendButton); sendButton.setOnClickListener(this.sendMsgListener); - pgpInfo = (LinearLayout) view.findViewById(R.id.pgp_keyentry); - pgpInfo.setOnClickListener(clickToDecryptListener); - mucError = (LinearLayout) view.findViewById(R.id.muc_error); - mucError.setOnClickListener(clickToMuc); - mucErrorText = (TextView) view.findViewById(R.id.muc_error_msg); + snackbar = (RelativeLayout) view.findViewById(R.id.snackbar); + snackbarMessage = (TextView) view.findViewById(R.id.snackbar_message); + snackbarAction = (TextView) view.findViewById(R.id.snackbar_action); messagesView = (ListView) view.findViewById(R.id.messages_view); messagesView.setOnScrollListener(mOnScrollListener); @@ -264,7 +284,7 @@ public class ConversationFragment extends Fragment { if (error) { viewHolder.time.setTextColor(0xFFe92727); } else { - viewHolder.time.setTextColor(0xFF8e8e8e); + viewHolder.time.setTextColor(mSecondaryTextColor); } if (message.getEncryption() == Message.ENCRYPTION_NONE) { viewHolder.indicator.setVisibility(View.GONE); @@ -341,7 +361,7 @@ public class ConversationFragment extends Fragment { } else { viewHolder.messageBody.setText(""); } - viewHolder.messageBody.setTextColor(0xff333333); + viewHolder.messageBody.setTextColor(mPrimaryTextColor); viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); viewHolder.messageBody.setTextIsSelectable(true); } @@ -474,6 +494,13 @@ public class ConversationFragment extends Fragment { getActivity() .getApplicationContext())); viewHolder.contact_picture.setAlpha(128); + viewHolder.contact_picture.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + Toast.makeText(getActivity(), R.string.contact_has_read_up_to_this_point, Toast.LENGTH_SHORT).show(); + } + }); } break; @@ -644,34 +671,6 @@ public class ConversationFragment extends Fragment { activity.invalidateOptionsMenu(); } } - if (conversation.getMode() == Conversation.MODE_MULTI) { - activity.xmppConnectionService - .setOnRenameListener(new OnRenameListener() { - - @Override - public void onRename(final boolean success) { - activity.xmppConnectionService - .updateConversation(conversation); - getActivity().runOnUiThread(new Runnable() { - - @Override - public void run() { - if (success) { - Toast.makeText( - getActivity(), - getString(R.string.your_nick_has_been_changed), - Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText( - getActivity(), - getString(R.string.nick_in_use), - Toast.LENGTH_SHORT).show(); - } - } - }); - } - }); - } } private void decryptMessage(Message message) { @@ -682,7 +681,8 @@ public class ConversationFragment extends Fragment { @Override public void userInputRequried(PendingIntent pi, Message message) { askForPassphraseIntent = pi.getIntentSender(); - pgpInfo.setVisibility(View.VISIBLE); + showSnackbar(R.string.openpgp_messages_found, + R.string.decrypt, clickToDecryptListener); } @Override @@ -698,8 +698,6 @@ public class ConversationFragment extends Fragment { // updateMessages(); } }); - } else { - pgpInfo.setVisibility(View.GONE); } } @@ -707,8 +705,20 @@ public class ConversationFragment extends Fragment { if (getView() == null) { return; } - ConversationActivity activity = (ConversationActivity) getActivity(); + hideSnackbar(); + final ConversationActivity activity = (ConversationActivity) getActivity(); if (this.conversation != null) { + final Contact contact = this.conversation.getContact(); + if (!contact.showInRoster() && contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { + showSnackbar(R.string.contact_added_you, R.string.add_back, new OnClickListener() { + + @Override + public void onClick(View v) { + activity.xmppConnectionService.createContact(contact); + activity.switchToContactDetails(contact); + } + }); + } for (Message message : this.conversation.getMessages()) { if ((message.getEncryption() == Message.ENCRYPTION_PGP) && ((message.getStatus() == Message.STATUS_RECIEVED) || (message @@ -735,13 +745,15 @@ public class ConversationFragment extends Fragment { makeFingerprintWarning(conversation.getLatestEncryption()); } } else { - if (conversation.getMucOptions().getError() != 0) { - mucError.setVisibility(View.VISIBLE); + if (!conversation.getMucOptions().online() + && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { if (conversation.getMucOptions().getError() == MucOptions.ERROR_NICK_IN_USE) { - mucErrorText.setText(getString(R.string.nick_in_use)); + showSnackbar(R.string.nick_in_use, R.string.edit, + clickToMuc); + } else if (conversation.getMucOptions().getError() == MucOptions.ERROR_ROOM_NOT_FOUND) { + showSnackbar(R.string.conference_not_found, + R.string.leave, leaveMuc); } - } else { - mucError.setVisibility(View.GONE); } } getActivity().invalidateOptionsMenu(); @@ -789,35 +801,41 @@ public class ConversationFragment extends Fragment { } protected void makeFingerprintWarning(int latestEncryption) { - final LinearLayout fingerprintWarning = (LinearLayout) getView() - .findViewById(R.id.new_fingerprint); Set<String> knownFingerprints = conversation.getContact() .getOtrFingerprints(); if ((latestEncryption == Message.ENCRYPTION_OTR) && (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints .contains(conversation.getOtrFingerprint())))) { - fingerprintWarning.setVisibility(View.VISIBLE); - TextView fingerprint = (TextView) getView().findViewById( - R.id.otr_fingerprint); - fingerprint.setText(conversation.getOtrFingerprint()); - fingerprintWarning.setOnClickListener(new OnClickListener() { + showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, + new OnClickListener() { - @Override - public void onClick(View v) { - if (conversation.getOtrFingerprint() != null) { - AlertDialog dialog = UIHelper.getVerifyFingerprintDialog( - (ConversationActivity) getActivity(), conversation, - fingerprintWarning); - dialog.show(); - } - } - }); - } else { - fingerprintWarning.setVisibility(View.GONE); + @Override + public void onClick(View v) { + if (conversation.getOtrFingerprint() != null) { + AlertDialog dialog = UIHelper + .getVerifyFingerprintDialog( + (ConversationActivity) getActivity(), + conversation, snackbar); + dialog.show(); + } + } + }); } } + protected void showSnackbar(int message, int action, + OnClickListener clickListener) { + snackbar.setVisibility(View.VISIBLE); + snackbarMessage.setText(message); + snackbarAction.setText(action); + snackbarAction.setOnClickListener(clickListener); + } + + protected void hideSnackbar() { + snackbar.setVisibility(View.GONE); + } + protected void sendPlainTextMessage(Message message) { ConversationActivity activity = (ConversationActivity) getActivity(); activity.xmppConnectionService.sendMessage(message); diff --git a/src/eu/siacs/conversations/ui/EditAccount.java b/src/eu/siacs/conversations/ui/EditAccountDialog.java index e1bcaeb5..7c135fc1 100644 --- a/src/eu/siacs/conversations/ui/EditAccount.java +++ b/src/eu/siacs/conversations/ui/EditAccountDialog.java @@ -1,14 +1,19 @@ package eu.siacs.conversations.ui; +import java.util.List; + import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.utils.Validator; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; +import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -16,9 +21,11 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.TextView; -public class EditAccount extends DialogFragment { +public class EditAccountDialog extends DialogFragment { protected Account account; + + protected AutoCompleteTextView mAccountJid; public void setAccount(Account account) { this.account = account; @@ -30,16 +37,28 @@ public class EditAccount extends DialogFragment { protected EditAccountListener listener = null; + private KnownHostsAdapter mKnownHostsAdapter; + public void setEditAccountListener(EditAccountListener listener) { this.listener = listener; } + + public void setKnownHosts(List<String> hosts, Context context) { + this.mKnownHostsAdapter = new KnownHostsAdapter(context, android.R.layout.simple_list_item_1, hosts); + if (this.mAccountJid != null) { + this.mAccountJid.setAdapter(this.mKnownHostsAdapter); + } + } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.edit_account_dialog, null); - final EditText jidText = (EditText) view.findViewById(R.id.account_jid); + mAccountJid = (AutoCompleteTextView) view.findViewById(R.id.account_jid); + if (this.mKnownHostsAdapter!=null) { + mAccountJid.setAdapter(this.mKnownHostsAdapter); + } final TextView confirmPwDesc = (TextView) view .findViewById(R.id.account_confirm_password_desc); @@ -51,7 +70,7 @@ public class EditAccount extends DialogFragment { .findViewById(R.id.edit_account_register_new); if (account != null) { - jidText.setText(account.getJid()); + mAccountJid.setText(account.getJid()); password.setText(account.getPassword()); if (account.isOptionSet(Account.OPTION_REGISTER)) { registerAccount.setChecked(true); diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java index c52916a2..6fa1ec31 100644 --- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -5,7 +5,8 @@ import java.util.List; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.ui.EditAccount.EditAccountListener; +import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; +import eu.siacs.conversations.ui.EditAccountDialog.EditAccountListener; import eu.siacs.conversations.xmpp.OnTLSExceptionReceived; import eu.siacs.conversations.xmpp.XmppConnection; import android.app.Activity; @@ -31,21 +32,21 @@ import android.widget.ListView; import android.widget.TextView; public class ManageAccountActivity extends XmppActivity { - + protected boolean isActionMode = false; protected ActionMode actionMode; protected Account selectedAccountForActionMode = null; protected ManageAccountActivity activity = this; - + protected boolean firstrun = true; - + protected List<Account> accountList = new ArrayList<Account>(); protected ListView accountListView; protected ArrayAdapter<Account> accountListViewAdapter; - protected OnAccountListChangedListener accountChanged = new OnAccountListChangedListener() { + protected OnAccountUpdate accountChanged = new OnAccountUpdate() { @Override - public void onAccountListChangedListener() { + public void onAccountUpdate() { accountList.clear(); accountList.addAll(xmppConnectionService.getAccounts()); runOnUiThread(new Runnable() { @@ -57,47 +58,55 @@ public class ManageAccountActivity extends XmppActivity { }); } }; - + protected OnTLSExceptionReceived tlsExceptionReceived = new OnTLSExceptionReceived() { - + @Override - public void onTLSExceptionReceived(final String fingerprint, final Account account) { + public void onTLSExceptionReceived(final String fingerprint, + final Account account) { activity.runOnUiThread(new Runnable() { - + @Override public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + AlertDialog.Builder builder = new AlertDialog.Builder( + activity); builder.setTitle(getString(R.string.account_status_error)); builder.setIconAttribute(android.R.attr.alertDialogIcon); - View view = (View) getLayoutInflater().inflate(R.layout.cert_warning, null); + View view = (View) getLayoutInflater().inflate( + R.layout.cert_warning, null); TextView sha = (TextView) view.findViewById(R.id.sha); TextView hint = (TextView) view.findViewById(R.id.hint); StringBuilder humanReadableSha = new StringBuilder(); humanReadableSha.append(fingerprint); - for(int i = 2; i < 59; i += 3) { - if ((i==14)||(i==29)||(i==44)) { + for (int i = 2; i < 59; i += 3) { + if ((i == 14) || (i == 29) || (i == 44)) { humanReadableSha.insert(i, "\n"); } else { humanReadableSha.insert(i, ":"); } - + } - hint.setText(getString(R.string.untrusted_cert_hint,account.getServer())); + hint.setText(getString(R.string.untrusted_cert_hint, + account.getServer())); sha.setText(humanReadableSha.toString()); builder.setView(view); - builder.setNegativeButton(getString(R.string.certif_no_trust), null); - builder.setPositiveButton(getString(R.string.certif_trust), new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - account.setSSLCertFingerprint(fingerprint); - activity.xmppConnectionService.updateAccount(account); - } - }); + builder.setNegativeButton( + getString(R.string.certif_no_trust), null); + builder.setPositiveButton(getString(R.string.certif_trust), + new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, + int which) { + account.setSSLCertFingerprint(fingerprint); + activity.xmppConnectionService + .updateAccount(account); + } + }); builder.create().show(); } }); - + } }; @@ -124,55 +133,68 @@ public class ManageAccountActivity extends XmppActivity { .findViewById(R.id.account_status); switch (account.getStatus()) { case Account.STATUS_DISABLED: - statusView.setText(getString(R.string.account_status_disabled)); + statusView + .setText(getString(R.string.account_status_disabled)); statusView.setTextColor(0xFF1da9da); break; case Account.STATUS_ONLINE: - statusView.setText(getString(R.string.account_status_online)); + statusView + .setText(getString(R.string.account_status_online)); statusView.setTextColor(0xFF83b600); break; case Account.STATUS_CONNECTING: - statusView.setText(getString(R.string.account_status_connecting)); + statusView + .setText(getString(R.string.account_status_connecting)); statusView.setTextColor(0xFF1da9da); break; case Account.STATUS_OFFLINE: - statusView.setText(getString(R.string.account_status_offline)); + statusView + .setText(getString(R.string.account_status_offline)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_UNAUTHORIZED: - statusView.setText(getString(R.string.account_status_unauthorized)); + statusView + .setText(getString(R.string.account_status_unauthorized)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_SERVER_NOT_FOUND: - statusView.setText(getString(R.string.account_status_not_found)); + statusView + .setText(getString(R.string.account_status_not_found)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_NO_INTERNET: - statusView.setText(getString(R.string.account_status_no_internet)); + statusView + .setText(getString(R.string.account_status_no_internet)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_SERVER_REQUIRES_TLS: - statusView.setText(getString(R.string.account_status_requires_tls)); + statusView + .setText(getString(R.string.account_status_requires_tls)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_TLS_ERROR: - statusView.setText(getString(R.string.account_status_error)); + statusView + .setText(getString(R.string.account_status_error)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_REGISTRATION_FAILED: - statusView.setText(getString(R.string.account_status_regis_fail)); + statusView + .setText(getString(R.string.account_status_regis_fail)); statusView.setTextColor(0xFFe92727); break; case Account.STATUS_REGISTRATION_CONFLICT: - statusView.setText(getString(R.string.account_status_regis_conflict)); + statusView + .setText(getString(R.string.account_status_regis_conflict)); statusView.setTextColor(0xFFe92727); break; - case Account.STATUS_REGISTRATION_SUCCESSFULL: - statusView.setText(getString(R.string.account_status_regis_success)); + case Account.STATUS_REGISTRATION_SUCCESSFULL: + statusView + .setText(getString(R.string.account_status_regis_success)); statusView.setTextColor(0xFF83b600); break; case Account.STATUS_REGISTRATION_NOT_SUPPORTED: - statusView.setText(getString(R.string.account_status_regis_not_sup)); + statusView + .setText(getString(R.string.account_status_regis_not_sup)); statusView.setTextColor(0xFFe92727); break; default: @@ -192,10 +214,14 @@ public class ManageAccountActivity extends XmppActivity { int position, long arg3) { if (!isActionMode) { Account account = accountList.get(position); - if ((account.getStatus() == Account.STATUS_OFFLINE)||(account.getStatus() == Account.STATUS_TLS_ERROR)) { - activity.xmppConnectionService.reconnectAccount(accountList.get(position),true); + if ((account.getStatus() == Account.STATUS_OFFLINE) + || (account.getStatus() == Account.STATUS_TLS_ERROR)) { + activity.xmppConnectionService.reconnectAccount( + accountList.get(position), true); } else if (account.getStatus() == Account.STATUS_ONLINE) { - activity.startActivity(new Intent(activity.getApplicationContext(),ContactsActivity.class)); + activity.startActivity(new Intent(activity + .getApplicationContext(), + StartConversationActivity.class)); } else if (account.getStatus() != Account.STATUS_DISABLED) { editAccount(account); } @@ -205,159 +231,242 @@ public class ManageAccountActivity extends XmppActivity { } } }); - accountListView.setOnItemLongClickListener(new OnItemLongClickListener() { + accountListView + .setOnItemLongClickListener(new OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView<?> arg0, View view, - int position, long arg3) { - if (!isActionMode) { - accountListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); - accountListView.setItemChecked(position,true); - selectedAccountForActionMode = accountList.get(position); - actionMode = activity.startActionMode((new ActionMode.Callback() { - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - if (selectedAccountForActionMode.isOptionSet(Account.OPTION_DISABLED)) { - menu.findItem(R.id.mgmt_account_enable).setVisible(true); - menu.findItem(R.id.mgmt_account_disable).setVisible(false); - } else { - menu.findItem(R.id.mgmt_account_disable).setVisible(true); - menu.findItem(R.id.mgmt_account_enable).setVisible(false); - } - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - // TODO Auto-generated method stub - - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - MenuInflater inflater = mode.getMenuInflater(); - inflater.inflate(R.menu.manageaccounts_context, menu); - return true; - } - - @Override - public boolean onActionItemClicked(final ActionMode mode, MenuItem item) { - if (item.getItemId()==R.id.mgmt_account_edit) { - editAccount(selectedAccountForActionMode); - } else if (item.getItemId()==R.id.mgmt_account_disable) { - selectedAccountForActionMode.setOption(Account.OPTION_DISABLED, true); - xmppConnectionService.updateAccount(selectedAccountForActionMode); - mode.finish(); - } else if (item.getItemId()==R.id.mgmt_account_enable) { - selectedAccountForActionMode.setOption(Account.OPTION_DISABLED, false); - xmppConnectionService.updateAccount(selectedAccountForActionMode); - mode.finish(); - } else if (item.getItemId()==R.id.mgmt_account_delete) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(getString(R.string.mgmt_account_are_you_sure)); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text)); - builder.setPositiveButton(getString(R.string.delete), new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - xmppConnectionService.deleteAccount(selectedAccountForActionMode); - selectedAccountForActionMode = null; - mode.finish(); - } - }); - builder.setNegativeButton(getString(R.string.cancel),null); - builder.create().show(); - } else if (item.getItemId()==R.id.mgmt_account_announce_pgp) { - if (activity.hasPgp()) { - mode.finish(); - announcePgp(selectedAccountForActionMode,null); - } else { - activity.showInstallPgpDialog(); - } - } else if (item.getItemId() == R.id.mgmt_otr_key) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle("OTR Fingerprint"); - String fingerprintTxt = selectedAccountForActionMode.getOtrFingerprint(getApplicationContext()); - View view = (View) getLayoutInflater().inflate(R.layout.otr_fingerprint, null); - if (fingerprintTxt!=null) { - TextView fingerprint = (TextView) view.findViewById(R.id.otr_fingerprint); - TextView noFingerprintView = (TextView) view.findViewById(R.id.otr_no_fingerprint); - fingerprint.setText(fingerprintTxt); - fingerprint.setVisibility(View.VISIBLE); - noFingerprintView.setVisibility(View.GONE); - } - builder.setView(view); - builder.setPositiveButton(getString(R.string.done), null); - builder.create().show(); - } else if (item.getItemId() == R.id.mgmt_account_info) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(getString(R.string.account_info)); - if (selectedAccountForActionMode.getStatus() == Account.STATUS_ONLINE) { - XmppConnection xmpp = selectedAccountForActionMode.getXmppConnection(); - long connectionAge = (SystemClock.elapsedRealtime() - xmpp.lastConnect) / 60000; - long sessionAge = (SystemClock.elapsedRealtime() - xmpp.lastSessionStarted) / 60000; - long connectionAgeHours = connectionAge / 60; - long sessionAgeHours = sessionAge / 60; - View view = (View) getLayoutInflater().inflate(R.layout.server_info, null); - TextView connection = (TextView) view.findViewById(R.id.connection); - TextView session = (TextView) view.findViewById(R.id.session); - TextView pcks_sent = (TextView) view.findViewById(R.id.pcks_sent); - TextView pcks_received = (TextView) view.findViewById(R.id.pcks_received); - TextView carbon = (TextView) view.findViewById(R.id.carbon); - TextView stream = (TextView) view.findViewById(R.id.stream); - TextView roster = (TextView) view.findViewById(R.id.roster); - TextView presences = (TextView) view.findViewById(R.id.number_presences); - presences.setText(selectedAccountForActionMode.countPresences()+""); - pcks_received.setText(""+xmpp.getReceivedStanzas()); - pcks_sent.setText(""+xmpp.getSentStanzas()); - if (connectionAgeHours >= 2) { - connection.setText(connectionAgeHours+" " + getString(R.string.hours)); - } else { - connection.setText(connectionAge+" " + getString(R.string.mins)); - } - if (xmpp.hasFeatureStreamManagment()) { - if (sessionAgeHours >= 2) { - session.setText(sessionAgeHours+" " + getString(R.string.hours)); - } else { - session.setText(sessionAge+" " + getString(R.string.mins)); + @Override + public boolean onItemLongClick(AdapterView<?> arg0, + View view, int position, long arg3) { + if (!isActionMode) { + accountListView + .setChoiceMode(ListView.CHOICE_MODE_SINGLE); + accountListView.setItemChecked(position, true); + selectedAccountForActionMode = accountList + .get(position); + actionMode = activity + .startActionMode((new ActionMode.Callback() { + + @Override + public boolean onPrepareActionMode( + ActionMode mode, Menu menu) { + if (selectedAccountForActionMode + .isOptionSet(Account.OPTION_DISABLED)) { + menu.findItem( + R.id.mgmt_account_enable) + .setVisible(true); + menu.findItem( + R.id.mgmt_account_disable) + .setVisible(false); + } else { + menu.findItem( + R.id.mgmt_account_disable) + .setVisible(true); + menu.findItem( + R.id.mgmt_account_enable) + .setVisible(false); + } + return true; } - stream.setText(getString(R.string.yes)); - } else { - stream.setText(getString(R.string.no)); - session.setText(connection.getText()); - } - if (xmpp.hasFeaturesCarbon()) { - carbon.setText(getString(R.string.yes)); - } else { - carbon.setText(getString(R.string.no)); - } - if (xmpp.hasFeatureRosterManagment()) { - roster.setText(getString(R.string.yes)); - } else { - roster.setText(getString(R.string.no)); - } - builder.setView(view); - } else { - builder.setMessage(getString(R.string.mgmt_account_account_offline)); - } - builder.setPositiveButton(getString(R.string.hide), null); - builder.create().show(); - } + + @Override + public void onDestroyActionMode( + ActionMode mode) { + // TODO Auto-generated method stub + + } + + @Override + public boolean onCreateActionMode( + ActionMode mode, Menu menu) { + MenuInflater inflater = mode + .getMenuInflater(); + inflater.inflate( + R.menu.manageaccounts_context, + menu); + return true; + } + + @Override + public boolean onActionItemClicked( + final ActionMode mode, + MenuItem item) { + if (item.getItemId() == R.id.mgmt_account_edit) { + editAccount(selectedAccountForActionMode); + } else if (item.getItemId() == R.id.mgmt_account_disable) { + selectedAccountForActionMode + .setOption( + Account.OPTION_DISABLED, + true); + xmppConnectionService + .updateAccount(selectedAccountForActionMode); + mode.finish(); + } else if (item.getItemId() == R.id.mgmt_account_enable) { + selectedAccountForActionMode + .setOption( + Account.OPTION_DISABLED, + false); + xmppConnectionService + .updateAccount(selectedAccountForActionMode); + mode.finish(); + } else if (item.getItemId() == R.id.mgmt_account_delete) { + AlertDialog.Builder builder = new AlertDialog.Builder( + activity); + builder.setTitle(getString(R.string.mgmt_account_are_you_sure)); + builder.setIconAttribute(android.R.attr.alertDialogIcon); + builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text)); + builder.setPositiveButton( + getString(R.string.delete), + new OnClickListener() { + + @Override + public void onClick( + DialogInterface dialog, + int which) { + xmppConnectionService + .deleteAccount(selectedAccountForActionMode); + selectedAccountForActionMode = null; + mode.finish(); + } + }); + builder.setNegativeButton( + getString(R.string.cancel), + null); + builder.create().show(); + } else if (item.getItemId() == R.id.mgmt_account_announce_pgp) { + if (activity.hasPgp()) { + mode.finish(); + announcePgp( + selectedAccountForActionMode, + null); + } else { + activity.showInstallPgpDialog(); + } + } else if (item.getItemId() == R.id.mgmt_otr_key) { + AlertDialog.Builder builder = new AlertDialog.Builder( + activity); + builder.setTitle("OTR Fingerprint"); + String fingerprintTxt = selectedAccountForActionMode + .getOtrFingerprint(getApplicationContext()); + View view = (View) getLayoutInflater() + .inflate( + R.layout.otr_fingerprint, + null); + if (fingerprintTxt != null) { + TextView fingerprint = (TextView) view + .findViewById(R.id.otr_fingerprint); + TextView noFingerprintView = (TextView) view + .findViewById(R.id.otr_no_fingerprint); + fingerprint + .setText(fingerprintTxt); + fingerprint + .setVisibility(View.VISIBLE); + noFingerprintView + .setVisibility(View.GONE); + } + builder.setView(view); + builder.setPositiveButton( + getString(R.string.done), + null); + builder.create().show(); + } else if (item.getItemId() == R.id.mgmt_account_info) { + AlertDialog.Builder builder = new AlertDialog.Builder( + activity); + builder.setTitle(getString(R.string.account_info)); + if (selectedAccountForActionMode + .getStatus() == Account.STATUS_ONLINE) { + XmppConnection xmpp = selectedAccountForActionMode + .getXmppConnection(); + long connectionAge = (SystemClock + .elapsedRealtime() - xmpp.lastConnect) / 60000; + long sessionAge = (SystemClock + .elapsedRealtime() - xmpp.lastSessionStarted) / 60000; + long connectionAgeHours = connectionAge / 60; + long sessionAgeHours = sessionAge / 60; + View view = (View) getLayoutInflater() + .inflate( + R.layout.server_info, + null); + TextView connection = (TextView) view + .findViewById(R.id.connection); + TextView session = (TextView) view + .findViewById(R.id.session); + TextView pcks_sent = (TextView) view + .findViewById(R.id.pcks_sent); + TextView pcks_received = (TextView) view + .findViewById(R.id.pcks_received); + TextView carbon = (TextView) view + .findViewById(R.id.carbon); + TextView stream = (TextView) view + .findViewById(R.id.stream); + TextView roster = (TextView) view + .findViewById(R.id.roster); + TextView presences = (TextView) view + .findViewById(R.id.number_presences); + presences.setText(selectedAccountForActionMode + .countPresences() + + ""); + pcks_received.setText("" + + xmpp.getReceivedStanzas()); + pcks_sent.setText("" + + xmpp.getSentStanzas()); + if (connectionAgeHours >= 2) { + connection + .setText(connectionAgeHours + + " " + + getString(R.string.hours)); + } else { + connection + .setText(connectionAge + + " " + + getString(R.string.mins)); + } + if (xmpp.hasFeatureStreamManagment()) { + if (sessionAgeHours >= 2) { + session.setText(sessionAgeHours + + " " + + getString(R.string.hours)); + } else { + session.setText(sessionAge + + " " + + getString(R.string.mins)); + } + stream.setText(getString(R.string.yes)); + } else { + stream.setText(getString(R.string.no)); + session.setText(connection + .getText()); + } + if (xmpp.hasFeaturesCarbon()) { + carbon.setText(getString(R.string.yes)); + } else { + carbon.setText(getString(R.string.no)); + } + if (xmpp.hasFeatureRosterManagment()) { + roster.setText(getString(R.string.yes)); + } else { + roster.setText(getString(R.string.no)); + } + builder.setView(view); + } else { + builder.setMessage(getString(R.string.mgmt_account_account_offline)); + } + builder.setPositiveButton( + getString(R.string.hide), + null); + builder.create().show(); + } + return true; + } + + })); return true; + } else { + return false; } - - - })); - return true; - } else { - return false; - } - } - }); + } + }); } - + @Override protected void onStop() { if (xmppConnectionServiceBound) { @@ -370,11 +479,12 @@ public class ManageAccountActivity extends XmppActivity { @Override void onBackendConnected() { xmppConnectionService.setOnAccountListChangedListener(accountChanged); - xmppConnectionService.setOnTLSExceptionReceivedListener(tlsExceptionReceived); + xmppConnectionService + .setOnTLSExceptionReceivedListener(tlsExceptionReceived); this.accountList.clear(); this.accountList.addAll(xmppConnectionService.getAccounts()); accountListViewAdapter.notifyDataSetChanged(); - if ((this.accountList.size() == 0)&&(this.firstrun)) { + if ((this.accountList.size() == 0) && (this.firstrun)) { getActionBar().setDisplayHomeAsUpEnabled(false); getActionBar().setHomeButtonEnabled(false); addAccount(); @@ -403,14 +513,15 @@ public class ManageAccountActivity extends XmppActivity { @Override public boolean onNavigateUp() { if (xmppConnectionService.getConversations().size() == 0) { - Intent contactsIntent = new Intent(this, ContactsActivity.class); + Intent contactsIntent = new Intent(this, StartConversationActivity.class); contactsIntent.setFlags( - // if activity exists in stack, pop the stack and go back to it + // if activity exists in stack, pop the stack and go back to it Intent.FLAG_ACTIVITY_CLEAR_TOP | // otherwise, make a new task for it - Intent.FLAG_ACTIVITY_NEW_TASK | - // don't use the new activity animation; finish animation runs instead - Intent.FLAG_ACTIVITY_NO_ANIMATION); + Intent.FLAG_ACTIVITY_NEW_TASK | + // don't use the new activity animation; finish + // animation runs instead + Intent.FLAG_ACTIVITY_NO_ANIMATION); startActivity(contactsIntent); finish(); return true; @@ -420,25 +531,26 @@ public class ManageAccountActivity extends XmppActivity { } private void editAccount(Account account) { - EditAccount dialog = new EditAccount(); - dialog.setAccount(account); - dialog.setEditAccountListener(new EditAccountListener() { + EditAccountDialog dialog = new EditAccountDialog(); + dialog.setAccount(account); + dialog.setEditAccountListener(new EditAccountListener() { - @Override - public void onAccountEdited(Account account) { - xmppConnectionService.updateAccount(account); - if (actionMode != null) { - actionMode.finish(); - } + @Override + public void onAccountEdited(Account account) { + xmppConnectionService.updateAccount(account); + if (actionMode != null) { + actionMode.finish(); } - }); - dialog.show(getFragmentManager(), "edit_account"); - + } + }); + dialog.show(getFragmentManager(), "edit_account"); + dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this); + } - + protected void addAccount() { final Activity activity = this; - EditAccount dialog = new EditAccount(); + EditAccountDialog dialog = new EditAccountDialog(); dialog.setEditAccountListener(new EditAccountListener() { @Override @@ -449,15 +561,15 @@ public class ManageAccountActivity extends XmppActivity { } }); dialog.show(getFragmentManager(), "add_account"); + dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this); } - @Override public void onActionModeStarted(ActionMode mode) { super.onActionModeStarted(mode); this.isActionMode = true; } - + @Override public void onActionModeFinished(ActionMode mode) { super.onActionModeFinished(mode); @@ -465,20 +577,20 @@ public class ManageAccountActivity extends XmppActivity { accountListView.clearChoices(); accountListView.requestLayout(); accountListView.post(new Runnable() { - @Override - public void run() { - accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE); - } - }); + @Override + public void run() { + accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE); + } + }); } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { if (requestCode == REQUEST_ANNOUNCE_PGP) { - announcePgp(selectedAccountForActionMode,null); + announcePgp(selectedAccountForActionMode, null); } - } - } + } + } } diff --git a/src/eu/siacs/conversations/ui/MucDetailsActivity.java b/src/eu/siacs/conversations/ui/MucDetailsActivity.java deleted file mode 100644 index ee6709b7..00000000 --- a/src/eu/siacs/conversations/ui/MucDetailsActivity.java +++ /dev/null @@ -1,213 +0,0 @@ -package eu.siacs.conversations.ui; - -import java.util.ArrayList; -import java.util.List; - -import org.openintents.openpgp.util.OpenPgpUtils; - -import eu.siacs.conversations.R; -import eu.siacs.conversations.crypto.PgpEngine; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.entities.MucOptions.User; -import eu.siacs.conversations.utils.UIHelper; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.IntentSender.SendIntentException; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -public class MucDetailsActivity extends XmppActivity { - public static final String ACTION_VIEW_MUC = "view_muc"; - private Conversation conversation; - private EditText mYourNick; - private EditText mSubject; - private TextView mRoleAffiliaton; - private TextView mFullJid; - private LinearLayout membersView; - private LinearLayout mMoreDetails; - private Button mInviteButton; - private String uuid = null; - private OnClickListener changeNickListener = new OnClickListener() { - - @Override - public void onClick(View arg0) { - MucOptions options = conversation.getMucOptions(); - String nick = mYourNick.getText().toString(); - if (!options.getNick().equals(nick)) { - xmppConnectionService.renameInMuc(conversation, nick); - finish(); - } - } - }; - - private OnClickListener changeSubjectListener = new OnClickListener() { - - @Override - public void onClick(View arg0) { - String subject = mSubject.getText().toString(); - MucOptions options = conversation.getMucOptions(); - if (!subject.equals(options.getSubject())) { - xmppConnectionService.sendConversationSubject(conversation,subject); - finish(); - } - } - }; - - private OnClickListener inviteListener = new OnClickListener() { - - @Override - public void onClick(View v) { - Intent intent = new Intent(getApplicationContext(), - ContactsActivity.class); - intent.setAction("invite"); - intent.putExtra("uuid",conversation.getUuid()); - startActivity(intent); - } - }; - - private List<User> users = new ArrayList<MucOptions.User>(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_muc_details); - mYourNick = (EditText) findViewById(R.id.muc_your_nick); - mFullJid = (TextView) findViewById(R.id.muc_jabberid); - ImageButton editNickButton = (ImageButton) findViewById(R.id.muc_edit_nick); - editNickButton.setOnClickListener(this.changeNickListener); - ImageButton editSubjectButton = (ImageButton) findViewById(R.id.muc_edit_subject); - editSubjectButton.setOnClickListener(this.changeSubjectListener); - membersView = (LinearLayout) findViewById(R.id.muc_members); - mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details); - mMoreDetails.setVisibility(View.GONE); - mSubject = (EditText) findViewById(R.id.muc_subject); - mInviteButton = (Button) findViewById(R.id.invite); - mInviteButton.setOnClickListener(inviteListener); - getActionBar().setHomeButtonEnabled(true); - getActionBar().setDisplayHomeAsUpEnabled(true); - - } - - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - switch (menuItem.getItemId()) { - case android.R.id.home: - finish(); - } - return super.onOptionsItemSelected(menuItem); - } - - public String getReadableRole(int role) { - switch (role) { - case User.ROLE_MODERATOR: - return getString(R.string.moderator); - case User.ROLE_PARTICIPANT: - return getString(R.string.participant); - case User.ROLE_VISITOR: - return getString(R.string.visitor); - default: - return ""; - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.muc_details, menu); - return true; - } - - @Override - void onBackendConnected() { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); - boolean useSubject = preferences.getBoolean("use_subject_in_muc", true); - if (getIntent().getAction().equals(ACTION_VIEW_MUC)) { - this.uuid = getIntent().getExtras().getString("uuid"); - } - if (uuid != null) { - for (Conversation mConv : xmppConnectionService.getConversations()) { - if (mConv.getUuid().equals(uuid)) { - this.conversation = mConv; - } - } - if (this.conversation != null) { - mSubject.setText(conversation.getMucOptions().getSubject()); - setTitle(conversation.getName(useSubject)); - mFullJid.setText(conversation.getContactJid().split("/")[0]); - mYourNick.setText(conversation.getMucOptions().getNick()); - mRoleAffiliaton = (TextView) findViewById(R.id.muc_role); - if (conversation.getMucOptions().online()) { - mMoreDetails.setVisibility(View.VISIBLE); - User self = conversation.getMucOptions().getSelf(); - switch (self.getAffiliation()) { - case User.AFFILIATION_ADMIN: - mRoleAffiliaton.setText(getReadableRole(self.getRole()) - + " (" + getString(R.string.admin) + ")"); - break; - case User.AFFILIATION_OWNER: - mRoleAffiliaton.setText(getReadableRole(self.getRole()) - + " (" + getString(R.string.owner) + ")"); - break; - default: - mRoleAffiliaton - .setText(getReadableRole(self.getRole())); - break; - } - } - this.users.clear(); - this.users.addAll(conversation.getMucOptions().getUsers()); - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - membersView.removeAllViews(); - for(final User contact : conversation.getMucOptions().getUsers()) { - View view = (View) inflater.inflate(R.layout.contact, null); - TextView displayName = (TextView) view.findViewById(R.id.contact_display_name); - TextView key = (TextView) view.findViewById(R.id.key); - displayName.setText(contact.getName()); - TextView role = (TextView) view.findViewById(R.id.contact_jid); - role.setText(getReadableRole(contact.getRole())); - if (contact.getPgpKeyId()!=0) { - key.setVisibility(View.VISIBLE); - key.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - PgpEngine pgp = xmppConnectionService.getPgpEngine(); - if (pgp!=null) { - PendingIntent intent = pgp.getIntentForKey(conversation.getAccount(), contact.getPgpKeyId()); - if (intent!=null) { - try { - startIntentSenderForResult(intent.getIntentSender(), 0, null, 0, 0, 0); - } catch (SendIntentException e) { - - } - } - } - } - }); - key.setText(OpenPgpUtils.convertKeyIdToHex(contact.getPgpKeyId())); - } - ImageView imageView = (ImageView) view - .findViewById(R.id.contact_photo); - imageView.setImageBitmap(UIHelper.getContactPicture(contact.getName(), 48,this.getApplicationContext(), false)); - membersView.addView(view); - } - } - } else { - Log.d("xmppService","uuid in muc details was null"); - } - } -} diff --git a/src/eu/siacs/conversations/ui/OnAccountListChangedListener.java b/src/eu/siacs/conversations/ui/OnAccountListChangedListener.java deleted file mode 100644 index 98ef445e..00000000 --- a/src/eu/siacs/conversations/ui/OnAccountListChangedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.siacs.conversations.ui; - -public interface OnAccountListChangedListener { - public void onAccountListChangedListener(); -} diff --git a/src/eu/siacs/conversations/ui/OnConversationListChangedListener.java b/src/eu/siacs/conversations/ui/OnConversationListChangedListener.java deleted file mode 100644 index 2a922e21..00000000 --- a/src/eu/siacs/conversations/ui/OnConversationListChangedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.siacs.conversations.ui; - -public interface OnConversationListChangedListener { - public void onConversationListChanged(); -} diff --git a/src/eu/siacs/conversations/ui/OnPresenceSelected.java b/src/eu/siacs/conversations/ui/OnPresenceSelected.java deleted file mode 100644 index 1c967224..00000000 --- a/src/eu/siacs/conversations/ui/OnPresenceSelected.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.siacs.conversations.ui; - -public interface OnPresenceSelected { - public void onPresenceSelected(); -} diff --git a/src/eu/siacs/conversations/ui/ShareWithActivity.java b/src/eu/siacs/conversations/ui/ShareWithActivity.java index 9fe5e500..461aaec4 100644 --- a/src/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/eu/siacs/conversations/ui/ShareWithActivity.java @@ -20,7 +20,6 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; -import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; @@ -90,7 +89,8 @@ public class ShareWithActivity extends XmppActivity { Set<Contact> displayedContacts = new HashSet<Contact>(); conversations.removeAllViews(); - List<Conversation> convList = xmppConnectionService.getConversations(); + List<Conversation> convList = new ArrayList<Conversation>(); + xmppConnectionService.populateWithOrderedConversations(convList); Collections.sort(convList, new Comparator<Conversation>() { @Override public int compare(Conversation lhs, Conversation rhs) { diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java new file mode 100644 index 00000000..d12d2878 --- /dev/null +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -0,0 +1,584 @@ +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.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +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.Menu; +import android.view.MenuItem; +import android.view.View; +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.CheckBox; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.Spinner; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Bookmark; +import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.ListItem; +import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; +import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; +import eu.siacs.conversations.ui.adapter.ListItemAdapter; +import eu.siacs.conversations.utils.Validator; + +public class StartConversationActivity extends XmppActivity { + + private Tab mContactsTab; + private Tab mConferencesTab; + private ViewPager mViewPager; + + private MyListFragment mContactsListFragment = new MyListFragment(); + private List<ListItem> contacts = new ArrayList<ListItem>(); + private ArrayAdapter<ListItem> mContactsAdapter; + + private MyListFragment mConferenceListFragment = new MyListFragment(); + private List<ListItem> conferences = new ArrayList<ListItem>(); + private ArrayAdapter<ListItem> mConferenceAdapter; + + private List<String> mActivatedAccounts = new ArrayList<String>(); + private List<String> mKnownHosts; + private List<String> mKnownConferenceHosts; + + private EditText mSearchEditText; + + public int conference_context_id; + public int contact_context_id; + + 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(""); + filter(null); + return true; + } + }; + private TextWatcher mSearchTextWatcher = new TextWatcher() { + + @Override + public void afterTextChanged(Editable editable) { + filter(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) { + } + }; + private OnRosterUpdate onRosterUpdate = new OnRosterUpdate() { + + @Override + public void onRosterUpdate() { + runOnUiThread(new Runnable() { + + @Override + public void run() { + filter(mSearchEditText.getText().toString()); + } + }); + } + }; + + @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(getApplicationContext(),conferences); + mConferenceListFragment.setListAdapter(mConferenceAdapter); + mConferenceListFragment.setContextMenu(R.menu.conference_context); + mConferenceListFragment + .setOnListItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, + int position, long arg3) { + openConversationForBookmark(position); + } + }); + + mContactsAdapter = new ListItemAdapter(getApplicationContext(),contacts); + mContactsListFragment.setListAdapter(mContactsAdapter); + mContactsListFragment.setContextMenu(R.menu.contact_context); + mContactsListFragment + .setOnListItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, + int position, long arg3) { + openConversationForContact(position); + } + }); + + } + + @Override + public void onStop() { + super.onStop(); + xmppConnectionService.removeOnRosterUpdateListener(); + } + + protected void openConversationForContact(int position) { + Contact contact = (Contact) contacts.get(position); + Conversation conversation = xmppConnectionService + .findOrCreateConversation(contact.getAccount(), + contact.getJid(), false); + switchToConversation(conversation); + } + + protected void openConversationForContact() { + int position = contact_context_id; + openConversationForContact(position); + } + + protected void openConversationForBookmark() { + openConversationForBookmark(conference_context_id); + } + + protected void openConversationForBookmark(int position) { + Bookmark bookmark = (Bookmark) conferences.get(position); + Conversation conversation = xmppConnectionService + .findOrCreateConversation(bookmark.getAccount(), + bookmark.getJid(), true); + conversation.setBookmark(bookmark); + if (!conversation.getMucOptions().online()) { + xmppConnectionService.joinMuc(conversation); + } + if (!bookmark.autojoin()) { + bookmark.setAutojoin(true); + xmppConnectionService.pushBookmarks(bookmark.getAccount()); + } + switchToConversation(conversation); + } + + protected void openDetailsForContact() { + int position = contact_context_id; + Contact contact = (Contact) contacts.get(position); + switchToContactDetails(contact); + } + + protected void deleteContact() { + int position = contact_context_id; + final Contact contact = (Contact) contacts.get(position); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setNegativeButton(R.string.cancel, null); + builder.setTitle(R.string.action_delete_contact); + builder.setMessage( + getString(R.string.remove_contact_text, + contact.getJid())); + builder.setPositiveButton(R.string.delete,new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + xmppConnectionService.deleteContactOnServer(contact); + filter(mSearchEditText.getText().toString()); + } + }); + builder.create().show(); + + } + + protected void deleteConference() { + int position = conference_context_id; + final Bookmark bookmark = (Bookmark) conferences.get(position); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setNegativeButton(R.string.cancel, null); + builder.setTitle(R.string.delete_bookmark); + builder.setMessage( + getString(R.string.remove_bookmark_text, + bookmark.getJid())); + builder.setPositiveButton(R.string.delete,new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + bookmark.unregisterConversation(); + Account account = bookmark.getAccount(); + account.getBookmarks().remove(bookmark); + xmppConnectionService.pushBookmarks(account); + filter(mSearchEditText.getText().toString()); + } + }); + builder.create().show(); + + } + + 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); + final CheckBox bookmarkCheckBox = (CheckBox) dialogView + .findViewById(R.id.bookmark); + 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); + if (bookmarkCheckBox.isChecked()) { + if (account.hasBookmarkFor(conferenceJid)) { + jid.setError(getString(R.string.bookmark_already_exists)); + } else { + Bookmark bookmark = new Bookmark(account, + conferenceJid); + bookmark.setAutojoin(true); + account.getBookmarks().add(bookmark); + xmppConnectionService + .pushBookmarks(account); + Conversation conversation = xmppConnectionService + .findOrCreateConversation(account, + conferenceJid, true); + conversation.setBookmark(bookmark); + if (!conversation.getMucOptions().online()) { + xmppConnectionService.joinMuc(conversation); + } + switchToConversation(conversation); + } + } else { + Conversation conversation = xmppConnectionService + .findOrCreateConversation(account, + conferenceJid, true); + if (!conversation.getMucOptions().online()) { + xmppConnectionService.joinMuc(conversation); + } + 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<String> adapter = new ArrayAdapter<String>(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() { + xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate ); + if (mSearchEditText != null) { + filter(mSearchEditText.getText().toString()); + } else { + filter(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 filter(String needle) { + this.filterContacts(needle); + this.filterConferences(needle); + } + + 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(); + } + + protected void filterConferences(String needle) { + this.conferences.clear(); + for (Account account : xmppConnectionService.getAccounts()) { + if (account.getStatus() != Account.STATUS_DISABLED) { + for (Bookmark bookmark : account.getBookmarks()) { + if (bookmark.match(needle)) { + this.conferences.add(bookmark); + } + } + } + } + Collections.sort(this.conferences); + mConferenceAdapter.notifyDataSetChanged(); + } + + private void onTabChanged() { + invalidateOptionsMenu(); + } + + public static class MyListFragment extends ListFragment { + private AdapterView.OnItemClickListener mOnItemClickListener; + private int mResContextMenu; + + public void setContextMenu(int res) { + this.mResContextMenu = res; + } + + @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); + StartConversationActivity activity = (StartConversationActivity) getActivity(); + activity.getMenuInflater().inflate(mResContextMenu, menu); + AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; + if (mResContextMenu == R.menu.conference_context) { + activity.conference_context_id = acmi.position; + } else { + activity.contact_context_id = acmi.position; + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + StartConversationActivity activity = (StartConversationActivity) getActivity(); + switch (item.getItemId()) { + case R.id.context_start_conversation: + activity.openConversationForContact(); + break; + case R.id.context_contact_details: + activity.openDetailsForContact(); + break; + case R.id.context_delete_contact: + activity.deleteContact(); + break; + case R.id.context_join_conference: + activity.openConversationForBookmark(); + break; + case R.id.context_delete_conference: + activity.deleteConference(); + } + return true; + } + } +} diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index c95cbfec..c813182f 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -27,16 +27,26 @@ import android.util.Log; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; public abstract class XmppActivity extends Activity { public static final int REQUEST_ANNOUNCE_PGP = 0x73731; + protected static final int REQUEST_INVITE_TO_CONVERSATION = 0x341830; protected final static String LOGTAG = "xmppService"; public XmppConnectionService xmppConnectionService; public boolean xmppConnectionServiceBound = false; protected boolean handledViewIntent = false; + + protected interface OnValueEdited { + public void onValueEdited(String value); + } + + public interface OnPresenceSelected { + public void onPresenceSelected(); + } protected ServiceConnection mConnection = new ServiceConnection() { @@ -149,6 +159,10 @@ public abstract class XmppActivity extends Activity { ExceptionHelper.init(getApplicationContext()); } + public void switchToConversation(Conversation conversation) { + switchToConversation(conversation, null, false); + } + public void switchToConversation(Conversation conversation, String text, boolean newTask) { Intent viewConversationIntent = new Intent(this, @@ -171,6 +185,20 @@ public abstract class XmppActivity extends Activity { startActivity(viewConversationIntent); } + public void switchToContactDetails(Contact contact) { + Intent intent = new Intent(this, ContactDetailsActivity.class); + intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT); + intent.putExtra("account", contact.getAccount().getJid()); + intent.putExtra("contact", contact.getJid()); + startActivity(intent); + } + + protected void inviteToConversation(Conversation conversation) { + Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class); + intent.putExtra("conversation",conversation.getUuid()); + startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION); + } + protected void announcePgp(Account account, final Conversation conversation) { xmppConnectionService.getPgpEngine().generateSignature(account, "online", new UiCallback<Account>() { @@ -181,17 +209,16 @@ public abstract class XmppActivity extends Activity { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); - } catch (SendIntentException e) { - Log.d("xmppService", - "coulnd start intent for pgp anncouncment"); - } + } catch (SendIntentException e) {} } @Override public void success(Account account) { xmppConnectionService.databaseBackend .updateAccount(account); - xmppConnectionService.sendPresence(account); + xmppConnectionService.sendPresencePacket(account, + xmppConnectionService.getPresenceGenerator() + .sendPresence(account)); if (conversation != null) { conversation .setNextEncryption(Message.ENCRYPTION_PGP); @@ -221,7 +248,7 @@ public abstract class XmppActivity extends Activity { }); } - + protected void showAddToRosterDialog(final Conversation conversation) { String jid = conversation.getContactJid(); AlertDialog.Builder builder = new AlertDialog.Builder(this); @@ -237,10 +264,31 @@ public abstract class XmppActivity extends Activity { Account account = conversation.getAccount(); Contact contact = account.getRoster().getContact(jid); xmppConnectionService.createContact(contact); + switchToContactDetails(contact); } }); builder.create().show(); } + + protected void quickEdit(final String previousValue, final OnValueEdited callback) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + View view = (View) getLayoutInflater().inflate(R.layout.quickedit, null); + final EditText editor = (EditText) view.findViewById(R.id.editor); + editor.setText(previousValue); + builder.setView(view); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.edit, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + String value = editor.getText().toString(); + if (!previousValue.equals(value) && value.trim().length() > 0) { + callback.onValueEdited(value); + } + } + }); + builder.create().show(); + } public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) { @@ -293,4 +341,18 @@ public abstract class XmppActivity extends Activity { } } } + + protected void onActivityResult(int requestCode, int resultCode, + final Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == REQUEST_INVITE_TO_CONVERSATION && resultCode == RESULT_OK) { + String contactJid = data.getStringExtra("contact"); + String conversationUuid = data.getStringExtra("conversation"); + Conversation conversation = xmppConnectionService.findConversationByUuid(conversationUuid); + if (conversation.getMode() == Conversation.MODE_MULTI) { + xmppConnectionService.invite(conversation, contactJid); + } + Log.d("xmppService","inviting "+contactJid+" to "+conversation.getName(true)); + } + } } diff --git a/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java b/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java new file mode 100644 index 00000000..040e6266 --- /dev/null +++ b/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java @@ -0,0 +1,69 @@ +package eu.siacs.conversations.ui.adapter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import android.content.Context; +import android.widget.ArrayAdapter; +import android.widget.Filter; + +public class KnownHostsAdapter extends ArrayAdapter<String> { + private ArrayList<String> domains; + private Filter domainFilter = new Filter() { + + @Override + protected FilterResults performFiltering(CharSequence constraint) { + if (constraint != null) { + ArrayList<String> suggestions = new ArrayList<String>(); + final String[] split = constraint.toString().split("@"); + if (split.length == 1) { + for (String domain : domains) { + suggestions.add(split[0].toLowerCase(Locale.getDefault()) + "@" + domain); + } + } else if (split.length == 2) { + for (String domain : domains) { + if (domain.contains(split[1])) { + suggestions.add(split[0].toLowerCase(Locale.getDefault()) + "@" + domain); + } + } + } else { + return new FilterResults(); + } + FilterResults filterResults = new FilterResults(); + filterResults.values = suggestions; + filterResults.count = suggestions.size(); + return filterResults; + } else { + return new FilterResults(); + } + } + + @Override + protected void publishResults(CharSequence constraint, + FilterResults results) { + ArrayList<String> filteredList = (ArrayList<String>) results.values; + if (results != null && results.count > 0) { + clear(); + for (String c : filteredList) { + add(c); + } + notifyDataSetChanged(); + } + } + }; + + public KnownHostsAdapter(Context context, int viewResourceId, + List<String> mKnownHosts) { + super(context, viewResourceId, mKnownHosts); + domains = new ArrayList<String>(mKnownHosts.size()); + for (String domain : mKnownHosts) { + domains.add(new String(domain)); + } + } + + @Override + public Filter getFilter() { + return domainFilter; + } +}
\ No newline at end of file diff --git a/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java new file mode 100644 index 00000000..9ef427fc --- /dev/null +++ b/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java @@ -0,0 +1,39 @@ +package eu.siacs.conversations.ui.adapter; + +import java.util.List; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.ListItem; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +public class ListItemAdapter extends ArrayAdapter<ListItem> { + + public ListItemAdapter(Context context, List<ListItem> objects) { + super(context, 0, objects); + } + + @Override + public View getView(int position, View view, ViewGroup parent) { + LayoutInflater inflater = (LayoutInflater) getContext() + .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(item.getImage(48, getContext())); + return view; + } + +}
\ No newline at end of file |