aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/ui/ConversationActivity.java')
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java765
1 files changed, 540 insertions, 225 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index f6c90274..1f163b82 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -10,14 +10,21 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
+import android.provider.Settings;
import android.support.v4.widget.SlidingPaneLayout;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Gravity;
+import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.Surface;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
@@ -33,17 +40,24 @@ import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.ui.dialogs.UserDecisionDialog;
import de.thedevstack.conversationsplus.ui.listeners.ResizePictureUserDecisionListener;
import de.timroes.android.listview.EnhancedListView;
+import org.openintents.openpgp.util.OpenPgpApi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import de.timroes.android.listview.EnhancedListView;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.crypto.axolotl.AxolotlService;
+import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Blockable;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.entities.Transferable;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
@@ -52,6 +66,8 @@ import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
import eu.siacs.conversations.utils.ExceptionHelper;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
+import eu.siacs.conversations.xmpp.jid.InvalidJidException;
+import eu.siacs.conversations.xmpp.jid.Jid;
public class ConversationActivity extends XmppActivity
implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast {
@@ -63,15 +79,20 @@ public class ConversationActivity extends XmppActivity
public static final String MESSAGE = "messageUuid";
public static final String TEXT = "text";
public static final String NICK = "nick";
+ public static final String PRIVATE_MESSAGE = "pm";
public static final int REQUEST_SEND_MESSAGE = 0x0201;
public static final int REQUEST_DECRYPT_PGP = 0x0202;
public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207;
+ public static final int REQUEST_TRUST_KEYS_TEXT = 0x0208;
+ public static final int REQUEST_TRUST_KEYS_MENU = 0x0209;
+ public static final int REQUEST_START_DOWNLOAD = 0x0210;
public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301;
public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303;
public static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304;
public static final int ATTACHMENT_CHOICE_LOCATION = 0x0305;
+ public static final int ATTACHMENT_CHOICE_INVALID = 0x0306;
private static final String STATE_OPEN_CONVERSATION = "state_open_conversation";
private static final String STATE_PANEL_OPEN = "state_panel_open";
private static final String STATE_PENDING_URI = "state_pending_uri";
@@ -81,6 +102,10 @@ public class ConversationActivity extends XmppActivity
final private List<Uri> mPendingImageUris = new ArrayList<>();
final private List<Uri> mPendingFileUris = new ArrayList<>();
private Uri mPendingGeoUri = null;
+ private boolean forbidProcessingPendings = false;
+ private Message mPendingDownloadableMessage = null;
+
+ private boolean conversationWasSelectedByKeyboard = false;
private View mContentView;
@@ -92,10 +117,9 @@ public class ConversationActivity extends XmppActivity
private ArrayAdapter<Conversation> listAdapter;
- private Toast prepareFileToast;
-
private boolean mActivityPaused = false;
- private boolean mRedirected = true;
+ private AtomicBoolean mRedirected = new AtomicBoolean(false);
+ private Pair<Integer, Intent> mPostponedActivityResult;
public Conversation getSelectedConversation() {
return this.mSelectedConversation;
@@ -131,8 +155,7 @@ public class ConversationActivity extends XmppActivity
public boolean isConversationsOverviewHideable() {
if (mContentView instanceof SlidingPaneLayout) {
- SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
- return mSlidingPaneLayout.isSlideable();
+ return true;
} else {
return false;
}
@@ -180,10 +203,11 @@ public class ConversationActivity extends XmppActivity
@Override
public void onItemClick(AdapterView<?> arg0, View clickedView,
- int position, long arg3) {
+ int position, long arg3) {
if (getSelectedConversation() != conversationList.get(position)) {
setSelectedConversation(conversationList.get(position));
ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
+ conversationWasSelectedByKeyboard = false;
}
hideConversationsOverview();
openConversation();
@@ -192,64 +216,67 @@ public class ConversationActivity extends XmppActivity
listView.setDismissCallback(new EnhancedListView.OnDismissCallback() {
- @Override
- public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) {
-
- final int index = listView.getFirstVisiblePosition();
- View v = listView.getChildAt(0);
- final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
-
- swipedConversation = listAdapter.getItem(position);
- listAdapter.remove(swipedConversation);
- swipedConversation.markRead();
- xmppConnectionService.getNotificationService().clear(swipedConversation);
-
- final boolean formerlySelected = (getSelectedConversation() == swipedConversation);
- if (position == 0 && listAdapter.getCount() == 0) {
- endConversation(swipedConversation, false, true);
- return null;
- } else if (formerlySelected) {
- setSelectedConversation(listAdapter.getItem(0));
- ConversationActivity.this.mConversationFragment
- .reInit(getSelectedConversation());
- }
-
- return new EnhancedListView.Undoable() {
-
- @Override
- public void undo() {
- listAdapter.insert(swipedConversation, position);
- if (formerlySelected) {
- setSelectedConversation(swipedConversation);
- ConversationActivity.this.mConversationFragment
- .reInit(getSelectedConversation());
- }
- swipedConversation = null;
- listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top);
- }
-
- @Override
- public void discard() {
- if (!swipedConversation.isRead()
- && swipedConversation.getMode() == Conversation.MODE_SINGLE) {
- swipedConversation = null;
- return;
- }
- endConversation(swipedConversation, false, false);
- swipedConversation = null;
- }
-
- @Override
- public String getTitle() {
- if (swipedConversation.getMode() == Conversation.MODE_MULTI) {
- return getResources().getString(R.string.title_undo_swipe_out_muc);
- } else {
- return getResources().getString(R.string.title_undo_swipe_out_conversation);
- }
- }
- };
- }
- });
+ @Override
+ public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) {
+
+ final int index = listView.getFirstVisiblePosition();
+ View v = listView.getChildAt(0);
+ final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
+
+ try {
+ swipedConversation = listAdapter.getItem(position);
+ } catch (IndexOutOfBoundsException e) {
+ return null;
+ }
+ listAdapter.remove(swipedConversation);
+ xmppConnectionService.markRead(swipedConversation);
+
+ final boolean formerlySelected = (getSelectedConversation() == swipedConversation);
+ if (position == 0 && listAdapter.getCount() == 0) {
+ endConversation(swipedConversation, false, true);
+ return null;
+ } else if (formerlySelected) {
+ setSelectedConversation(listAdapter.getItem(0));
+ ConversationActivity.this.mConversationFragment
+ .reInit(getSelectedConversation());
+ }
+
+ return new EnhancedListView.Undoable() {
+
+ @Override
+ public void undo() {
+ listAdapter.insert(swipedConversation, position);
+ if (formerlySelected) {
+ setSelectedConversation(swipedConversation);
+ ConversationActivity.this.mConversationFragment
+ .reInit(getSelectedConversation());
+ }
+ swipedConversation = null;
+ listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top);
+ }
+
+ @Override
+ public void discard() {
+ if (!swipedConversation.isRead()
+ && swipedConversation.getMode() == Conversation.MODE_SINGLE) {
+ swipedConversation = null;
+ return;
+ }
+ endConversation(swipedConversation, false, false);
+ swipedConversation = null;
+ }
+
+ @Override
+ public String getTitle() {
+ if (swipedConversation.getMode() == Conversation.MODE_MULTI) {
+ return getResources().getString(R.string.title_undo_swipe_out_muc);
+ } else {
+ return getResources().getString(R.string.title_undo_swipe_out_conversation);
+ }
+ }
+ };
+ }
+ });
listView.enableSwipeToDismiss();
listView.setSwipeDirection(EnhancedListView.SwipeDirection.START);
listView.setSwipingLayout(R.id.swipeable_item);
@@ -277,7 +304,7 @@ public class ConversationActivity extends XmppActivity
hideKeyboard();
if (xmppConnectionServiceBound) {
xmppConnectionService.getNotificationService()
- .setOpenConversation(null);
+ .setOpenConversation(null);
}
closeContextMenu();
}
@@ -301,12 +328,12 @@ public class ConversationActivity extends XmppActivity
public void switchToConversation(Conversation conversation) {
setSelectedConversation(conversation);
runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
- openConversation();
- }
- });
+ @Override
+ public void run() {
+ ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
+ openConversation();
+ }
+ });
}
private void updateActionBarTitle() {
@@ -381,7 +408,7 @@ public class ConversationActivity extends XmppActivity
} else {
menuAdd.setVisible(!isConversationsOverviewHideable());
if (this.getSelectedConversation() != null) {
- if (this.getSelectedConversation().getNextEncryption(ConversationsPlusPreferences.forceEncryption()) != Message.ENCRYPTION_NONE) {
+ if (this.getSelectedConversation().getNextEncryption() != Message.ENCRYPTION_NONE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
menuSecure.setIcon(R.drawable.ic_lock_white_24dp);
} else {
@@ -390,8 +417,9 @@ public class ConversationActivity extends XmppActivity
}
if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
menuContactDetails.setVisible(false);
- menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable());
+ menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable() && getSelectedConversation().getMucOptions().participating());
menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite());
+ menuSecure.setVisible(!Config.HIDE_PGP_IN_UI && !Config.X509_VERIFICATION); //if pgp is hidden conferences have no choice of encryption
} else {
menuMucDetails.setVisible(false);
}
@@ -405,7 +433,7 @@ public class ConversationActivity extends XmppActivity
return true;
}
- private void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) {
+ protected void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) {
final Conversation conversation = getSelectedConversation();
final Account account = conversation.getAccount();
final OnPresenceSelected callback = new OnPresenceSelected() {
@@ -419,7 +447,7 @@ public class ConversationActivity extends XmppActivity
case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
intent.setAction(Intent.ACTION_GET_CONTENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true);
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
intent.setType("image/*");
chooser = true;
@@ -469,7 +497,7 @@ public class ConversationActivity extends XmppActivity
private Intent getInstallApkIntent(final String packageId) {
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse("market://details?id="+packageId));
+ intent.setData(Uri.parse("market://details?id=" + packageId));
if (intent.resolveActivity(getPackageManager()) != null) {
return intent;
} else {
@@ -479,6 +507,11 @@ public class ConversationActivity extends XmppActivity
}
public void attachFile(final int attachmentChoice) {
+ if (attachmentChoice != ATTACHMENT_CHOICE_LOCATION) {
+ if (!hasStoragePermission(attachmentChoice)) {
+ return;
+ }
+ }
switch (attachmentChoice) {
case ATTACHMENT_CHOICE_LOCATION:
ConversationsPlusPreferences.applyRecentlyUsedQuickAction("location");
@@ -494,23 +527,23 @@ public class ConversationActivity extends XmppActivity
break;
}
final Conversation conversation = getSelectedConversation();
- final int encryption = conversation.getNextEncryption(ConversationsPlusPreferences.forceEncryption());
+ final int encryption = conversation.getNextEncryption();
+ final int mode = conversation.getMode();
if (encryption == Message.ENCRYPTION_PGP) {
if (hasPgp()) {
- if (conversation.getContact().getPgpKeyId() != 0) {
+ if (mode == Conversation.MODE_SINGLE && conversation.getContact().getPgpKeyId() != 0) {
xmppConnectionService.getPgpEngine().hasKey(
conversation.getContact(),
new UiCallback<Contact>() {
@Override
- public void userInputRequried(PendingIntent pi,
- Contact contact) {
- ConversationActivity.this.runIntent(pi,attachmentChoice);
+ public void userInputRequried(PendingIntent pi, Contact contact) {
+ ConversationActivity.this.runIntent(pi, attachmentChoice);
}
@Override
public void success(Contact contact) {
- selectPresenceToAttachFile(attachmentChoice,encryption);
+ selectPresenceToAttachFile(attachmentChoice, encryption);
}
@Override
@@ -518,21 +551,31 @@ public class ConversationActivity extends XmppActivity
displayErrorDialog(error);
}
});
+ } else if (mode == Conversation.MODE_MULTI && conversation.getMucOptions().pgpKeysInUse()) {
+ if (!conversation.getMucOptions().everybodyHasKeys()) {
+ Toast warning = Toast
+ .makeText(this,
+ R.string.missing_public_keys,
+ Toast.LENGTH_LONG);
+ warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
+ warning.show();
+ }
+ selectPresenceToAttachFile(attachmentChoice, encryption);
} else {
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
- .findFragmentByTag("conversation");
+ .findFragmentByTag("conversation");
if (fragment != null) {
fragment.showNoPGPKeyDialog(false,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
- int which) {
+ int which) {
conversation
- .setNextEncryption(Message.ENCRYPTION_NONE);
+ .setNextEncryption(Message.ENCRYPTION_NONE);
xmppConnectionService.databaseBackend
- .updateConversation(conversation);
- selectPresenceToAttachFile(attachmentChoice,Message.ENCRYPTION_NONE);
+ .updateConversation(conversation);
+ selectPresenceToAttachFile(attachmentChoice, Message.ENCRYPTION_NONE);
}
});
}
@@ -541,7 +584,40 @@ public class ConversationActivity extends XmppActivity
showInstallPgpDialog();
}
} else {
- selectPresenceToAttachFile(attachmentChoice, encryption);
+ if (encryption != Message.ENCRYPTION_AXOLOTL || !trustKeysIfNeeded(REQUEST_TRUST_KEYS_MENU, attachmentChoice)) {
+ selectPresenceToAttachFile(attachmentChoice, encryption);
+ }
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
+ if (grantResults.length > 0)
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ if (requestCode == REQUEST_START_DOWNLOAD) {
+ if (this.mPendingDownloadableMessage != null) {
+ startDownloadable(this.mPendingDownloadableMessage);
+ }
+ } else {
+ attachFile(requestCode);
+ }
+ } else {
+ Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void startDownloadable(Message message) {
+ if (!hasStoragePermission(ConversationActivity.REQUEST_START_DOWNLOAD)) {
+ this.mPendingDownloadableMessage = message;
+ return;
+ }
+ Transferable transferable = message.getTransferable();
+ if (transferable != null) {
+ if (!transferable.start()) {
+ Toast.makeText(this, R.string.not_connected_try_again, Toast.LENGTH_SHORT).show();
+ }
+ } else if (message.treatAsDownloadable() != Message.Decision.NEVER) {
+ xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, true);
}
}
@@ -616,6 +692,12 @@ public class ConversationActivity extends XmppActivity
this.mConversationFragment.reInit(getSelectedConversation());
} else {
setSelectedConversation(null);
+ if (mRedirected.compareAndSet(false, true)) {
+ Intent intent = new Intent(this, StartConversationActivity.class);
+ intent.putExtra("init", true);
+ startActivity(intent);
+ finish();
+ }
}
}
}
@@ -627,23 +709,23 @@ public class ConversationActivity extends XmppActivity
View dialogView = getLayoutInflater().inflate(
R.layout.dialog_clear_history, null);
final CheckBox endConversationCheckBox = (CheckBox) dialogView
- .findViewById(R.id.end_conversation_checkbox);
+ .findViewById(R.id.end_conversation_checkbox);
builder.setView(dialogView);
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.delete_messages),
- new OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- ConversationActivity.this.xmppConnectionService.clearConversationHistory(conversation);
- if (endConversationCheckBox.isChecked()) {
- endConversation(conversation);
- } else {
- updateConversationList();
- ConversationActivity.this.mConversationFragment.updateMessages();
- }
- }
- });
+ new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ ConversationActivity.this.xmppConnectionService.clearConversationHistory(conversation);
+ if (endConversationCheckBox.isChecked()) {
+ endConversation(conversation);
+ } else {
+ updateConversationList();
+ ConversationActivity.this.mConversationFragment.updateMessages();
+ }
+ }
+ });
builder.create().show();
}
@@ -703,7 +785,7 @@ public class ConversationActivity extends XmppActivity
Intent intent = new Intent(ConversationActivity.this, VerifyOTRActivity.class);
intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT);
intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString());
- intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString());
+ intent.putExtra(EXTRA_ACCOUNT, conversation.getAccount().getJid().toBareJid().toString());
switch (menuItem.getItemId()) {
case R.id.scan_fingerprint:
intent.putExtra("mode", VerifyOTRActivity.MODE_SCAN_FINGERPRINT);
@@ -729,7 +811,7 @@ public class ConversationActivity extends XmppActivity
}
PopupMenu popup = new PopupMenu(this, menuItemView);
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
- .findFragmentByTag("conversation");
+ .findFragmentByTag("conversation");
if (fragment != null) {
popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@@ -746,16 +828,22 @@ public class ConversationActivity extends XmppActivity
break;
case R.id.encryption_choice_pgp:
if (hasPgp()) {
- if (conversation.getAccount().getKeys().has("pgp_signature")) {
+ if (conversation.getAccount().getPgpSignature() != null) {
conversation.setNextEncryption(Message.ENCRYPTION_PGP);
item.setChecked(true);
} else {
- announcePgp(conversation.getAccount(),conversation);
+ announcePgp(conversation.getAccount(), conversation);
}
} else {
showInstallPgpDialog();
}
break;
+ case R.id.encryption_choice_axolotl:
+ Log.d(Config.LOGTAG, AxolotlService.getLogprefix(conversation.getAccount())
+ + "Enabled axolotl for Contact " + conversation.getContact().getJid());
+ conversation.setNextEncryption(Message.ENCRYPTION_AXOLOTL);
+ item.setChecked(true);
+ break;
default:
conversation.setNextEncryption(Message.ENCRYPTION_NONE);
break;
@@ -763,6 +851,7 @@ public class ConversationActivity extends XmppActivity
xmppConnectionService.databaseBackend.updateConversation(conversation);
fragment.updateChatMsgHint();
invalidateOptionsMenu();
+ refreshUi();
return true;
}
});
@@ -770,15 +859,17 @@ public class ConversationActivity extends XmppActivity
MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr);
MenuItem none = popup.getMenu().findItem(R.id.encryption_choice_none);
MenuItem pgp = popup.getMenu().findItem(R.id.encryption_choice_pgp);
- boolean forceEncryption = ConversationsPlusPreferences.forceEncryption();
+ MenuItem axolotl = popup.getMenu().findItem(R.id.encryption_choice_axolotl);
+ pgp.setVisible(!Config.HIDE_PGP_IN_UI && !Config.X509_VERIFICATION);
+ none.setVisible(!Config.FORCE_E2E_ENCRYPTION);
+ otr.setVisible(!Config.X509_VERIFICATION);
if (conversation.getMode() == Conversation.MODE_MULTI) {
- otr.setEnabled(false);
- } else {
- if (forceEncryption) {
- none.setVisible(false);
- }
+ otr.setVisible(false);
+ axolotl.setVisible(false);
+ } else if (!conversation.getAccount().getAxolotlService().isContactAxolotlCapable(conversation.getContact())) {
+ axolotl.setEnabled(false);
}
- switch (conversation.getNextEncryption(forceEncryption)) {
+ switch (conversation.getNextEncryption()) {
case Message.ENCRYPTION_NONE:
none.setChecked(true);
break;
@@ -788,6 +879,9 @@ public class ConversationActivity extends XmppActivity
case Message.ENCRYPTION_PGP:
pgp.setChecked(true);
break;
+ case Message.ENCRYPTION_AXOLOTL:
+ axolotl.setChecked(true);
+ break;
default:
none.setChecked(true);
break;
@@ -799,27 +893,26 @@ public class ConversationActivity extends XmppActivity
protected void muteConversationDialog(final Conversation conversation) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.disable_notifications);
- final int[] durations = getResources().getIntArray(
- R.array.mute_options_durations);
+ final int[] durations = getResources().getIntArray(R.array.mute_options_durations);
builder.setItems(R.array.mute_options_descriptions,
- new OnClickListener() {
-
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- final long till;
- if (durations[which] == -1) {
- till = Long.MAX_VALUE;
- } else {
- till = System.currentTimeMillis() + (durations[which] * 1000);
- }
- conversation.setMutedTill(till);
- ConversationActivity.this.xmppConnectionService.databaseBackend
- .updateConversation(conversation);
- updateConversationList();
- ConversationActivity.this.mConversationFragment.updateMessages();
- invalidateOptionsMenu();
- }
- });
+ new OnClickListener() {
+
+ @Override
+ public void onClick(final DialogInterface dialog, final int which) {
+ final long till;
+ if (durations[which] == -1) {
+ till = Long.MAX_VALUE;
+ } else {
+ till = System.currentTimeMillis() + (durations[which] * 1000);
+ }
+ conversation.setMutedTill(till);
+ ConversationActivity.this.xmppConnectionService.databaseBackend
+ .updateConversation(conversation);
+ updateConversationList();
+ ConversationActivity.this.mConversationFragment.updateMessages();
+ invalidateOptionsMenu();
+ }
+ });
builder.create().show();
}
@@ -841,10 +934,119 @@ public class ConversationActivity extends XmppActivity
}
@Override
+ public boolean onKeyUp(int key, KeyEvent event) {
+ int rotation = getWindowManager().getDefaultDisplay().getRotation();
+ final int upKey;
+ final int downKey;
+ switch (rotation) {
+ case Surface.ROTATION_90:
+ upKey = KeyEvent.KEYCODE_DPAD_LEFT;
+ downKey = KeyEvent.KEYCODE_DPAD_RIGHT;
+ break;
+ case Surface.ROTATION_180:
+ upKey = KeyEvent.KEYCODE_DPAD_DOWN;
+ downKey = KeyEvent.KEYCODE_DPAD_UP;
+ break;
+ case Surface.ROTATION_270:
+ upKey = KeyEvent.KEYCODE_DPAD_RIGHT;
+ downKey = KeyEvent.KEYCODE_DPAD_LEFT;
+ break;
+ default:
+ upKey = KeyEvent.KEYCODE_DPAD_UP;
+ downKey = KeyEvent.KEYCODE_DPAD_DOWN;
+ }
+ final boolean modifier = event.isCtrlPressed() || event.isAltPressed();
+ if (modifier && key == KeyEvent.KEYCODE_TAB && isConversationsOverviewHideable()) {
+ toggleConversationsOverview();
+ return true;
+ } else if (modifier && key == downKey) {
+ if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) {
+ showConversationsOverview();
+ ;
+ }
+ return selectDownConversation();
+ } else if (modifier && key == upKey) {
+ if (isConversationsOverviewHideable() && !isConversationsOverviewVisable()) {
+ showConversationsOverview();
+ }
+ return selectUpConversation();
+ } else if (modifier && key == KeyEvent.KEYCODE_1) {
+ return openConversationByIndex(0);
+ } else if (modifier && key == KeyEvent.KEYCODE_2) {
+ return openConversationByIndex(1);
+ } else if (modifier && key == KeyEvent.KEYCODE_3) {
+ return openConversationByIndex(2);
+ } else if (modifier && key == KeyEvent.KEYCODE_4) {
+ return openConversationByIndex(3);
+ } else if (modifier && key == KeyEvent.KEYCODE_5) {
+ return openConversationByIndex(4);
+ } else if (modifier && key == KeyEvent.KEYCODE_6) {
+ return openConversationByIndex(5);
+ } else if (modifier && key == KeyEvent.KEYCODE_7) {
+ return openConversationByIndex(6);
+ } else if (modifier && key == KeyEvent.KEYCODE_8) {
+ return openConversationByIndex(7);
+ } else if (modifier && key == KeyEvent.KEYCODE_9) {
+ return openConversationByIndex(8);
+ } else if (modifier && key == KeyEvent.KEYCODE_0) {
+ return openConversationByIndex(9);
+ } else {
+ return super.onKeyUp(key, event);
+ }
+ }
+
+ private void toggleConversationsOverview() {
+ if (isConversationsOverviewVisable()) {
+ hideConversationsOverview();
+ if (mConversationFragment != null) {
+ mConversationFragment.setFocusOnInputField();
+ }
+ } else {
+ showConversationsOverview();
+ }
+ }
+
+ private boolean selectUpConversation() {
+ if (this.mSelectedConversation != null) {
+ int index = this.conversationList.indexOf(this.mSelectedConversation);
+ if (index > 0) {
+ return openConversationByIndex(index - 1);
+ }
+ }
+ return false;
+ }
+
+ private boolean selectDownConversation() {
+ if (this.mSelectedConversation != null) {
+ int index = this.conversationList.indexOf(this.mSelectedConversation);
+ if (index != -1 && index < this.conversationList.size() - 1) {
+ return openConversationByIndex(index + 1);
+ }
+ }
+ return false;
+ }
+
+ private boolean openConversationByIndex(int index) {
+ try {
+ this.conversationWasSelectedByKeyboard = true;
+ setSelectedConversation(this.conversationList.get(index));
+ this.mConversationFragment.reInit(getSelectedConversation());
+ if (index > listView.getLastVisiblePosition() - 1 || index < listView.getFirstVisiblePosition() + 1) {
+ this.listView.setSelection(index);
+ }
+ openConversation();
+ return true;
+ } catch (IndexOutOfBoundsException e) {
+ return false;
+ }
+ }
+
+ @Override
protected void onNewIntent(final Intent intent) {
if (xmppConnectionServiceBound) {
if (intent != null && VIEW_CONVERSATION.equals(intent.getType())) {
handleViewConversationIntent(intent);
+ setIntent(new Intent());
}
} else {
setIntent(intent);
@@ -854,7 +1056,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void onStart() {
super.onStart();
- this.mRedirected = false;
+ this.mRedirected.set(false);
if (this.xmppConnectionServiceBound) {
this.onBackendConnected();
}
@@ -896,17 +1098,26 @@ public class ConversationActivity extends XmppActivity
public void onSaveInstanceState(final Bundle savedInstanceState) {
Conversation conversation = getSelectedConversation();
if (conversation != null) {
- savedInstanceState.putString(STATE_OPEN_CONVERSATION,
- conversation.getUuid());
+ savedInstanceState.putString(STATE_OPEN_CONVERSATION, conversation.getUuid());
+ } else {
+ savedInstanceState.remove(STATE_OPEN_CONVERSATION);
}
- savedInstanceState.putBoolean(STATE_PANEL_OPEN,
- isConversationsOverviewVisable());
+ savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable());
if (this.mPendingImageUris.size() >= 1) {
savedInstanceState.putString(STATE_PENDING_URI, this.mPendingImageUris.get(0).toString());
+ } else {
+ savedInstanceState.remove(STATE_PENDING_URI);
}
super.onSaveInstanceState(savedInstanceState);
}
+ private void clearPending() {
+ mPendingImageUris.clear();
+ mPendingFileUris.clear();
+ mPendingGeoUri = null;
+ mPostponedActivityResult = null;
+ }
+
@Override
void onBackendConnected() {
this.xmppConnectionService.getNotificationService().setIsInForeground(true);
@@ -918,20 +1129,23 @@ public class ConversationActivity extends XmppActivity
}
if (xmppConnectionService.getAccounts().size() == 0) {
- if (!mRedirected) {
- this.mRedirected = true;
- startActivity(new Intent(this, EditAccountActivity.class));
+ if (mRedirected.compareAndSet(false, true)) {
+ if (Config.X509_VERIFICATION) {
+ startActivity(new Intent(this, ManageAccountActivity.class));
+ } else {
+ startActivity(new Intent(this, EditAccountActivity.class));
+ }
finish();
}
} else if (conversationList.size() <= 0) {
- if (!mRedirected) {
- this.mRedirected = true;
+ if (mRedirected.compareAndSet(false, true)) {
Intent intent = new Intent(this, StartConversationActivity.class);
- intent.putExtra("init",true);
+ intent.putExtra("init", true);
startActivity(intent);
finish();
}
} else if (getIntent() != null && VIEW_CONVERSATION.equals(getIntent().getType())) {
+ clearPending();
handleViewConversationIntent(getIntent());
} else if (selectConversationByUuid(mOpenConverstaion)) {
if (mPanelOpen) {
@@ -939,32 +1153,46 @@ public class ConversationActivity extends XmppActivity
} else {
if (isConversationsOverviewHideable()) {
openConversation();
+ updateActionBarTitle(true);
}
}
this.mConversationFragment.reInit(getSelectedConversation());
mOpenConverstaion = null;
} else if (getSelectedConversation() == null) {
showConversationsOverview();
- mPendingImageUris.clear();
- mPendingFileUris.clear();
- mPendingGeoUri = null;
+ clearPending();
setSelectedConversation(conversationList.get(0));
this.mConversationFragment.reInit(getSelectedConversation());
+ } else {
+ this.mConversationFragment.messageListAdapter.updatePreferences();
+ this.mConversationFragment.messagesView.invalidateViews();
+ this.mConversationFragment.setupIme();
}
- for(Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
- attachImageToConversation(getSelectedConversation(),i.next());
+ if (this.mPostponedActivityResult != null) {
+ this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
}
- for(Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
- attachFileToConversation(getSelectedConversation(),i.next());
+ if (!forbidProcessingPendings) {
+ for (Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
+ Uri foo = i.next();
+ attachImageToConversation(getSelectedConversation(), foo);
+ }
+
+ for (Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
+ attachFileToConversation(getSelectedConversation(), i.next());
+ }
+
+ if (mPendingGeoUri != null) {
+ attachLocationToConversation(getSelectedConversation(), mPendingGeoUri);
+ mPendingGeoUri = null;
+ }
}
+ forbidProcessingPendings = false;
- if (mPendingGeoUri != null) {
- attachLocationToConversation(getSelectedConversation(), mPendingGeoUri);
- mPendingGeoUri = null;
+ if (!ExceptionHelper.checkForCrash(this, this.xmppConnectionService)) {
+ openBatteryOptimizationDialogIfNeeded();
}
- ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
setIntent(new Intent());
}
@@ -973,10 +1201,21 @@ public class ConversationActivity extends XmppActivity
final String downloadUuid = intent.getStringExtra(MESSAGE);
final String text = intent.getStringExtra(TEXT);
final String nick = intent.getStringExtra(NICK);
+ final boolean pm = intent.getBooleanExtra(PRIVATE_MESSAGE, false);
if (selectConversationByUuid(uuid)) {
this.mConversationFragment.reInit(getSelectedConversation());
if (nick != null) {
- this.mConversationFragment.highlightInConference(nick);
+ if (pm) {
+ Jid jid = getSelectedConversation().getJid();
+ try {
+ Jid next = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), nick);
+ this.mConversationFragment.privateMessageWith(next);
+ } catch (final InvalidJidException ignored) {
+ //do nothing
+ }
+ } else {
+ this.mConversationFragment.highlightInConference(nick);
+ }
} else {
this.mConversationFragment.appendText(text);
}
@@ -988,7 +1227,7 @@ public class ConversationActivity extends XmppActivity
if (downloadUuid != null) {
final Message message = mSelectedConversation.findMessageWithFileAndUuid(downloadUuid);
if (message != null) {
- mConversationFragment.messageListAdapter.startDownloadable(message);
+ startDownloadable(message);
}
}
}
@@ -1016,10 +1255,13 @@ public class ConversationActivity extends XmppActivity
@SuppressLint("NewApi")
private static List<Uri> extractUriFromIntent(final Intent intent) {
List<Uri> uris = new ArrayList<>();
+ if (intent == null) {
+ return uris;
+ }
Uri uri = intent.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && uri == null) {
ClipData clipData = intent.getClipData();
- for(int i = 0; i < clipData.getItemCount(); ++i) {
+ for (int i = 0; i < clipData.getItemCount(); ++i) {
uris.add(clipData.getItemAt(i).getUri());
}
} else {
@@ -1029,26 +1271,46 @@ public class ConversationActivity extends XmppActivity
}
@Override
- protected void onActivityResult(int requestCode, int resultCode,
- final Intent data) {
+ protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_DECRYPT_PGP) {
- mConversationFragment.hideSnackbar();
- mConversationFragment.updateMessages();
+ mConversationFragment.onActivityResult(requestCode, resultCode, data);
+ } else if (requestCode == REQUEST_CHOOSE_PGP_ID) {
+ // the user chose OpenPGP for encryption and selected his key in the PGP provider
+ if (xmppConnectionServiceBound) {
+ if (data.getExtras().containsKey(OpenPgpApi.EXTRA_SIGN_KEY_ID)) {
+ // associate selected PGP keyId with the account
+ mSelectedConversation.getAccount().setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
+ // we need to announce the key as described in XEP-027
+ announcePgp(mSelectedConversation.getAccount(), null);
+ } else {
+ choosePgpSignId(mSelectedConversation.getAccount());
+ }
+ this.mPostponedActivityResult = null;
+ } else {
+ this.mPostponedActivityResult = new Pair<>(requestCode, data);
+ }
+ } else if (requestCode == REQUEST_ANNOUNCE_PGP) {
+ if (xmppConnectionServiceBound) {
+ announcePgp(mSelectedConversation.getAccount(), mSelectedConversation);
+ this.mPostponedActivityResult = null;
+ } else {
+ this.mPostponedActivityResult = new Pair<>(requestCode, data);
+ }
} else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
mPendingImageUris.clear();
mPendingImageUris.addAll(extractUriFromIntent(data));
if (xmppConnectionServiceBound) {
- for(Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
- attachImageToConversation(getSelectedConversation(),i.next());
+ for (Iterator<Uri> i = mPendingImageUris.iterator(); i.hasNext(); i.remove()) {
+ attachImageToConversation(getSelectedConversation(), i.next());
}
}
} else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_FILE || requestCode == ATTACHMENT_CHOICE_RECORD_VOICE) {
mPendingFileUris.clear();
mPendingFileUris.addAll(extractUriFromIntent(data));
if (xmppConnectionServiceBound) {
- for(Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
+ for (Iterator<Uri> i = mPendingFileUris.iterator(); i.hasNext(); i.remove()) {
attachFileToConversation(getSelectedConversation(), i.next());
}
}
@@ -1066,78 +1328,105 @@ public class ConversationActivity extends XmppActivity
mPendingImageUris.clear();
}
} else if (requestCode == ATTACHMENT_CHOICE_LOCATION) {
- double latitude = data.getDoubleExtra("latitude",0);
- double longitude = data.getDoubleExtra("longitude",0);
- this.mPendingGeoUri = Uri.parse("geo:"+String.valueOf(latitude)+","+String.valueOf(longitude));
+ double latitude = data.getDoubleExtra("latitude", 0);
+ double longitude = data.getDoubleExtra("longitude", 0);
+ this.mPendingGeoUri = Uri.parse("geo:" + String.valueOf(latitude) + "," + String.valueOf(longitude));
if (xmppConnectionServiceBound) {
attachLocationToConversation(getSelectedConversation(), mPendingGeoUri);
this.mPendingGeoUri = null;
}
+ } else if (requestCode == REQUEST_TRUST_KEYS_TEXT || requestCode == REQUEST_TRUST_KEYS_MENU) {
+ this.forbidProcessingPendings = !xmppConnectionServiceBound;
+ if (xmppConnectionServiceBound) {
+ mConversationFragment.onActivityResult(requestCode, resultCode, data);
+ this.mPostponedActivityResult = null;
+ } else {
+ this.mPostponedActivityResult = new Pair<>(requestCode, data);
+ }
+
}
} else {
- mPendingImageUris.clear();
- mPendingFileUris.clear();
+ if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
+ mPendingImageUri = null;
+ }
}
}
private void attachLocationToConversation(Conversation conversation, Uri uri) {
- if (conversation == null) {
- return;
- }
- xmppConnectionService.attachLocationToConversation(conversation, uri, new UiCallback<Message>() {
+ xmppConnectionService.attachLocationToConversation(conversation,uri, new UiCallback<Message>() {
- @Override
- public void success(Message message) {
- xmppConnectionService.sendMessage(message);
- }
+ @Override
+ public void success(Message message) {
+ xmppConnectionService.sendMessage(message);
+ }
- @Override
- public void error(int errorCode, Message object) {
+ @Override
+ public void error(int errorCode, Message object) {
- }
+ }
- @Override
- public void userInputRequried(PendingIntent pi, Message object) {
+ @Override
+ public void userInputRequried(PendingIntent pi, Message object) {
- }
- });
+ }
+ });
}
private void attachFileToConversation(Conversation conversation, Uri uri) {
if (conversation == null) {
return;
}
- prepareFileToast = Toast.makeText(getApplicationContext(),getText(R.string.preparing_file), Toast.LENGTH_LONG);
+ final Toast prepareFileToast = Toast.makeText(getApplicationContext(),getText(R.string.preparing_file), Toast.LENGTH_LONG);
prepareFileToast.show();
xmppConnectionService.attachFileToConversation(conversation, uri, new UiCallback<Message>() {
- @Override
- public void success(Message message) {
- hidePrepareFileToast();
- xmppConnectionService.sendMessage(message);
- }
+ @Override
+ public void success(Message message) {
+ hidePrepareFileToast(prepareFileToast);
+ xmppConnectionService.sendMessage(message);
+ }
- @Override
- public void error(int errorCode, Message message) {
- displayErrorDialog(errorCode);
- }
+ @Override
+ public void error(int errorCode, Message message) {
+ hidePrepareFileToast(prepareFileToast);
+ displayErrorDialog(errorCode);
+ }
- @Override
- public void userInputRequried(PendingIntent pi, Message message) {
+ @Override
+ public void userInputRequried(PendingIntent pi, Message message) {
- }
- });
+ }
+ });
}
private void attachImageToConversation(Conversation conversation, Uri uri) {
if (conversation == null) {
return;
}
- ResizePictureUserDecisionListener userDecisionListener = new ResizePictureUserDecisionListener(this, conversation, uri, xmppConnectionService);
- UserDecisionDialog userDecisionDialog = new UserDecisionDialog(this, R.string.userdecision_question_resize_picture, userDecisionListener);
- userDecisionDialog.decide(ConversationsPlusPreferences.resizePicture());
+ final Toast prepareFileToast = Toast.makeText(getApplicationContext(),getText(R.string.preparing_image), Toast.LENGTH_LONG);
+ prepareFileToast.show();
+ xmppConnectionService.attachImageToConversation(conversation, uri,
+ new UiCallback<Message>() {
+
+ @Override
+ public void userInputRequried(PendingIntent pi, Message object) {
+ hidePrepareFileToast(prepareFileToast);
+ }
+
+ @Override
+ public void success(Message message) {
+ hidePrepareFileToast(prepareFileToast);
+ xmppConnectionService.sendMessage(message);
+ }
+
+ @Override
+ public void error(int error, Message message) {
+ hidePrepareFileToast(prepareFileToast);
+ displayErrorDialog(error);
+ }
+ });
}
- private void hidePrepareFileToast() {
+ private void hidePrepareFileToast(final Toast prepareFileToast) {
if (prepareFileToast != null) {
runOnUiThread(new Runnable() {
@@ -1176,7 +1465,7 @@ public class ConversationActivity extends XmppActivity
@Override
public void userInputRequried(PendingIntent pi,
- Message message) {
+ Message message) {
ConversationActivity.this.runIntent(pi,
ConversationActivity.REQUEST_SEND_MESSAGE);
}
@@ -1194,26 +1483,50 @@ public class ConversationActivity extends XmppActivity
});
}
+ public boolean useSendButtonToIndicateStatus() {
+ return getPreferences().getBoolean("send_button_status", false);
+ }
+
+ public boolean indicateReceived() {
+ return getPreferences().getBoolean("indicate_received", false);
+ }
+
+ public boolean useWhiteBackground() {
+ return getPreferences().getBoolean("use_white_background",false);
+ }
+
+ protected boolean trustKeysIfNeeded(int requestCode) {
+ return trustKeysIfNeeded(requestCode, ATTACHMENT_CHOICE_INVALID);
+ }
+
+ protected boolean trustKeysIfNeeded(int requestCode, int attachmentChoice) {
+ AxolotlService axolotlService = mSelectedConversation.getAccount().getAxolotlService();
+ Contact contact = mSelectedConversation.getContact();
+ boolean hasUndecidedOwn = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED).isEmpty();
+ boolean hasUndecidedContact = !axolotlService.getKeysWithTrust(XmppAxolotlSession.Trust.UNDECIDED,contact).isEmpty();
+ boolean hasPendingKeys = !axolotlService.findDevicesWithoutSession(mSelectedConversation).isEmpty();
+ boolean hasNoTrustedKeys = axolotlService.getNumTrustedKeys(mSelectedConversation.getContact()) == 0;
+ if(hasUndecidedOwn || hasUndecidedContact || hasPendingKeys || hasNoTrustedKeys) {
+ axolotlService.createSessionsIfNeeded(mSelectedConversation);
+ Intent intent = new Intent(getApplicationContext(), TrustKeysActivity.class);
+ intent.putExtra("contact", mSelectedConversation.getContact().getJid().toBareJid().toString());
+ intent.putExtra(EXTRA_ACCOUNT, mSelectedConversation.getAccount().getJid().toBareJid().toString());
+ intent.putExtra("choice", attachmentChoice);
+ intent.putExtra("has_no_trusted", hasNoTrustedKeys);
+ startActivityForResult(intent, requestCode);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
@Override
protected void refreshUiReal() {
updateConversationList();
- if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 0) {
- if (!mRedirected) {
- this.mRedirected = true;
- startActivity(new Intent(this, EditAccountActivity.class));
- finish();
- }
- } else if (conversationList.size() == 0) {
- if (!mRedirected) {
- this.mRedirected = true;
- Intent intent = new Intent(this, StartConversationActivity.class);
- intent.putExtra("init",true);
- startActivity(intent);
- finish();
- }
- } else {
+ if (conversationList.size() > 0) {
ConversationActivity.this.mConversationFragment.updateMessages();
updateActionBarTitle();
+ invalidateOptionsMenu();
}
}
@@ -1235,18 +1548,16 @@ public class ConversationActivity extends XmppActivity
@Override
public void OnUpdateBlocklist(Status status) {
this.refreshUi();
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- invalidateOptionsMenu();
- }
- });
}
public void unblockConversation(final Blockable conversation) {
xmppConnectionService.sendUnblockRequest(conversation);
}
+ public boolean enterIsSend() {
+ return getPreferences().getBoolean("enter_is_send",false);
+ }
+
@Override
public void onShowErrorToast(final int resId) {
runOnUiThread(new Runnable() {
@@ -1256,4 +1567,8 @@ public class ConversationActivity extends XmppActivity
}
});
}
+
+ public boolean highlightSelectedConversations() {
+ return !isConversationsOverviewHideable() || this.conversationWasSelectedByKeyboard;
+ }
}