diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index dd1720268..3866e81c5 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -1,16 +1,16 @@ package eu.siacs.conversations.ui; -import android.databinding.DataBindingUtil; -import android.support.v7.app.AlertDialog; import android.app.PendingIntent; import android.content.Context; import android.content.IntentSender.SendIntentException; import android.content.res.Resources; +import android.databinding.DataBindingUtil; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; +import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -43,6 +43,7 @@ import eu.siacs.conversations.entities.MucOptions.User; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.utils.UIHelper; import rocks.xmpp.addr.Jid; @@ -254,6 +255,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public boolean onOptionsItemSelected(MenuItem menuItem) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } switch (menuItem.getItemId()) { case android.R.id.home: finish(); diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 26a5f09d5..b20d33ae1 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -1,10 +1,9 @@ package eu.siacs.conversations.ui; -import android.databinding.DataBindingUtil; -import android.support.v7.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.databinding.DataBindingUtil; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; @@ -12,6 +11,7 @@ import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Intents; import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.Menu; @@ -23,7 +23,6 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.TextView; import android.widget.Toast; - import org.openintents.openpgp.util.OpenPgpUtils; import java.util.List; @@ -39,6 +38,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.utils.IrregularUnicodeDetector; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.XmppUri; @@ -50,7 +50,7 @@ import rocks.xmpp.addr.Jid; public class ContactDetailsActivity extends OmemoActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated { public static final String ACTION_VIEW_CONTACT = "view_contact"; - + ActivityContactDetailsBinding binding; private Contact contact; private DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() { @@ -98,9 +98,6 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp } } }; - - ActivityContactDetailsBinding binding; - private Jid accountJid; private Jid contactJid; private boolean showDynamicTags = false; @@ -220,6 +217,9 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp @Override public boolean onOptionsItemSelected(final MenuItem menuItem) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setNegativeButton(getString(R.string.cancel), null); switch (menuItem.getItemId()) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 3cea31a49..207f0baad 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -85,6 +85,7 @@ import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.util.ActivityResult; import eu.siacs.conversations.ui.util.AttachmentTool; import eu.siacs.conversations.ui.util.ConversationMenuConfigurator; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.ui.util.PresenceSelector; import eu.siacs.conversations.ui.util.ScrollState; @@ -1105,7 +1106,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke @Override public boolean onOptionsItemSelected(final MenuItem item) { - if (conversation == null) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } else if (conversation == null) { return super.onOptionsItemSelected(item); } switch (item.getItemId()) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java index 804ca9b4a..9c6e4790c 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java @@ -71,6 +71,7 @@ import eu.siacs.conversations.ui.interfaces.OnConversationSelected; import eu.siacs.conversations.ui.interfaces.OnConversationsListItemUpdated; import eu.siacs.conversations.ui.service.EmojiService; import eu.siacs.conversations.ui.util.ActivityResult; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; @@ -284,11 +285,11 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio } @Override - public void onRequestPermissionsResult(int requestCode,@NonNull String permissions[], @NonNull int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults); if (grantResults.length > 0) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - switch(requestCode) { + switch (requestCode) { case REQUEST_OPEN_MESSAGE: refreshUiReal(); ConversationFragment.openPendingMessage(this); @@ -338,7 +339,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio private void handlePositiveActivityResult(int requestCode, final Intent data) { Conversation conversation = ConversationFragment.getConversationReliable(this); if (conversation == null) { - Log.d(Config.LOGTAG,"conversation not found"); + Log.d(Config.LOGTAG, "conversation not found"); return; } switch (requestCode) { @@ -404,7 +405,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio @Override public void onConversationSelected(Conversation conversation) { if (ConversationFragment.getConversation(this) == conversation) { - Log.d(Config.LOGTAG,"ignore onConversationSelected() because conversation is already open"); + Log.d(Config.LOGTAG, "ignore onConversationSelected() because conversation is already open"); return; } openConversation(conversation, null); @@ -438,6 +439,9 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio @Override public boolean onOptionsItemSelected(MenuItem item) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } switch (item.getItemId()) { case android.R.id.home: FragmentManager fm = getFragmentManager(); @@ -583,8 +587,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio @Override public void switchToConversation(Conversation conversation) { - Log.d(Config.LOGTAG,"override"); - openConversation(conversation,null); + Log.d(Config.LOGTAG, "override"); + openConversation(conversation, null); } @Override @@ -592,7 +596,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio if (!mActivityPaused && pendingViewIntent.peek() == null) { xmppConnectionService.sendReadMarker(conversation); } else { - Log.d(Config.LOGTAG,"ignoring read callback. mActivityPaused="+Boolean.toString(mActivityPaused)); + Log.d(Config.LOGTAG, "ignoring read callback. mActivityPaused=" + Boolean.toString(mActivityPaused)); } } diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 853d23669..68e24f1fe 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -65,6 +65,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.PresenceTemplateAdapter; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.ui.widget.DisabledActionModeCallback; import eu.siacs.conversations.utils.CryptoHelper; @@ -764,6 +765,9 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat @Override public boolean onOptionsItemSelected(final MenuItem item) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } switch (item.getItemId()) { case R.id.action_show_block_list: final Intent showBlocklistIntent = new Intent(this, BlocklistActivity.class); diff --git a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java index 66c693e0c..9e28753a0 100644 --- a/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -1,12 +1,12 @@ package eu.siacs.conversations.ui; -import android.support.v7.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Bundle; import android.security.KeyChain; import android.security.KeyChainAliasCallback; import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; import android.util.Pair; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -19,6 +19,8 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.Toast; +import org.openintents.openpgp.util.OpenPgpApi; + import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,11 +31,10 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.ui.adapter.AccountAdapter; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.xmpp.XmppConnection; import rocks.xmpp.addr.Jid; -import org.openintents.openpgp.util.OpenPgpApi; - public class ManageAccountActivity extends XmppActivity implements OnAccountUpdate, KeyChainAliasCallback, XmppConnectionService.OnAccountCreated { private final String STATE_SELECTED_ACCOUNT = "selected_account"; @@ -199,6 +200,9 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda @Override public boolean onOptionsItemSelected(MenuItem item) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } switch (item.getItemId()) { case R.id.action_add_account: startActivity(new Intent(getApplicationContext(), diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 987f24884..d2e6600dc 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -83,6 +83,7 @@ import eu.siacs.conversations.ui.adapter.ListItemAdapter; import eu.siacs.conversations.ui.interfaces.OnBackendConnected; import eu.siacs.conversations.ui.service.EmojiService; import eu.siacs.conversations.ui.util.DelayedHintHelper; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; @@ -544,6 +545,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU @Override public boolean onOptionsItemSelected(MenuItem item) { + if (MenuDoubleTabUtil.shouldIgnoreTap()) { + return false; + } switch (item.getItemId()) { case R.id.action_join_conference: showJoinConferenceDialog(null); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 10a278574..5093eefcb 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -38,9 +38,11 @@ import android.os.SystemClock; import android.preference.PreferenceManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; +import android.support.v7.app.AppCompatDelegate; import android.text.InputType; import android.util.DisplayMetrics; import android.util.Log; +import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; @@ -66,6 +68,7 @@ import eu.siacs.conversations.services.AvatarService; import eu.siacs.conversations.services.BarcodeProvider; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; +import eu.siacs.conversations.ui.util.MenuDoubleTabUtil; import eu.siacs.conversations.ui.util.PresenceSelector; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; @@ -856,6 +859,14 @@ public abstract class XmppActivity extends AppCompatActivity { super.onPause(); } + @Override + public boolean onMenuOpened(int id, Menu menu) { + if(id == AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR && menu != null) { + MenuDoubleTabUtil.recordMenuOpen(); + } + return super.onMenuOpened(id, menu); + } + protected void showQrCode() { showQrCode(getShareableUri()); } diff --git a/src/main/java/eu/siacs/conversations/ui/util/MenuDoubleTabUtil.java b/src/main/java/eu/siacs/conversations/ui/util/MenuDoubleTabUtil.java new file mode 100644 index 000000000..bb85d88ab --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/util/MenuDoubleTabUtil.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, Daniel Gultsch All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package eu.siacs.conversations.ui.util; + +import android.os.SystemClock; +import android.util.Log; + +import eu.siacs.conversations.Config; + +public class MenuDoubleTabUtil { + + private static final int TIMEOUT = 250; + + private static long lastMenuOpenedTimestamp = 0L; + + public static void recordMenuOpen() { + lastMenuOpenedTimestamp = SystemClock.elapsedRealtime(); + } + + public static boolean shouldIgnoreTap() { + boolean ignoreTab = lastMenuOpenedTimestamp + 250 > SystemClock.elapsedRealtime(); + if (ignoreTab) { + Log.d(Config.LOGTAG,"ignoring tab"); + } + return ignoreTab; + } +}