diff options
Diffstat (limited to 'src/eu/siacs/conversations/ui')
15 files changed, 1410 insertions, 893 deletions
diff --git a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 56903da8..c33277f9 100644 --- a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -7,6 +7,8 @@ import org.openintents.openpgp.util.OpenPgpUtils; 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.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; @@ -54,7 +56,7 @@ public class ConferenceDetailsActivity extends XmppActivity { private List<User> users = new ArrayList<MucOptions.User>(); private OnConversationUpdate onConvChanged = new OnConversationUpdate() { - + @Override public void onConversationUpdate() { runOnUiThread(new Runnable() { @@ -150,13 +152,14 @@ public class ConferenceDetailsActivity extends XmppActivity { this.uuid = getIntent().getExtras().getString("uuid"); } if (uuid != null) { - this.conversation = xmppConnectionService.findConversationByUuid(uuid); + this.conversation = xmppConnectionService + .findConversationByUuid(uuid); if (this.conversation != null) { populateView(); } } } - + @Override protected void onStop() { if (xmppConnectionServiceBound) { @@ -164,39 +167,39 @@ public class ConferenceDetailsActivity extends XmppActivity { } super.onStop(); } - + protected void registerListener() { if (xmppConnectionServiceBound) { xmppConnectionService .setOnConversationListChangedListener(this.onConvChanged); - xmppConnectionService.setOnRenameListener(new OnRenameListener() { + xmppConnectionService.setOnRenameListener(new OnRenameListener() { - @Override - public void onRename(final boolean success) { - runOnUiThread(new Runnable() { + @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(); + @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)); + mYourPhoto.setImageBitmap(conversation.getAccount().getImage(this, 48)); setTitle(conversation.getName(true)); mFullJid.setText(conversation.getContactJid().split("/")[0]); mYourNick.setText(conversation.getMucOptions().getActualNick()); @@ -222,28 +225,44 @@ public class ConferenceDetailsActivity extends XmppActivity { 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 + Account account = conversation.getAccount(); + for (final User user : conversation.getMucOptions().getUsers()) { + View view = (View) inflater.inflate(R.layout.contact, membersView, + false); + TextView name = (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) { + if (user.getPgpKeyId() != 0) { key.setVisibility(View.VISIBLE); key.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - viewPgpKey(contact); + viewPgpKey(user); } }); - key.setText(OpenPgpUtils.convertKeyIdToHex(contact - .getPgpKeyId())); + key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId())); + } + Bitmap bm; + if (user.getJid() != null) { + Contact contact = account.getRoster().getContact(user.getJid()); + if (contact.showInRoster()) { + bm = contact.getImage(48, this); + name.setText(contact.getDisplayName()); + role.setText(user.getName() + " \u2022 " + getReadableRole(user.getRole())); + } else { + bm = UIHelper.getContactPicture(user.getName(), 48, this, + false); + name.setText(user.getName()); + role.setText(getReadableRole(user.getRole())); + } + } else { + bm = UIHelper + .getContactPicture(user.getName(), 48, this, false); + name.setText(user.getName()); + role.setText(getReadableRole(user.getRole())); } - Bitmap bm = UIHelper.getContactPicture(contact.getName(), 48, this, - false); ImageView iv = (ImageView) view.findViewById(R.id.contact_photo); iv.setImageBitmap(bm); membersView.addView(view); diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index aa4fda4e..c68063d2 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -4,13 +4,14 @@ import java.io.FileNotFoundException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.RejectedExecutionException; import eu.siacs.conversations.R; 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.ui.adapter.ConversationAdapter; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.UIHelper; import android.net.Uri; @@ -18,10 +19,10 @@ import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.MediaStore; +import android.app.ActionBar; import android.app.AlertDialog; import android.app.FragmentTransaction; import android.app.PendingIntent; -import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.IntentSender.SendIntentException; @@ -29,8 +30,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.support.v4.widget.SlidingPaneLayout; @@ -38,11 +37,9 @@ import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener; import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; @@ -50,7 +47,6 @@ import android.widget.CheckBox; import android.widget.ListView; import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; -import android.widget.TextView; import android.widget.ImageView; import android.widget.Toast; @@ -61,17 +57,17 @@ public class ConversationActivity extends XmppActivity { public static final String TEXT = "text"; public static final String PRESENCE = "eu.siacs.conversations.presence"; - public static final int REQUEST_SEND_MESSAGE = 0x75441; - public static final int REQUEST_DECRYPT_PGP = 0x76783; - private static final int REQUEST_ATTACH_FILE_DIALOG = 0x48502; - private static final int REQUEST_IMAGE_CAPTURE = 0x33788; - private static final int REQUEST_RECORD_AUDIO = 0x46189; - private static final int REQUEST_SEND_PGP_IMAGE = 0x53883; - public static final int REQUEST_ENCRYPT_MESSAGE = 0x378018; + public static final int REQUEST_SEND_MESSAGE = 0x0201; + public static final int REQUEST_DECRYPT_PGP = 0x0202; + private static final int REQUEST_ATTACH_FILE_DIALOG = 0x0203; + private static final int REQUEST_IMAGE_CAPTURE = 0x0204; + private static final int REQUEST_RECORD_AUDIO = 0x0205; + private static final int REQUEST_SEND_PGP_IMAGE = 0x0206; + public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207; - private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x92734; - private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x84123; - private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x75291; + private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; + private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; + private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0303; protected SlidingPaneLayout spl; @@ -115,6 +111,8 @@ public class ConversationActivity extends XmppActivity { protected ConversationActivity activity = this; private DisplayMetrics metrics; private Toast prepareImageToast; + + private Uri pendingImageUri = null; public List<Conversation> getConversationList() { return this.conversationList; @@ -150,93 +148,11 @@ public class ConversationActivity extends XmppActivity { setContentView(R.layout.fragment_conversations_overview); listView = (ListView) findViewById(R.id.list); + + getActionBar().setDisplayHomeAsUpEnabled(false); + getActionBar().setHomeButtonEnabled(false); - this.listAdapter = new ArrayAdapter<Conversation>(this, - R.layout.conversation_list_row, conversationList) { - @Override - public View getView(int position, View view, ViewGroup parent) { - if (view == null) { - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = (View) inflater.inflate( - R.layout.conversation_list_row, null); - } - Conversation conv; - if (conversationList.size() > position) { - conv = getItem(position); - } else { - return view; - } - if (!spl.isSlideable()) { - if (conv == getSelectedConversation()) { - view.setBackgroundColor(0xffdddddd); - } else { - view.setBackgroundColor(Color.TRANSPARENT); - } - } else { - view.setBackgroundColor(Color.TRANSPARENT); - } - TextView convName = (TextView) view - .findViewById(R.id.conversation_name); - convName.setText(conv.getName(useSubject)); - TextView convLastMsg = (TextView) view - .findViewById(R.id.conversation_lastmsg); - ImageView imagePreview = (ImageView) view - .findViewById(R.id.conversation_lastimage); - - Message latestMessage = conv.getLatestMessage(); - - if (latestMessage.getType() == Message.TYPE_TEXT) { - if ((latestMessage.getEncryption() != Message.ENCRYPTION_PGP) - && (latestMessage.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { - convLastMsg.setText(conv.getLatestMessage().getBody()); - } else { - convLastMsg - .setText(getText(R.string.encrypted_message_received)); - } - convLastMsg.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - } else if (latestMessage.getType() == Message.TYPE_IMAGE) { - if (latestMessage.getStatus() >= Message.STATUS_RECIEVED) { - convLastMsg.setVisibility(View.GONE); - imagePreview.setVisibility(View.VISIBLE); - loadBitmap(latestMessage, imagePreview); - } else { - convLastMsg.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - if (latestMessage.getStatus() == Message.STATUS_RECEIVED_OFFER) { - convLastMsg - .setText(getText(R.string.image_offered_for_download)); - } else if (latestMessage.getStatus() == Message.STATUS_RECIEVING) { - convLastMsg - .setText(getText(R.string.receiving_image)); - } else { - convLastMsg.setText(""); - } - } - } - - if (!conv.isRead()) { - convName.setTypeface(null, Typeface.BOLD); - convLastMsg.setTypeface(null, Typeface.BOLD); - } else { - convName.setTypeface(null, Typeface.NORMAL); - convLastMsg.setTypeface(null, Typeface.NORMAL); - } - - ((TextView) view.findViewById(R.id.conversation_lastupdate)) - .setText(UIHelper.readableTimeDifference(getContext(), - conv.getLatestMessage().getTimeSent())); - - ImageView profilePicture = (ImageView) view - .findViewById(R.id.conversation_image); - profilePicture.setImageBitmap(UIHelper.getContactPicture(conv, - 56, activity.getApplicationContext(), false)); - - return view; - } - - }; - + this.listAdapter = new ConversationAdapter(this, conversationList); listView.setAdapter(this.listAdapter); listView.setOnItemClickListener(new OnItemClickListener() { @@ -247,7 +163,7 @@ public class ConversationActivity extends XmppActivity { paneShouldBeOpen = false; if (getSelectedConversation() != conversationList.get(position)) { setSelectedConversation(conversationList.get(position)); - swapConversationFragment(); // .onBackendConnected(conversationList.get(position)); + swapConversationFragment(); } else { spl.closePane(); } @@ -262,9 +178,12 @@ public class ConversationActivity extends XmppActivity { @Override public void onPanelOpened(View arg0) { paneShouldBeOpen = true; - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - getActionBar().setTitle(R.string.app_name); + ActionBar ab = getActionBar(); + if (ab!=null) { + ab.setDisplayHomeAsUpEnabled(false); + ab.setHomeButtonEnabled(false); + ab.setTitle(R.string.app_name); + } invalidateOptionsMenu(); hideKeyboard(); } @@ -274,10 +193,13 @@ public class ConversationActivity extends XmppActivity { paneShouldBeOpen = false; if ((conversationList.size() > 0) && (getSelectedConversation() != null)) { - getActionBar().setDisplayHomeAsUpEnabled(true); - getActionBar().setHomeButtonEnabled(true); - getActionBar().setTitle( + ActionBar ab = getActionBar(); + if (ab!=null) { + ab.setDisplayHomeAsUpEnabled(true); + ab.setHomeButtonEnabled(true); + ab.setTitle( getSelectedConversation().getName(useSubject)); + } invalidateOptionsMenu(); if (!getSelectedConversation().isRead()) { xmppConnectionService @@ -345,10 +267,11 @@ public class ConversationActivity extends XmppActivity { @Override public void onPresenceSelected() { if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) { + pendingImageUri = xmppConnectionService.getFileBackend().getTakePhotoUri(); + Log.d("xmppService",pendingImageUri.toString()); Intent takePictureIntent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE); - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, - ImageProvider.getIncomingContentUri()); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,pendingImageUri); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); @@ -427,7 +350,7 @@ public class ConversationActivity extends XmppActivity { switch (item.getItemId()) { case android.R.id.home: spl.openPane(); - break; + return true; case R.id.action_attach_file: View menuAttachFile = findViewById(R.id.action_attach_file); if (menuAttachFile==null) { @@ -602,12 +525,15 @@ public class ConversationActivity extends XmppActivity { protected ConversationFragment swapConversationFragment() { ConversationFragment selectedFragment = new ConversationFragment(); + if (!isFinishing()) { FragmentTransaction transaction = getFragmentManager() .beginTransaction(); transaction.replace(R.id.selected_conversation, selectedFragment, "conversation"); - transaction.commitAllowingStateLoss(); + + transaction.commitAllowingStateLoss(); + } return selectedFragment; } @@ -624,19 +550,24 @@ public class ConversationActivity extends XmppActivity { @Override protected void onNewIntent(Intent intent) { - if ((Intent.ACTION_VIEW.equals(intent.getAction()) && (VIEW_CONVERSATION - .equals(intent.getType())))) { - String convToView = (String) intent.getExtras().get(CONVERSATION); - updateConversationList(); - for (int i = 0; i < conversationList.size(); ++i) { - if (conversationList.get(i).getUuid().equals(convToView)) { - setSelectedConversation(conversationList.get(i)); - break; + if (xmppConnectionServiceBound) { + if ((Intent.ACTION_VIEW.equals(intent.getAction()) && (VIEW_CONVERSATION + .equals(intent.getType())))) { + String convToView = (String) intent.getExtras().get(CONVERSATION); + updateConversationList(); + for (int i = 0; i < conversationList.size(); ++i) { + if (conversationList.get(i).getUuid().equals(convToView)) { + setSelectedConversation(conversationList.get(i)); + break; + } } + paneShouldBeOpen = false; + String text = intent.getExtras().getString(TEXT, null); + swapConversationFragment().setText(text); } - paneShouldBeOpen = false; - String text = intent.getExtras().getString(TEXT, null); - swapConversationFragment().setText(text); + } else { + handledViewIntent = false; + setIntent(intent); } } @@ -669,6 +600,13 @@ public class ConversationActivity extends XmppActivity { if (conversationList.size() == 0) { updateConversationList(); } + + if (getSelectedConversation()!=null && pendingImageUri !=null) { + attachImageToConversation(getSelectedConversation(), pendingImageUri); + pendingImageUri = null; + } else { + pendingImageUri = null; + } if ((getIntent().getAction() != null) && (getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) { @@ -690,8 +628,7 @@ public class ConversationActivity extends XmppActivity { } } else { if (xmppConnectionService.getAccounts().size() == 0) { - startActivity(new Intent(this, ManageAccountActivity.class)); - finish(); + startActivity(new Intent(this, EditAccountActivity.class)); } else if (conversationList.size() <= 0) { // add no history startActivity(new Intent(this, StartConversationActivity.class)); @@ -731,8 +668,11 @@ public class ConversationActivity extends XmppActivity { selectedFragment.hideSnackbar(); } } else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) { - attachImageToConversation(getSelectedConversation(), - data.getData()); + pendingImageUri = data.getData(); + if (xmppConnectionServiceBound) { + attachImageToConversation(getSelectedConversation(),pendingImageUri); + pendingImageUri = null; + } } else if (requestCode == REQUEST_SEND_PGP_IMAGE) { } else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) { @@ -745,19 +685,22 @@ public class ConversationActivity extends XmppActivity { } else if (requestCode == REQUEST_ENCRYPT_MESSAGE) { // encryptTextMessage(); } else if (requestCode == REQUEST_IMAGE_CAPTURE) { - attachImageToConversation(getSelectedConversation(), null); + if (xmppConnectionServiceBound) { + attachImageToConversation(getSelectedConversation(), pendingImageUri); + pendingImageUri = null; + } + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(pendingImageUri); + sendBroadcast(intent); } else if (requestCode == REQUEST_RECORD_AUDIO) { - Log.d("xmppService", data.getData().toString()); attachAudioToConversation(getSelectedConversation(), data.getData()); - } else { - Log.d(LOGTAG, "unknown result code:" + requestCode); } } } private void attachAudioToConversation(Conversation conversation, Uri uri) { - + } private void attachImageToConversation(Conversation conversation, Uri uri) { @@ -818,9 +761,7 @@ public class ConversationActivity extends XmppActivity { try { this.startIntentSenderForResult(pi.getIntentSender(), requestCode, null, 0, 0, 0); - } catch (SendIntentException e1) { - Log.d("xmppService", "failed to start intent to send message"); - } + } catch (SendIntentException e1) {} } class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { @@ -838,7 +779,6 @@ public class ConversationActivity extends XmppActivity { return xmppConnectionService.getFileBackend().getThumbnail( message, (int) (metrics.density * 288), false); } catch (FileNotFoundException e) { - Log.d("xmppService", "file not found!"); return null; } } @@ -873,7 +813,11 @@ public class ConversationActivity extends XmppActivity { final AsyncDrawable asyncDrawable = new AsyncDrawable( getResources(), null, task); imageView.setImageDrawable(asyncDrawable); - task.execute(message); + try { + task.execute(message); + } catch (RejectedExecutionException e) { + return; + } } } } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 1df59843..48fa8c69 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -13,13 +13,16 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.EditMessage.OnEnterPressed; import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected; import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; +import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; import eu.siacs.conversations.utils.UIHelper; import android.app.AlertDialog; import android.app.Fragment; import android.app.PendingIntent; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentSender; @@ -30,14 +33,17 @@ import android.preference.PreferenceManager; import android.text.Editable; import android.text.Selection; import android.view.Gravity; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView.OnScrollListener; +import android.widget.TextView.OnEditorActionListener; import android.widget.AbsListView; -import android.widget.EditText; import android.widget.ListView; import android.widget.ImageButton; import android.widget.RelativeLayout; @@ -55,7 +61,7 @@ public class ConversationFragment extends Fragment { protected String queuedPqpMessage = null; - private EditText chatMsg; + private EditMessage mEditMessage; private String pastedText = null; private RelativeLayout snackbar; private TextView snackbarMessage; @@ -66,23 +72,28 @@ public class ConversationFragment extends Fragment { private IntentSender askForPassphraseIntent = null; - private OnClickListener sendMsgListener = new OnClickListener() { + private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() { @Override - public void onClick(View v) { - if (chatMsg.getText().length() < 1) - return; - Message message = new Message(conversation, chatMsg.getText() - .toString(), conversation.getNextEncryption()); - if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) { - sendOtrMessage(message); - } else if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { - sendPgpMessage(message); + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + InputMethodManager imm = (InputMethodManager) v.getContext() + .getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(v.getWindowToken(), 0); + return true; } else { - sendPlainTextMessage(message); + return false; } } }; + + private OnClickListener mSendButtonListener = new OnClickListener() { + + @Override + public void onClick(View v) { + sendMessage(); + } + }; protected OnClickListener clickToDecryptListener = new OnClickListener() { @Override @@ -148,19 +159,53 @@ public class ConversationFragment extends Fragment { private ConversationActivity activity; + private void sendMessage() { + if (mEditMessage.getText().length() < 1) { + if (this.conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setNextPresence(null); + updateChatMsgHint(); + } + return; + } + Message message = new Message(conversation, mEditMessage.getText() + .toString(), conversation.getNextEncryption()); + if (conversation.getMode() == Conversation.MODE_MULTI) { + if (conversation.getNextPresence() != null) { + message.setPresence(conversation.getNextPresence()); + message.setType(Message.TYPE_PRIVATE); + conversation.setNextPresence(null); + } + } + if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) { + sendOtrMessage(message); + } else if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { + sendPgpMessage(message); + } else { + sendPlainTextMessage(message); + } + } + public void updateChatMsgHint() { - switch (conversation.getNextEncryption()) { - case Message.ENCRYPTION_NONE: - chatMsg.setHint(getString(R.string.send_plain_text_message)); - break; - case Message.ENCRYPTION_OTR: - chatMsg.setHint(getString(R.string.send_otr_message)); - break; - case Message.ENCRYPTION_PGP: - chatMsg.setHint(getString(R.string.send_pgp_message)); - break; - default: - break; + if (conversation.getMode() == Conversation.MODE_MULTI + && conversation.getNextPresence() != null) { + this.mEditMessage.setHint(getString( + R.string.send_private_message_to, + conversation.getNextPresence())); + } else { + switch (conversation.getNextEncryption()) { + case Message.ENCRYPTION_NONE: + mEditMessage + .setHint(getString(R.string.send_plain_text_message)); + break; + case Message.ENCRYPTION_OTR: + mEditMessage.setHint(getString(R.string.send_otr_message)); + break; + case Message.ENCRYPTION_PGP: + mEditMessage.setHint(getString(R.string.send_pgp_message)); + break; + default: + break; + } } } @@ -169,8 +214,8 @@ public class ConversationFragment extends Fragment { ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_conversation, container, false); - chatMsg = (EditText) view.findViewById(R.id.textinput); - chatMsg.setOnClickListener(new OnClickListener() { + mEditMessage = (EditMessage) view.findViewById(R.id.textinput); + mEditMessage.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -179,10 +224,18 @@ public class ConversationFragment extends Fragment { } } }); + mEditMessage.setOnEditorActionListener(mEditorActionListener); + mEditMessage.setOnEnterPressedListener(new OnEnterPressed() { + + @Override + public void onEnterPressed() { + sendMessage(); + } + }); ImageButton sendButton = (ImageButton) view .findViewById(R.id.textSendButton); - sendButton.setOnClickListener(this.sendMsgListener); + sendButton.setOnClickListener(this.mSendButtonListener); snackbar = (RelativeLayout) view.findViewById(R.id.snackbar); snackbarMessage = (TextView) view.findViewById(R.id.snackbar_message); @@ -191,30 +244,56 @@ public class ConversationFragment extends Fragment { messagesView = (ListView) view.findViewById(R.id.messages_view); messagesView.setOnScrollListener(mOnScrollListener); messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); - messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList); - messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() { - - @Override - public void onContactPictureClicked(Message message) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - highlightInConference(message.getCounterpart()); - } - } - }); + messageListAdapter = new MessageAdapter( + (ConversationActivity) getActivity(), this.messageList); + messageListAdapter + .setOnContactPictureClicked(new OnContactPictureClicked() { + + @Override + public void onContactPictureClicked(Message message) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + if (message.getPresence() != null) { + highlightInConference(message.getPresence()); + } else { + highlightInConference(message.getCounterpart()); + } + } + } + }); + messageListAdapter + .setOnContactPictureLongClicked(new OnContactPictureLongClicked() { + + @Override + public void onContactPictureLongClicked(Message message) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + if (message.getPresence() != null) { + privateMessageWith(message.getPresence()); + } else { + privateMessageWith(message.getCounterpart()); + } + } + } + }); messagesView.setAdapter(messageListAdapter); return view; } + protected void privateMessageWith(String counterpart) { + this.mEditMessage.setText(""); + this.conversation.setNextPresence(counterpart); + updateChatMsgHint(); + } + protected void highlightInConference(String nick) { - String oldString = chatMsg.getText().toString().trim(); + String oldString = mEditMessage.getText().toString().trim(); if (oldString.isEmpty()) { - chatMsg.setText(nick + ": "); + mEditMessage.setText(nick + ": "); } else { - chatMsg.setText(oldString + " " + nick + " "); + mEditMessage.setText(oldString + " " + nick + " "); } - int position = chatMsg.length(); - Editable etext = chatMsg.getText(); + int position = mEditMessage.length(); + Editable etext = mEditMessage.getText(); Selection.setSelection(etext, position); } @@ -234,31 +313,31 @@ public class ConversationFragment extends Fragment { public void onStop() { super.onStop(); if (this.conversation != null) { - this.conversation.setNextMessage(chatMsg.getText().toString()); + this.conversation.setNextMessage(mEditMessage.getText().toString()); } } public void onBackendConnected() { + this.activity = (ConversationActivity) getActivity(); this.conversation = activity.getSelectedConversation(); if (this.conversation == null) { return; } String oldString = conversation.getNextMessage().trim(); if (this.pastedText == null) { - this.chatMsg.setText(oldString); + this.mEditMessage.setText(oldString); } else { if (oldString.isEmpty()) { - chatMsg.setText(pastedText); + mEditMessage.setText(pastedText); } else { - chatMsg.setText(oldString + " " + pastedText); + mEditMessage.setText(oldString + " " + pastedText); } pastedText = null; } - int position = chatMsg.length(); - Editable etext = chatMsg.getText(); + int position = mEditMessage.length(); + Editable etext = mEditMessage.getText(); Selection.setSelection(etext, position); - updateMessages(); if (activity.getSlidingPaneLayout().isSlideable()) { if (!activity.shouldPaneBeOpen()) { activity.getSlidingPaneLayout().closePane(); @@ -269,6 +348,10 @@ public class ConversationFragment extends Fragment { activity.invalidateOptionsMenu(); } } + if (this.conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setNextPresence(null); + } + updateMessages(); } private void decryptMessage(Message message) { @@ -307,15 +390,19 @@ public class ConversationFragment extends Fragment { 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); - } - }); + 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) @@ -371,7 +458,8 @@ public class ConversationFragment extends Fragment { if (size >= 1) { messagesView.setSelection(size - 1); } - chatMsg.setText(""); + mEditMessage.setText(""); + updateChatMsgHint(); } protected void updateStatusMessages() { @@ -425,7 +513,9 @@ public class ConversationFragment extends Fragment { protected void showSnackbar(int message, int action, OnClickListener clickListener) { snackbar.setVisibility(View.VISIBLE); + snackbar.setOnClickListener(null); snackbarMessage.setText(message); + snackbarMessage.setOnClickListener(null); snackbarAction.setText(action); snackbarAction.setOnClickListener(clickListener); } @@ -560,6 +650,6 @@ public class ConversationFragment extends Fragment { } public void clearInputField() { - this.chatMsg.setText(""); + this.mEditMessage.setText(""); } } diff --git a/src/eu/siacs/conversations/ui/EditAccountActivity.java b/src/eu/siacs/conversations/ui/EditAccountActivity.java new file mode 100644 index 00000000..2d24aa49 --- /dev/null +++ b/src/eu/siacs/conversations/ui/EditAccountActivity.java @@ -0,0 +1,341 @@ +package eu.siacs.conversations.ui; + +import android.app.PendingIntent; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.TextView; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; +import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; +import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.utils.Validator; +import eu.siacs.conversations.xmpp.XmppConnection.Features; +import eu.siacs.conversations.xmpp.pep.Avatar; + +public class EditAccountActivity extends XmppActivity { + + private AutoCompleteTextView mAccountJid; + private EditText mPassword; + private EditText mPasswordConfirm; + private CheckBox mRegisterNew; + private Button mCancelButton; + private Button mSaveButton; + + private LinearLayout mStats; + private TextView mServerInfoSm; + private TextView mServerInfoCarbons; + private TextView mServerInfoPep; + private TextView mSessionEst; + private TextView mOtrFingerprint; + private TextView mOtrFingerprintHeadline; + + private String jidToEdit; + private Account mAccount; + + private boolean mFetchingAvatar = false; + + private OnClickListener mSaveButtonClickListener = new OnClickListener() { + + @Override + public void onClick(View v) { + if (!Validator.isValidJid(mAccountJid.getText().toString())) { + mAccountJid.setError(getString(R.string.invalid_jid)); + mAccountJid.requestFocus(); + return; + } + boolean registerNewAccount = mRegisterNew.isChecked(); + String[] jidParts = mAccountJid.getText().toString().split("@"); + String username = jidParts[0]; + String server; + if (jidParts.length >= 2) { + server = jidParts[1]; + } else { + server = ""; + } + String password = mPassword.getText().toString(); + String passwordConfirm = mPasswordConfirm.getText().toString(); + if (registerNewAccount) { + if (!password.equals(passwordConfirm)) { + mPasswordConfirm + .setError(getString(R.string.passwords_do_not_match)); + mPasswordConfirm.requestFocus(); + return; + } + } + if (mAccount != null) { + mAccount.setPassword(password); + mAccount.setUsername(username); + mAccount.setServer(server); + mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); + xmppConnectionService.updateAccount(mAccount); + } else { + if (xmppConnectionService.findAccountByJid(mAccountJid + .getText().toString()) != null) { + mAccountJid + .setError(getString(R.string.account_already_exists)); + mAccountJid.requestFocus(); + return; + } + mAccount = new Account(username, server, password); + mAccount.setOption(Account.OPTION_USETLS, true); + mAccount.setOption(Account.OPTION_USECOMPRESSION, true); + mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount); + xmppConnectionService.createAccount(mAccount); + } + if (jidToEdit != null) { + finish(); + } else { + updateSaveButton(); + updateAccountInformation(); + } + + } + }; + private OnClickListener mCancelButtonClickListener = new OnClickListener() { + + @Override + public void onClick(View v) { + finish(); + } + }; + private OnAccountUpdate mOnAccountUpdateListener = new OnAccountUpdate() { + + @Override + public void onAccountUpdate() { + runOnUiThread(new Runnable() { + + @Override + public void run() { + if (mAccount != null + && mAccount.getStatus() != Account.STATUS_ONLINE + && mFetchingAvatar) { + startActivity(new Intent(getApplicationContext(), + ManageAccountActivity.class)); + finish(); + } else if (jidToEdit == null && mAccount != null + && mAccount.getStatus() == Account.STATUS_ONLINE) { + if (!mFetchingAvatar) { + mFetchingAvatar = true; + xmppConnectionService.checkForAvatar(mAccount, + mAvatarFetchCallback); + } + } else { + updateSaveButton(); + } + if (mAccount != null) { + updateAccountInformation(); + } + } + }); + } + }; + private UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() { + + @Override + public void userInputRequried(PendingIntent pi, Avatar avatar) { + finishInitialSetup(avatar); + } + + @Override + public void success(Avatar avatar) { + finishInitialSetup(avatar); + } + + @Override + public void error(int errorCode, Avatar avatar) { + finishInitialSetup(avatar); + } + }; + private KnownHostsAdapter mKnownHostsAdapter; + + protected void finishInitialSetup(final Avatar avatar) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + Intent intent; + if (avatar != null) { + intent = new Intent(getApplicationContext(), + StartConversationActivity.class); + } else { + intent = new Intent(getApplicationContext(), + PublishProfilePictureActivity.class); + intent.putExtra("account", mAccount.getJid()); + intent.putExtra("setup", true); + } + startActivity(intent); + finish(); + } + }); + } + + protected boolean inputDataDiffersFromAccount() { + if (mAccount == null) { + return true; + } else { + return (!mAccount.getJid().equals(mAccountJid.getText().toString())) + || (!mAccount.getPassword().equals( + mPassword.getText().toString()) || mAccount + .isOptionSet(Account.OPTION_REGISTER) != mRegisterNew + .isChecked()); + } + } + + protected void updateSaveButton() { + if (mAccount != null + && mAccount.getStatus() == Account.STATUS_CONNECTING) { + this.mSaveButton.setEnabled(false); + this.mSaveButton.setTextColor(getSecondaryTextColor()); + this.mSaveButton.setText(R.string.account_status_connecting); + } else { + this.mSaveButton.setEnabled(true); + this.mSaveButton.setTextColor(getPrimaryTextColor()); + if (jidToEdit != null) { + this.mSaveButton.setText(R.string.connect); + } else { + this.mSaveButton.setText(R.string.next); + } + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_edit_account); + this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid); + this.mPassword = (EditText) findViewById(R.id.account_password); + this.mPasswordConfirm = (EditText) findViewById(R.id.account_password_confirm); + this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new); + this.mStats = (LinearLayout) findViewById(R.id.stats); + this.mSessionEst = (TextView) findViewById(R.id.session_est); + this.mServerInfoCarbons = (TextView) findViewById(R.id.server_info_carbons); + this.mServerInfoSm = (TextView) findViewById(R.id.server_info_sm); + this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep); + this.mOtrFingerprint = (TextView) findViewById(R.id.otr_fingerprint); + this.mOtrFingerprintHeadline = (TextView) findViewById(R.id.otr_fingerprint_headline); + this.mSaveButton = (Button) findViewById(R.id.save_button); + this.mCancelButton = (Button) findViewById(R.id.cancel_button); + this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener); + this.mCancelButton.setOnClickListener(this.mCancelButtonClickListener); + this.mRegisterNew + .setOnCheckedChangeListener(new OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + if (isChecked) { + mPasswordConfirm.setVisibility(View.VISIBLE); + } else { + mPasswordConfirm.setVisibility(View.GONE); + } + updateSaveButton(); + } + }); + } + + @Override + protected void onStart() { + super.onStart(); + if (getIntent() != null) { + this.jidToEdit = getIntent().getStringExtra("jid"); + if (this.jidToEdit != null) { + this.mRegisterNew.setVisibility(View.GONE); + getActionBar().setTitle(R.string.mgmt_account_edit); + } else { + getActionBar().setTitle(R.string.action_add_account); + } + } + } + + @Override + protected void onStop() { + if (xmppConnectionServiceBound) { + xmppConnectionService.removeOnAccountListChangedListener(); + } + super.onStop(); + } + + @Override + protected void onBackendConnected() { + this.mKnownHostsAdapter = new KnownHostsAdapter(this, + android.R.layout.simple_list_item_1, + xmppConnectionService.getKnownHosts()); + this.xmppConnectionService + .setOnAccountListChangedListener(this.mOnAccountUpdateListener); + if (this.jidToEdit != null) { + this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit); + updateAccountInformation(); + } else if (this.xmppConnectionService.getAccounts().size() == 0) { + getActionBar().setDisplayHomeAsUpEnabled(false); + getActionBar().setDisplayShowHomeEnabled(false); + this.mCancelButton.setEnabled(false); + this.mCancelButton.setTextColor(getSecondaryTextColor()); + } + this.mAccountJid.setAdapter(this.mKnownHostsAdapter); + updateSaveButton(); + } + + private void updateAccountInformation() { + this.mAccountJid.setText(this.mAccount.getJid()); + this.mPassword.setText(this.mAccount.getPassword()); + if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) { + this.mRegisterNew.setVisibility(View.VISIBLE); + this.mRegisterNew.setChecked(true); + this.mPasswordConfirm.setText(this.mAccount.getPassword()); + } else { + this.mRegisterNew.setVisibility(View.GONE); + this.mRegisterNew.setChecked(false); + } + if (this.mAccount.getStatus() == Account.STATUS_ONLINE + && !this.mFetchingAvatar) { + this.mStats.setVisibility(View.VISIBLE); + this.mSessionEst.setText(UIHelper.readableTimeDifference( + getApplicationContext(), this.mAccount.getXmppConnection() + .getLastSessionEstablished())); + Features features = this.mAccount.getXmppConnection().getFeatures(); + if (features.carbons()) { + this.mServerInfoCarbons.setText(R.string.server_info_available); + } else { + this.mServerInfoCarbons + .setText(R.string.server_info_unavailable); + } + if (features.sm()) { + this.mServerInfoSm.setText(R.string.server_info_available); + } else { + this.mServerInfoSm.setText(R.string.server_info_unavailable); + } + if (features.pubsub()) { + this.mServerInfoPep.setText(R.string.server_info_available); + } else { + this.mServerInfoPep.setText(R.string.server_info_unavailable); + } + String fingerprint = this.mAccount + .getOtrFingerprint(getApplicationContext()); + if (fingerprint != null) { + this.mOtrFingerprintHeadline.setVisibility(View.VISIBLE); + this.mOtrFingerprint.setVisibility(View.VISIBLE); + this.mOtrFingerprint.setText(fingerprint); + } else { + this.mOtrFingerprint.setVisibility(View.GONE); + this.mOtrFingerprintHeadline.setVisibility(View.GONE); + } + } else { + if (this.mAccount.errorStatus()) { + this.mAccountJid.setError(getString(this.mAccount + .getReadableStatusId())); + this.mAccountJid.requestFocus(); + } + this.mStats.setVisibility(View.GONE); + } + } +} diff --git a/src/eu/siacs/conversations/ui/EditAccountDialog.java b/src/eu/siacs/conversations/ui/EditAccountDialog.java deleted file mode 100644 index 7c135fc1..00000000 --- a/src/eu/siacs/conversations/ui/EditAccountDialog.java +++ /dev/null @@ -1,157 +0,0 @@ -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; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.EditText; -import android.widget.TextView; - -public class EditAccountDialog extends DialogFragment { - - protected Account account; - - protected AutoCompleteTextView mAccountJid; - - public void setAccount(Account account) { - this.account = account; - } - - public interface EditAccountListener { - public void onAccountEdited(Account account); - } - - 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); - 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); - - final EditText password = (EditText) view - .findViewById(R.id.account_password); - final EditText passwordConfirm = (EditText) view - .findViewById(R.id.account_password_confirm2); - final CheckBox registerAccount = (CheckBox) view - .findViewById(R.id.edit_account_register_new); - - if (account != null) { - mAccountJid.setText(account.getJid()); - password.setText(account.getPassword()); - if (account.isOptionSet(Account.OPTION_REGISTER)) { - registerAccount.setChecked(true); - passwordConfirm.setVisibility(View.VISIBLE); - passwordConfirm.setText(account.getPassword()); - } else { - registerAccount.setVisibility(View.GONE); - } - } - builder.setTitle(R.string.account_settings); - - - registerAccount - .setOnCheckedChangeListener(new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - if (isChecked) { - passwordConfirm.setVisibility(View.VISIBLE); - confirmPwDesc.setVisibility(View.VISIBLE); - } else { - passwordConfirm.setVisibility(View.GONE); - confirmPwDesc.setVisibility(View.GONE); - } - } - }); - - builder.setView(view); - builder.setNeutralButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.save), null); - return builder.create(); - } - - @Override - public void onStart() { - super.onStart(); - final AlertDialog d = (AlertDialog) getDialog(); - Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE); - positiveButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EditText jidEdit = (EditText) d.findViewById(R.id.account_jid); - String jid = jidEdit.getText().toString(); - EditText passwordEdit = (EditText) d - .findViewById(R.id.account_password); - EditText passwordConfirmEdit = (EditText) d.findViewById(R.id.account_password_confirm2); - String password = passwordEdit.getText().toString(); - String passwordConfirm = passwordConfirmEdit.getText().toString(); - CheckBox register = (CheckBox) d.findViewById(R.id.edit_account_register_new); - String username; - String server; - if (Validator.isValidJid(jid)) { - String[] parts = jid.split("@"); - username = parts[0]; - server = parts[1]; - } else { - jidEdit.setError(getString(R.string.invalid_jid)); - return; - } - if (register.isChecked()) { - if (!passwordConfirm.equals(password)) { - passwordConfirmEdit.setError(getString(R.string.passwords_do_not_match)); - return; - } - } - if (account != null) { - account.setPassword(password); - account.setUsername(username); - account.setServer(server); - } else { - account = new Account(username, server, password); - account.setOption(Account.OPTION_USETLS, true); - account.setOption(Account.OPTION_USECOMPRESSION, true); - } - account.setOption(Account.OPTION_REGISTER, register.isChecked()); - if (listener != null) { - listener.onAccountEdited(account); - d.dismiss(); - } - } - }); - } -} diff --git a/src/eu/siacs/conversations/ui/EditMessage.java b/src/eu/siacs/conversations/ui/EditMessage.java new file mode 100644 index 00000000..f8302050 --- /dev/null +++ b/src/eu/siacs/conversations/ui/EditMessage.java @@ -0,0 +1,39 @@ +package eu.siacs.conversations.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.widget.EditText; + +public class EditMessage extends EditText { + + public EditMessage(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public EditMessage(Context context) { + super(context); + } + + protected OnEnterPressed mOnEnterPressed; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_ENTER) { + if (mOnEnterPressed != null) { + mOnEnterPressed.onEnterPressed(); + } + return true; + } + return super.onKeyDown(keyCode, event); + } + + public void setOnEnterPressedListener(OnEnterPressed listener) { + this.mOnEnterPressed = listener; + } + + public interface OnEnterPressed { + public void onEnterPressed(); + } + +} diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java index e56e2db9..c57121da 100644 --- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -6,42 +6,31 @@ import java.util.List; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; -import eu.siacs.conversations.ui.EditAccountDialog.EditAccountListener; -import eu.siacs.conversations.xmpp.XmppConnection; -import android.app.Activity; +import eu.siacs.conversations.ui.adapter.AccountAdapter; import android.app.AlertDialog; -import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; -import android.os.SystemClock; -import android.view.ActionMode; -import android.view.LayoutInflater; +import android.view.ContextMenu; import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; +import android.view.ContextMenu.ContextMenuInfo; import android.widget.AdapterView; +import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ArrayAdapter; 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 Account selectedAccount = null; protected List<Account> accountList = new ArrayList<Account>(); protected ListView accountListView; - protected ArrayAdapter<Account> accountListViewAdapter; + protected AccountAdapter mAccountAdapter; protected OnAccountUpdate accountChanged = new OnAccountUpdate() { @Override @@ -52,7 +41,7 @@ public class ManageAccountActivity extends XmppActivity { @Override public void run() { - accountListViewAdapter.notifyDataSetChanged(); + mAccountAdapter.notifyDataSetChanged(); } }); } @@ -66,347 +55,34 @@ public class ManageAccountActivity extends XmppActivity { setContentView(R.layout.manage_accounts); accountListView = (ListView) findViewById(R.id.account_list); - accountListViewAdapter = new ArrayAdapter<Account>( - getApplicationContext(), R.layout.account_row, this.accountList) { - @Override - public View getView(int position, View view, ViewGroup parent) { - Account account = getItem(position); - if (view == null) { - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = (View) inflater.inflate(R.layout.account_row, null); - } - ((TextView) view.findViewById(R.id.account_jid)) - .setText(account.getJid()); - TextView statusView = (TextView) view - .findViewById(R.id.account_status); - switch (account.getStatus()) { - case 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.setTextColor(0xFF83b600); - break; - case 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.setTextColor(0xFFe92727); - break; - case 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.setTextColor(0xFFe92727); - break; - case 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.setTextColor(0xFFe92727); - break; - case Account.STATUS_REGISTRATION_FAILED: - 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.setTextColor(0xFFe92727); - break; - 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.setTextColor(0xFFe92727); - break; - default: - statusView.setText(""); - break; - } - - return view; - } - }; - final XmppActivity activity = this; - accountListView.setAdapter(this.accountListViewAdapter); + this.mAccountAdapter = new AccountAdapter(this, accountList); + accountListView.setAdapter(this.mAccountAdapter); accountListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) { - if (!isActionMode) { - Account account = accountList.get(position); - if (account.getStatus() == Account.STATUS_OFFLINE) { - activity.xmppConnectionService.reconnectAccount( - accountList.get(position), true); - } else if (account.getStatus() == Account.STATUS_ONLINE) { - activity.startActivity(new Intent(activity - .getApplicationContext(), - StartConversationActivity.class)); - } else if (account.getStatus() != Account.STATUS_DISABLED) { - editAccount(account); - } - } else { - selectedAccountForActionMode = accountList.get(position); - actionMode.invalidate(); - } + editAccount(accountList.get(position)); } }); - 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)); - } - 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; - } + registerForContextMenu(accountListView); + } - })); - return true; - } else { - return false; - } - } - }); + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + activity.getMenuInflater().inflate(R.menu.manageaccounts_context, menu); + AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; + this.selectedAccount = accountList.get(acmi.position); + if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) { + menu.findItem(R.id.mgmt_account_disable).setVisible(false); + menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(false); + menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false); + } else { + menu.findItem(R.id.mgmt_account_enable).setVisible(false); + } + menu.setHeaderTitle(this.selectedAccount.getJid()); } @Override @@ -422,13 +98,7 @@ public class ManageAccountActivity extends XmppActivity { xmppConnectionService.setOnAccountListChangedListener(accountChanged); this.accountList.clear(); this.accountList.addAll(xmppConnectionService.getAccounts()); - accountListViewAdapter.notifyDataSetChanged(); - if ((this.accountList.size() == 0) && (this.firstrun)) { - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - addAccount(); - this.firstrun = false; - } + mAccountAdapter.notifyDataSetChanged(); } @Override @@ -438,10 +108,33 @@ public class ManageAccountActivity extends XmppActivity { } @Override + public boolean onContextItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.mgmt_account_publish_avatar: + publishAvatar(selectedAccount); + return true; + case R.id.mgmt_account_disable: + disableAccount(selectedAccount); + return true; + case R.id.mgmt_account_enable: + enableAccount(selectedAccount); + return true; + case R.id.mgmt_account_delete: + deleteAccount(selectedAccount); + return true; + case R.id.mgmt_account_announce_pgp: + publishOpenPGPPublicKey(selectedAccount); + default: + return super.onContextItemSelected(item); + } + } + + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_add_account: - addAccount(); + startActivity(new Intent(getApplicationContext(), + EditAccountActivity.class)); break; default: break; @@ -452,7 +145,8 @@ public class ManageAccountActivity extends XmppActivity { @Override public boolean onNavigateUp() { if (xmppConnectionService.getConversations().size() == 0) { - Intent contactsIntent = new Intent(this, StartConversationActivity.class); + Intent contactsIntent = new Intent(this, + StartConversationActivity.class); contactsIntent.setFlags( // if activity exists in stack, pop the stack and go back to it Intent.FLAG_ACTIVITY_CLEAR_TOP | @@ -470,57 +164,51 @@ public class ManageAccountActivity extends XmppActivity { } private void editAccount(Account account) { - 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(); - } - } - }); - dialog.show(getFragmentManager(), "edit_account"); - dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this); + Intent intent = new Intent(this, EditAccountActivity.class); + intent.putExtra("jid", account.getJid()); + startActivity(intent); + } + private void publishAvatar(Account account) { + Intent intent = new Intent(getApplicationContext(), + PublishProfilePictureActivity.class); + intent.putExtra("account", account.getJid()); + startActivity(intent); } - protected void addAccount() { - final Activity activity = this; - EditAccountDialog dialog = new EditAccountDialog(); - dialog.setEditAccountListener(new EditAccountListener() { + private void disableAccount(Account account) { + account.setOption(Account.OPTION_DISABLED, true); + xmppConnectionService.updateAccount(account); + } - @Override - public void onAccountEdited(Account account) { - xmppConnectionService.createAccount(account); - activity.getActionBar().setDisplayHomeAsUpEnabled(true); - activity.getActionBar().setHomeButtonEnabled(true); - } - }); - dialog.show(getFragmentManager(), "add_account"); - dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this); + private void enableAccount(Account account) { + account.setOption(Account.OPTION_DISABLED, false); + xmppConnectionService.updateAccount(account); } - @Override - public void onActionModeStarted(ActionMode mode) { - super.onActionModeStarted(mode); - this.isActionMode = true; + private void publishOpenPGPPublicKey(Account account) { + if (activity.hasPgp()) { + announcePgp(account, null); + } else { + this.showInstallPgpDialog(); + } } - @Override - public void onActionModeFinished(ActionMode mode) { - super.onActionModeFinished(mode); - this.isActionMode = false; - accountListView.clearChoices(); - accountListView.requestLayout(); - accountListView.post(new Runnable() { - @Override - public void run() { - accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE); - } - }); + private void deleteAccount(final Account account) { + 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(account); + selectedAccount = null; + } + }); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.create().show(); } @Override @@ -528,7 +216,7 @@ public class ManageAccountActivity extends XmppActivity { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == REQUEST_ANNOUNCE_PGP) { - announcePgp(selectedAccountForActionMode, null); + announcePgp(selectedAccount, null); } } } diff --git a/src/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/eu/siacs/conversations/ui/PublishProfilePictureActivity.java new file mode 100644 index 00000000..c4c1b45e --- /dev/null +++ b/src/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -0,0 +1,242 @@ +package eu.siacs.conversations.ui; + +import android.app.PendingIntent; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.utils.PhoneHelper; +import eu.siacs.conversations.xmpp.pep.Avatar; + +public class PublishProfilePictureActivity extends XmppActivity { + + private static final int REQUEST_CHOOSE_FILE = 0xac23; + + private ImageView avatar; + private TextView accountTextView; + private TextView hintOrWarning; + private TextView secondaryHint; + private Button cancelButton; + private Button publishButton; + + private Uri avatarUri; + private Uri defaultUri; + + private Account account; + + private boolean support = false; + + private boolean mInitialAccountSetup; + + private UiCallback<Avatar> avatarPublication = new UiCallback<Avatar>() { + + @Override + public void success(Avatar object) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + if (mInitialAccountSetup) { + startActivity(new Intent(getApplicationContext(), + StartConversationActivity.class)); + } + finish(); + } + }); + } + + @Override + public void error(final int errorCode, Avatar object) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + hintOrWarning.setText(errorCode); + hintOrWarning.setTextColor(getWarningTextColor()); + publishButton.setText(R.string.publish_avatar); + enablePublishButton(); + } + }); + + } + + @Override + public void userInputRequried(PendingIntent pi, Avatar object) { + } + }; + + private OnLongClickListener backToDefaultListener = new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + avatarUri = defaultUri; + loadImageIntoPreview(defaultUri); + return true; + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_publish_profile_picture); + this.avatar = (ImageView) findViewById(R.id.account_image); + this.cancelButton = (Button) findViewById(R.id.cancel_button); + this.publishButton = (Button) findViewById(R.id.publish_button); + this.accountTextView = (TextView) findViewById(R.id.account); + this.hintOrWarning = (TextView) findViewById(R.id.hint_or_warning); + this.secondaryHint = (TextView) findViewById(R.id.secondary_hint); + this.publishButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + if (avatarUri != null) { + publishButton.setText(R.string.publishing); + disablePublishButton(); + xmppConnectionService.publishAvatar(account, avatarUri, + avatarPublication); + } + } + }); + this.cancelButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + if (mInitialAccountSetup) { + startActivity(new Intent(getApplicationContext(), + StartConversationActivity.class)); + } + finish(); + } + }); + this.avatar.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + Intent attachFileIntent = new Intent(); + attachFileIntent.setType("image/*"); + attachFileIntent.setAction(Intent.ACTION_GET_CONTENT); + Intent chooser = Intent.createChooser(attachFileIntent, + getString(R.string.attach_file)); + startActivityForResult(chooser, REQUEST_CHOOSE_FILE); + } + }); + this.defaultUri = PhoneHelper.getSefliUri(getApplicationContext()); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, + final Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == REQUEST_CHOOSE_FILE) { + this.avatarUri = data.getData(); + if (xmppConnectionServiceBound) { + loadImageIntoPreview(this.avatarUri); + } + } + } + } + + @Override + protected void onBackendConnected() { + if (getIntent() != null) { + String jid = getIntent().getStringExtra("account"); + if (jid != null) { + this.account = xmppConnectionService.findAccountByJid(jid); + if (this.account.getXmppConnection() != null) { + this.support = this.account.getXmppConnection() + .getFeatures().pubsub(); + } + if (this.avatarUri == null) { + if (this.account.getAvatar() != null + || this.defaultUri == null) { + this.avatar.setImageBitmap(this.account.getImage( + getApplicationContext(), 384)); + if (this.defaultUri != null) { + this.avatar + .setOnLongClickListener(this.backToDefaultListener); + } else { + this.secondaryHint.setVisibility(View.INVISIBLE); + } + if (!support) { + this.hintOrWarning + .setTextColor(getWarningTextColor()); + this.hintOrWarning + .setText(R.string.error_publish_avatar_no_server_support); + } + } else { + this.avatarUri = this.defaultUri; + loadImageIntoPreview(this.defaultUri); + this.secondaryHint.setVisibility(View.INVISIBLE); + } + } else { + loadImageIntoPreview(avatarUri); + } + this.accountTextView.setText(this.account.getJid()); + } + } + + } + + @Override + protected void onStart() { + super.onStart(); + if (getIntent() != null) { + this.mInitialAccountSetup = getIntent().getBooleanExtra("setup", + false); + } + if (this.mInitialAccountSetup) { + this.cancelButton.setText(R.string.skip); + } + } + + protected void loadImageIntoPreview(Uri uri) { + Bitmap bm = xmppConnectionService.getFileBackend().cropCenterSquare( + uri, 384); + if (bm == null) { + disablePublishButton(); + this.hintOrWarning.setTextColor(getWarningTextColor()); + this.hintOrWarning + .setText(R.string.error_publish_avatar_converting); + return; + } + this.avatar.setImageBitmap(bm); + if (support) { + enablePublishButton(); + this.publishButton.setText(R.string.publish_avatar); + this.hintOrWarning.setText(R.string.publish_avatar_explanation); + this.hintOrWarning.setTextColor(getPrimaryTextColor()); + } else { + disablePublishButton(); + this.hintOrWarning.setTextColor(getWarningTextColor()); + this.hintOrWarning + .setText(R.string.error_publish_avatar_no_server_support); + } + if (this.defaultUri != null && uri.equals(this.defaultUri)) { + this.secondaryHint.setVisibility(View.INVISIBLE); + this.avatar.setOnLongClickListener(null); + } else if (this.defaultUri != null) { + this.secondaryHint.setVisibility(View.VISIBLE); + this.avatar.setOnLongClickListener(this.backToDefaultListener); + } + } + + protected void enablePublishButton() { + this.publishButton.setEnabled(true); + this.publishButton.setTextColor(getPrimaryTextColor()); + } + + protected void disablePublishButton() { + this.publishButton.setEnabled(false); + this.publishButton.setTextColor(getSecondaryTextColor()); + } + +} diff --git a/src/eu/siacs/conversations/ui/SettingsActivity.java b/src/eu/siacs/conversations/ui/SettingsActivity.java index abaf8c68..f8fd9469 100644 --- a/src/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/eu/siacs/conversations/ui/SettingsActivity.java @@ -1,9 +1,8 @@ package eu.siacs.conversations.ui; -import android.app.Activity; import android.os.Bundle; -public class SettingsActivity extends Activity { +public class SettingsActivity extends XmppActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -13,4 +12,9 @@ public class SettingsActivity extends Activity { .replace(android.R.id.content, new SettingsFragment()).commit(); } + @Override + void onBackendConnected() { + + } + } diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index d12d2878..bcb9f1dd 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -21,6 +21,7 @@ import android.text.Editable; import android.text.TextWatcher; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -63,6 +64,7 @@ public class StartConversationActivity extends XmppActivity { private List<String> mKnownHosts; private List<String> mKnownConferenceHosts; + private Menu mOptionsMenu; private EditText mSearchEditText; public int conference_context_id; @@ -141,14 +143,16 @@ public class StartConversationActivity extends XmppActivity { } }; private OnRosterUpdate onRosterUpdate = new OnRosterUpdate() { - + @Override public void onRosterUpdate() { runOnUiThread(new Runnable() { - + @Override public void run() { - filter(mSearchEditText.getText().toString()); + if (mSearchEditText != null) { + filter(mSearchEditText.getText().toString()); + } } }); } @@ -187,7 +191,8 @@ public class StartConversationActivity extends XmppActivity { } }); - mConferenceAdapter = new ListItemAdapter(getApplicationContext(),conferences); + mConferenceAdapter = new ListItemAdapter(getApplicationContext(), + conferences); mConferenceListFragment.setListAdapter(mConferenceAdapter); mConferenceListFragment.setContextMenu(R.menu.conference_context); mConferenceListFragment @@ -200,7 +205,8 @@ public class StartConversationActivity extends XmppActivity { } }); - mContactsAdapter = new ListItemAdapter(getApplicationContext(),contacts); + mContactsAdapter = new ListItemAdapter(getApplicationContext(), + contacts); mContactsListFragment.setListAdapter(mContactsAdapter); mContactsListFragment.setContextMenu(R.menu.contact_context); mContactsListFragment @@ -214,7 +220,7 @@ public class StartConversationActivity extends XmppActivity { }); } - + @Override public void onStop() { super.onStop(); @@ -266,11 +272,10 @@ public class StartConversationActivity extends XmppActivity { 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() { - + 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); @@ -278,21 +283,20 @@ public class StartConversationActivity extends XmppActivity { } }); 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() { - + 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(); @@ -303,7 +307,7 @@ public class StartConversationActivity extends XmppActivity { } }); builder.create().show(); - + } protected void showCreateContactDialog() { @@ -327,6 +331,9 @@ public class StartConversationActivity extends XmppActivity { @Override public void onClick(View v) { + if (!xmppConnectionServiceBound) { + return; + } if (Validator.isValidJid(jid.getText().toString())) { String accountJid = (String) spinner .getSelectedItem(); @@ -373,6 +380,9 @@ public class StartConversationActivity extends XmppActivity { @Override public void onClick(View v) { + if (!xmppConnectionServiceBound) { + return; + } if (Validator.isValidJid(jid.getText().toString())) { String accountJid = (String) spinner .getSelectedItem(); @@ -394,7 +404,8 @@ public class StartConversationActivity extends XmppActivity { conferenceJid, true); conversation.setBookmark(bookmark); if (!conversation.getMucOptions().online()) { - xmppConnectionService.joinMuc(conversation); + xmppConnectionService + .joinMuc(conversation); } switchToConversation(conversation); } @@ -430,6 +441,7 @@ public class StartConversationActivity extends XmppActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { + this.mOptionsMenu = menu; getMenuInflater().inflate(R.menu.start_conversation, menu); MenuItem menuCreateContact = (MenuItem) menu .findItem(R.id.action_create_contact); @@ -463,8 +475,17 @@ public class StartConversationActivity extends XmppActivity { } @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_SEARCH && !event.isLongPress()) { + mOptionsMenu.findItem(R.id.action_search).expandActionView(); + return true; + } + return super.onKeyUp(keyCode, event); + } + + @Override void onBackendConnected() { - xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate ); + xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate); if (mSearchEditText != null) { filter(mSearchEditText.getText().toString()); } else { @@ -482,8 +503,10 @@ public class StartConversationActivity extends XmppActivity { } protected void filter(String needle) { - this.filterContacts(needle); - this.filterConferences(needle); + if (xmppConnectionServiceBound) { + this.filterContacts(needle); + this.filterConferences(needle); + } } protected void filterContacts(String needle) { diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index fad4d026..44043a79 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -31,22 +31,24 @@ 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 static final int REQUEST_ANNOUNCE_PGP = 0x0101; + protected static final int REQUEST_INVITE_TO_CONVERSATION = 0x0102; protected final static String LOGTAG = "xmppService"; public XmppConnectionService xmppConnectionService; public boolean xmppConnectionServiceBound = false; protected boolean handledViewIntent = false; - + protected int mPrimaryTextColor; protected int mSecondaryTextColor; - + protected int mWarningTextColor; + protected int mPrimaryColor; + protected interface OnValueEdited { public void onValueEdited(String value); } - + public interface OnPresenceSelected { public void onPresenceSelected(); } @@ -152,6 +154,9 @@ public abstract class XmppActivity extends Activity { case R.id.action_accounts: startActivity(new Intent(this, ManageAccountActivity.class)); break; + case android.R.id.home: + finish(); + break; } return super.onOptionsItemSelected(item); } @@ -162,6 +167,8 @@ public abstract class XmppActivity extends Activity { ExceptionHelper.init(getApplicationContext()); mPrimaryTextColor = getResources().getColor(R.color.primarytext); mSecondaryTextColor = getResources().getColor(R.color.secondarytext); + mWarningTextColor = getResources().getColor(R.color.warningtext); + mPrimaryColor = getResources().getColor(R.color.primary); } public void switchToConversation(Conversation conversation) { @@ -199,11 +206,12 @@ public abstract class XmppActivity extends Activity { } protected void inviteToConversation(Conversation conversation) { - Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class); - intent.putExtra("conversation",conversation.getUuid()); + 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>() { @@ -214,7 +222,8 @@ public abstract class XmppActivity extends Activity { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); - } catch (SendIntentException e) {} + } catch (SendIntentException e) { + } } @Override @@ -275,15 +284,17 @@ public abstract class XmppActivity extends Activity { builder.create().show(); } - protected void quickEdit(final String previousValue, final OnValueEdited callback) { + 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); + 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(); @@ -294,11 +305,11 @@ public abstract class XmppActivity extends Activity { }); builder.create().show(); } - + public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) { Contact contact = conversation.getContact(); - if (contact == null) { + if (!contact.showInRoster()) { showAddToRosterDialog(conversation); } else { Presences presences = contact.getPresences(); @@ -346,26 +357,37 @@ 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) { + if (requestCode == REQUEST_INVITE_TO_CONVERSATION + && resultCode == RESULT_OK) { String contactJid = data.getStringExtra("contact"); String conversationUuid = data.getStringExtra("conversation"); - Conversation conversation = xmppConnectionService.findConversationByUuid(conversationUuid); + Conversation conversation = xmppConnectionService + .findConversationByUuid(conversationUuid); if (conversation.getMode() == Conversation.MODE_MULTI) { xmppConnectionService.invite(conversation, contactJid); } - Log.d("xmppService","inviting "+contactJid+" to "+conversation.getName(true)); + Log.d("xmppService", "inviting " + contactJid + " to " + + conversation.getName(true)); } } - + public int getSecondaryTextColor() { return this.mSecondaryTextColor; } - + public int getPrimaryTextColor() { return this.mPrimaryTextColor; } + + public int getWarningTextColor() { + return this.mWarningTextColor; + } + + public int getPrimaryColor() { + return this.mPrimaryColor; + } } diff --git a/src/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/eu/siacs/conversations/ui/adapter/AccountAdapter.java new file mode 100644 index 00000000..cd8b376f --- /dev/null +++ b/src/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -0,0 +1,101 @@ +package eu.siacs.conversations.ui.adapter; + +import java.util.List; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.ui.XmppActivity; +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 AccountAdapter extends ArrayAdapter<Account> { + + private XmppActivity activity; + + public AccountAdapter(XmppActivity activity, List<Account> objects) { + super(activity, 0, objects); + this.activity = activity; + } + + @Override + public View getView(int position, View view, ViewGroup parent) { + Account account = getItem(position); + if (view == null) { + LayoutInflater inflater = (LayoutInflater) getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = (View) inflater.inflate(R.layout.account_row, parent, false); + } + TextView jid = (TextView) view.findViewById(R.id.account_jid); + jid.setText(account.getJid()); + TextView statusView = (TextView) view.findViewById(R.id.account_status); + ImageView imageView = (ImageView) view.findViewById(R.id.account_image); + imageView.setImageBitmap(account.getImage(activity,48)); + switch (account.getStatus()) { + case Account.STATUS_DISABLED: + statusView.setText(getContext().getString( + R.string.account_status_disabled)); + statusView.setTextColor(activity.getSecondaryTextColor()); + break; + case Account.STATUS_ONLINE: + statusView.setText(getContext().getString( + R.string.account_status_online)); + statusView.setTextColor(activity.getPrimaryColor()); + break; + case Account.STATUS_CONNECTING: + statusView.setText(getContext().getString( + R.string.account_status_connecting)); + statusView.setTextColor(activity.getSecondaryTextColor()); + break; + case Account.STATUS_OFFLINE: + statusView.setText(getContext().getString( + R.string.account_status_offline)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + case Account.STATUS_UNAUTHORIZED: + statusView.setText(getContext().getString( + R.string.account_status_unauthorized)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + case Account.STATUS_SERVER_NOT_FOUND: + statusView.setText(getContext().getString( + R.string.account_status_not_found)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + case Account.STATUS_NO_INTERNET: + statusView.setText(getContext().getString( + R.string.account_status_no_internet)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + case Account.STATUS_REGISTRATION_FAILED: + statusView.setText(getContext().getString( + R.string.account_status_regis_fail)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + case Account.STATUS_REGISTRATION_CONFLICT: + statusView.setText(getContext().getString( + R.string.account_status_regis_conflict)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + case Account.STATUS_REGISTRATION_SUCCESSFULL: + statusView.setText(getContext().getString( + R.string.account_status_regis_success)); + statusView.setTextColor(activity.getSecondaryTextColor()); + break; + case Account.STATUS_REGISTRATION_NOT_SUPPORTED: + statusView.setText(getContext().getString( + R.string.account_status_regis_not_sup)); + statusView.setTextColor(activity.getWarningTextColor()); + break; + default: + statusView.setText(""); + break; + } + + return view; + } +} diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java new file mode 100644 index 00000000..66403804 --- /dev/null +++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -0,0 +1,107 @@ +package eu.siacs.conversations.ui.adapter; + +import java.util.List; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.ui.ConversationActivity; +import eu.siacs.conversations.utils.UIHelper; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Typeface; +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 ConversationAdapter extends ArrayAdapter<Conversation> { + + ConversationActivity activity; + + public ConversationAdapter(ConversationActivity activity, + List<Conversation> conversations) { + super(activity, 0, conversations); + this.activity = activity; + } + + @Override + public View getView(int position, View view, ViewGroup parent) { + if (view == null) { + LayoutInflater inflater = (LayoutInflater) activity + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = (View) inflater.inflate(R.layout.conversation_list_row, + parent, false); + } + Conversation conv = getItem(position); + if (!activity.getSlidingPaneLayout().isSlideable()) { + if (conv == activity.getSelectedConversation()) { + view.setBackgroundColor(0xffdddddd); + } else { + view.setBackgroundColor(Color.TRANSPARENT); + } + } else { + view.setBackgroundColor(Color.TRANSPARENT); + } + TextView convName = (TextView) view + .findViewById(R.id.conversation_name); + convName.setText(conv.getName(true)); + TextView convLastMsg = (TextView) view + .findViewById(R.id.conversation_lastmsg); + ImageView imagePreview = (ImageView) view + .findViewById(R.id.conversation_lastimage); + + Message latestMessage = conv.getLatestMessage(); + + if (latestMessage.getType() == Message.TYPE_TEXT + || latestMessage.getType() == Message.TYPE_PRIVATE) { + if ((latestMessage.getEncryption() != Message.ENCRYPTION_PGP) + && (latestMessage.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { + convLastMsg.setText(conv.getLatestMessage().getBody()); + } else { + convLastMsg.setText(activity + .getText(R.string.encrypted_message_received)); + } + convLastMsg.setVisibility(View.VISIBLE); + imagePreview.setVisibility(View.GONE); + } else if (latestMessage.getType() == Message.TYPE_IMAGE) { + if (latestMessage.getStatus() >= Message.STATUS_RECIEVED) { + convLastMsg.setVisibility(View.GONE); + imagePreview.setVisibility(View.VISIBLE); + activity.loadBitmap(latestMessage, imagePreview); + } else { + convLastMsg.setVisibility(View.VISIBLE); + imagePreview.setVisibility(View.GONE); + if (latestMessage.getStatus() == Message.STATUS_RECEIVED_OFFER) { + convLastMsg.setText(activity + .getText(R.string.image_offered_for_download)); + } else if (latestMessage.getStatus() == Message.STATUS_RECIEVING) { + convLastMsg.setText(activity + .getText(R.string.receiving_image)); + } else { + convLastMsg.setText(""); + } + } + } + + if (!conv.isRead()) { + convName.setTypeface(null, Typeface.BOLD); + convLastMsg.setTypeface(null, Typeface.BOLD); + } else { + convName.setTypeface(null, Typeface.NORMAL); + convLastMsg.setTypeface(null, Typeface.NORMAL); + } + + ((TextView) view.findViewById(R.id.conversation_lastupdate)) + .setText(UIHelper.readableTimeDifference(getContext(), conv + .getLatestMessage().getTimeSent())); + + ImageView profilePicture = (ImageView) view + .findViewById(R.id.conversation_image); + profilePicture.setImageBitmap(conv.getImage(activity, 56)); + + return view; + } +} diff --git a/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java b/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java index 040e6266..d286052c 100644 --- a/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/KnownHostsAdapter.java @@ -23,7 +23,10 @@ public class KnownHostsAdapter extends ArrayAdapter<String> { } } else if (split.length == 2) { for (String domain : domains) { - if (domain.contains(split[1])) { + if (domain.contentEquals(split[1])) { + suggestions.clear(); + break; + } else if (domain.contains(split[1])) { suggestions.add(split[0].toLowerCase(Locale.getDefault()) + "@" + domain); } } diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 0a2857d2..72587f99 100644 --- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -7,16 +7,18 @@ import eu.siacs.conversations.R; 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.ui.ConversationActivity; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jingle.JingleConnection; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.Typeface; -import android.preference.PreferenceManager; +import android.text.Html; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; +import android.text.style.StyleSpan; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; @@ -37,44 +39,38 @@ public class MessageAdapter extends ArrayAdapter<Message> { private ConversationActivity activity; - private Bitmap selfBitmap2; + private Bitmap accountBitmap; private BitmapCache mBitmapCache = new BitmapCache(); private DisplayMetrics metrics; - private boolean useSubject = true; - private OnContactPictureClicked mOnContactPictureClickedListener; + private OnContactPictureLongClicked mOnContactPictureLongClickedListener; public MessageAdapter(ConversationActivity activity, List<Message> messages) { super(activity, 0, messages); this.activity = activity; metrics = getContext().getResources().getDisplayMetrics(); - SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(getContext()); - useSubject = preferences.getBoolean("use_subject_in_muc", true); } private Bitmap getSelfBitmap() { - if (this.selfBitmap2 == null) { + if (this.accountBitmap == null) { if (getCount() > 0) { - SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(getContext()); - boolean showPhoneSelfContactPicture = preferences.getBoolean( - "show_phone_selfcontact_picture", true); - - this.selfBitmap2 = UIHelper.getSelfContactPicture(getItem(0) - .getConversation().getAccount(), 48, - showPhoneSelfContactPicture, getContext()); + this.accountBitmap = getItem(0).getConversation().getAccount() + .getImage(getContext(), 48); } } - return this.selfBitmap2; + return this.accountBitmap; } public void setOnContactPictureClicked(OnContactPictureClicked listener) { this.mOnContactPictureClickedListener = listener; } + + public void setOnContactPictureLongClicked(OnContactPictureLongClicked listener) { + this.mOnContactPictureLongClickedListener = listener; + } @Override public int getViewTypeCount() { @@ -130,7 +126,16 @@ public class MessageAdapter extends ArrayAdapter<Message> { error = true; default: if (multiReceived) { - info = message.getCounterpart(); + Contact contact = message.getContact(); + if (contact != null) { + info = contact.getDisplayName(); + } else { + if (message.getPresence() != null) { + info = message.getPresence(); + } else { + info = message.getCounterpart(); + } + } } break; } @@ -199,14 +204,33 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.messageBody.setTextIsSelectable(false); } - private void displayTextMessage(ViewHolder viewHolder, String text) { + private void displayTextMessage(ViewHolder viewHolder, Message message) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); } viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); - if (text != null) { - viewHolder.messageBody.setText(text.trim()); + if (message.getBody() != null) { + if (message.getType() != Message.TYPE_PRIVATE) { + viewHolder.messageBody.setText(message.getBody().trim()); + } else { + String privateMarker; + if (message.getStatus() <= Message.STATUS_RECIEVED) { + privateMarker = activity.getString(R.string.private_message); + } else { + String to; + if (message.getPresence() != null) { + to = message.getPresence(); + } else { + to = message.getCounterpart(); + } + privateMarker = activity.getString(R.string.private_message_to, to); + } + SpannableString span = new SpannableString(privateMarker+" "+message.getBody()); + span.setSpan(new ForegroundColorSpan(activity.getSecondaryTextColor()), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(span); + } } else { viewHolder.messageBody.setText(""); } @@ -245,8 +269,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(ImageProvider.getContentUri(message), - "image/*"); + intent.setDataAndType(activity.xmppConnectionService + .getFileBackend().getJingleFileUri(message), "image/*"); getContext().startActivity(intent); } }); @@ -257,7 +281,9 @@ public class MessageAdapter extends ArrayAdapter<Message> { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_STREAM, - ImageProvider.getContentUri(message)); + activity.xmppConnectionService.getFileBackend() + .getJingleFileUri(message)); + shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setType("image/webp"); getContext().startActivity( Intent.createChooser(shareIntent, @@ -277,7 +303,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { switch (type) { case SENT: view = (View) activity.getLayoutInflater().inflate( - R.layout.message_sent, null); + R.layout.message_sent, parent, false); viewHolder.message_box = (LinearLayout) view .findViewById(R.id.message_box); viewHolder.contact_picture = (ImageView) view @@ -295,7 +321,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { break; case RECIEVED: view = (View) activity.getLayoutInflater().inflate( - R.layout.message_recieved, null); + R.layout.message_recieved, parent, false); viewHolder.message_box = (LinearLayout) view .findViewById(R.id.message_box); viewHolder.contact_picture = (ImageView) view @@ -307,9 +333,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( - item.getConversation().getName(useSubject), item - .getConversation().getContact(), - getContext())); + item.getConversation().getContact(), getContext())); } viewHolder.indicator = (ImageView) view @@ -324,15 +348,13 @@ public class MessageAdapter extends ArrayAdapter<Message> { break; case STATUS: view = (View) activity.getLayoutInflater().inflate( - R.layout.message_status, null); + R.layout.message_status, parent, false); viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( - item.getConversation().getName(useSubject), item - .getConversation().getContact(), - getContext())); + item.getConversation().getContact(), getContext())); viewHolder.contact_picture.setAlpha(128); viewHolder.contact_picture .setOnClickListener(new OnClickListener() { @@ -366,8 +388,17 @@ public class MessageAdapter extends ArrayAdapter<Message> { if (type == RECIEVED) { if (item.getConversation().getMode() == Conversation.MODE_MULTI) { - viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( - item.getCounterpart(), null, getContext())); + Contact contact = item.getContact(); + if (contact != null) { + viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( + contact, getContext())); + } else { + String name = item.getPresence(); + if (name==null) { + name = item.getCounterpart(); + } + viewHolder.contact_picture.setImageBitmap(mBitmapCache.get(name, getContext())); + } viewHolder.contact_picture .setOnClickListener(new OnClickListener() { @@ -381,6 +412,18 @@ public class MessageAdapter extends ArrayAdapter<Message> { } }); + viewHolder.contact_picture.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { + MessageAdapter.this.mOnContactPictureLongClickedListener.onContactPictureLongClicked(item); + return true; + } else { + return false; + } + } + }); } } @@ -431,7 +474,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { } else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { displayDecryptionFailed(viewHolder); } else { - displayTextMessage(viewHolder, item.getBody()); + displayTextMessage(viewHolder, item); } } @@ -453,20 +496,24 @@ public class MessageAdapter extends ArrayAdapter<Message> { } private class BitmapCache { - private HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>(); + private HashMap<String, Bitmap> contactBitmaps = new HashMap<String, Bitmap>(); + private HashMap<String, Bitmap> unknownBitmaps = new HashMap<String, Bitmap>(); + + public Bitmap get(Contact contact, Context context) { + if (!contactBitmaps.containsKey(contact.getJid())) { + contactBitmaps.put(contact.getJid(), + contact.getImage(48, context)); + } + return contactBitmaps.get(contact.getJid()); + } - public Bitmap get(String name, Contact contact, Context context) { - if (bitmaps.containsKey(name)) { - return bitmaps.get(name); + public Bitmap get(String name, Context context) { + if (unknownBitmaps.containsKey(name)) { + return unknownBitmaps.get(name); } else { - Bitmap bm; - if (contact != null) { - bm = UIHelper - .getContactPicture(contact, 48, context, false); - } else { - bm = UIHelper.getContactPicture(name, 48, context, false); - } - bitmaps.put(name, bm); + Bitmap bm = UIHelper + .getContactPicture(name, 48, context, false); + unknownBitmaps.put(name, bm); return bm; } } @@ -475,4 +522,8 @@ public class MessageAdapter extends ArrayAdapter<Message> { public interface OnContactPictureClicked { public void onContactPictureClicked(Message message); } + + public interface OnContactPictureLongClicked { + public void onContactPictureLongClicked(Message message); + } } |