diff options
author | Adithya Abraham Philip <adithyaphilip@gmail.com> | 2015-02-28 14:29:20 +0530 |
---|---|---|
committer | Adithya Abraham Philip <adithyaphilip@gmail.com> | 2015-02-28 14:29:20 +0530 |
commit | 94114e35c2af9e264bfa6b3d458f6ceae77ab4f9 (patch) | |
tree | 5ff39778fa22dde56057a2f15fcad7aa63b330fb /OpenKeychain/src/main/java | |
parent | 23cbd786eae8720769e775e4f8785da47115110f (diff) | |
parent | 2ae4d6ce05e6ca1585239b779b1dd6f39f58050a (diff) | |
download | open-keychain-94114e35c2af9e264bfa6b3d458f6ceae77ab4f9.tar.gz open-keychain-94114e35c2af9e264bfa6b3d458f6ceae77ab4f9.tar.bz2 open-keychain-94114e35c2af9e264bfa6b3d458f6ceae77ab4f9.zip |
Merge branch 'development' of https://github.com/open-keychain/open-keychain into development
Diffstat (limited to 'OpenKeychain/src/main/java')
15 files changed, 375 insertions, 380 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java index ceb0a2d2b..635fe86f1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java @@ -78,6 +78,10 @@ public class KeychainIntentServiceHandler extends Handler { } public void showProgressDialog(FragmentActivity activity) { + if (mProgressDialogFragment == null) { + return; + } + // TODO: This is a hack!, see // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult final FragmentManager manager = activity.getSupportFragmentManager(); @@ -94,7 +98,8 @@ public class KeychainIntentServiceHandler extends Handler { Bundle data = message.getData(); if (mProgressDialogFragment == null) { - Log.e(Constants.TAG, "Progress has not been updated because mProgressDialogFragment was null!"); + // Log.e(Constants.TAG, + // "Progress has not been updated because mProgressDialogFragment was null!"); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java index 777288e69..b7c80c1ed 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java @@ -17,14 +17,12 @@ package org.sufficientlysecure.keychain.ui; -import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.util.Log; public class CertifyFingerprintActivity extends BaseActivity { @@ -79,14 +77,4 @@ public class CertifyFingerprintActivity extends BaseActivity { getSupportFragmentManager().executePendingTransactions(); } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - // if a result has been returned, display a notify - if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) { - OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); - result.createNotify(this).show(); - } else { - super.onActivityResult(requestCode, resultCode, data); - } - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java index aef705ee9..a6b8a0e85 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java @@ -41,6 +41,8 @@ import org.sufficientlysecure.keychain.util.Log; public class CertifyFingerprintFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks<Cursor> { + static final int REQUEST_CERTIFY = 1; + public static final String ARG_DATA_URI = "uri"; private TextView mFingerprint; @@ -177,8 +179,20 @@ public class CertifyFingerprintFragment extends LoaderFragment implements Log.e(Constants.TAG, "key not found!", e); } Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class); + certifyIntent.putExtras(getActivity().getIntent()); certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId}); - startActivityForResult(certifyIntent, 0); + startActivityForResult(certifyIntent, REQUEST_CERTIFY); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + // always just pass this one through + if (requestCode == REQUEST_CERTIFY) { + getActivity().setResult(resultCode, data); + getActivity().finish(); + return; + } + super.onActivityResult(requestCode, resultCode, data); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 50d5e3229..e1467ec61 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.os.Parcel; +import android.os.Parcelable; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -94,6 +95,7 @@ public class CertifyKeyFragment extends LoaderFragment private static final int INDEX_IS_REVOKED = 4; private MultiUserIdsAdapter mUserIdsAdapter; + private Messenger mPassthroughMessenger; @Override public void onActivityCreated(Bundle savedInstanceState) { @@ -109,6 +111,9 @@ public class CertifyKeyFragment extends LoaderFragment return; } + mPassthroughMessenger = getActivity().getIntent().getParcelableExtra( + KeychainIntentService.EXTRA_MESSENGER); + // preselect certify key id if given long certifyKeyId = getActivity().getIntent().getLongExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, Constants.key.none); if (certifyKeyId != Constants.key.none) { @@ -332,7 +337,6 @@ public class CertifyKeyFragment extends LoaderFragment } } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { @@ -362,51 +366,63 @@ public class CertifyKeyFragment extends LoaderFragment return; } + Bundle data = new Bundle(); + { + // fill values for this action + CertifyActionsParcel parcel = new CertifyActionsParcel(mSignMasterKeyId); + parcel.mCertifyActions.addAll(certifyActions); + + data.putParcelable(KeychainIntentService.CERTIFY_PARCEL, parcel); + if (mUploadKeyCheckbox.isChecked()) { + String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); + data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver); + } + } + // Send all information needed to service to sign key in other thread Intent intent = new Intent(getActivity(), KeychainIntentService.class); - intent.setAction(KeychainIntentService.ACTION_CERTIFY_KEYRING); - - // fill values for this action - CertifyActionsParcel parcel = new CertifyActionsParcel(mSignMasterKeyId); - parcel.mCertifyActions.addAll(certifyActions); - - Bundle data = new Bundle(); - data.putParcelable(KeychainIntentService.CERTIFY_PARCEL, parcel); - if (mUploadKeyCheckbox.isChecked()) { - String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); - data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver); - } intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after signing is done in KeychainIntentService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), - getString(R.string.progress_certifying), ProgressDialog.STYLE_SPINNER, true) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - Bundle data = message.getData(); - CertifyResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); - - Intent intent = new Intent(); - intent.putExtra(CertifyResult.EXTRA_RESULT, result); - getActivity().setResult(Activity.RESULT_OK, intent); - getActivity().finish(); + if (mPassthroughMessenger != null) { + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, mPassthroughMessenger); + } else { + + // Message is received after signing is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_certifying), ProgressDialog.STYLE_SPINNER, true) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + Bundle data = message.getData(); + CertifyResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); + + Intent intent = new Intent(); + intent.putExtra(CertifyResult.EXTRA_RESULT, result); + getActivity().setResult(Activity.RESULT_OK, intent); + getActivity().finish(); + } } - } - }; + }; - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - // show progress dialog - saveHandler.showProgressDialog(getActivity()); + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + } // start service with intent getActivity().startService(intent); + + if (mPassthroughMessenger != null) { + getActivity().setResult(Activity.RESULT_OK); + getActivity().finish(); + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 99714b4a0..496048582 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; +import android.animation.ObjectAnimator; import android.annotation.TargetApi; import android.app.ProgressDialog; import android.content.Context; @@ -36,16 +37,12 @@ import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.CursorAdapter; -import android.support.v4.widget.NoScrollableSwipeRefreshLayout; -import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -57,6 +54,7 @@ import android.widget.ListView; import android.widget.TextView; import com.getbase.floatingactionbutton.FloatingActionButton; +import com.getbase.floatingactionbutton.FloatingActionsMenu; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -73,8 +71,8 @@ import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.util.Highlighter; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.ui.widget.ListAwareSwipeRefreshLayout; import org.sufficientlysecure.keychain.util.ExportHelper; +import org.sufficientlysecure.keychain.util.FabContainer; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; @@ -91,25 +89,19 @@ import se.emilsjolander.stickylistheaders.StickyListHeadersListView; */ public class KeyListFragment extends LoaderFragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener, - LoaderManager.LoaderCallbacks<Cursor> { + LoaderManager.LoaderCallbacks<Cursor>, FabContainer { ExportHelper mExportHelper; private KeyListAdapter mAdapter; private StickyListHeadersListView mStickyList; - private ListAwareSwipeRefreshLayout mSwipeRefreshLayout; // saves the mode object for multiselect, needed for reset at some point private ActionMode mActionMode = null; - private boolean mShowAllKeys = true; - private String mQuery; - private SearchView mSearchView; - private FloatingActionButton mFabQrCode; - private FloatingActionButton mFabCloud; - private FloatingActionButton mFabFile; + private FloatingActionsMenu mFab; @Override public void onCreate(Bundle savedInstanceState) { @@ -129,96 +121,38 @@ public class KeyListFragment extends LoaderFragment mStickyList = (StickyListHeadersListView) view.findViewById(R.id.key_list_list); mStickyList.setOnItemClickListener(this); - mFabQrCode = (FloatingActionButton) view.findViewById(R.id.fab_add_qr_code); - mFabCloud = (FloatingActionButton) view.findViewById(R.id.fab_add_cloud); - mFabFile = (FloatingActionButton) view.findViewById(R.id.fab_add_file); + mFab = (FloatingActionsMenu) view.findViewById(R.id.fab_main); + + FloatingActionButton fabQrCode = (FloatingActionButton) view.findViewById(R.id.fab_add_qr_code); + FloatingActionButton fabCloud = (FloatingActionButton) view.findViewById(R.id.fab_add_cloud); + FloatingActionButton fabFile = (FloatingActionButton) view.findViewById(R.id.fab_add_file); - mFabQrCode.setOnClickListener(new OnClickListener() { + fabQrCode.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { + mFab.collapse(); scanQrCode(); } }); - mFabCloud.setOnClickListener(new OnClickListener() { + fabCloud.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { + mFab.collapse(); searchCloud(); } }); - mFabFile.setOnClickListener(new OnClickListener() { + fabFile.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { + mFab.collapse(); importFile(); } }); - mSwipeRefreshLayout = (ListAwareSwipeRefreshLayout) view.findViewById(R.id.key_list_swipe_container); - mSwipeRefreshLayout.setOnRefreshListener(new NoScrollableSwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - KeychainIntentServiceHandler finishedHandler = new KeychainIntentServiceHandler(getActivity()) { - public void handleMessage(Message message) { - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - mSwipeRefreshLayout.setRefreshing(false); - } - } - }; - // new KeyUpdateHelper().updateAllKeys(getActivity(), finishedHandler); - updateActionbarForSwipe(false); - } - }); - mSwipeRefreshLayout.setColorScheme( - R.color.android_purple_dark, - R.color.android_purple_light, - R.color.android_purple_dark, - R.color.android_purple_light); - mSwipeRefreshLayout.setStickyListHeadersListView(mStickyList); - mSwipeRefreshLayout.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_MOVE) { - updateActionbarForSwipe(true); - } else { - updateActionbarForSwipe(false); - } - return false; - } - }); - // Just disable for now - mSwipeRefreshLayout.setIsLocked(true); return root; } - private void updateActionbarForSwipe(boolean show) { - ActionBarActivity activity = (ActionBarActivity) getActivity(); - ActionBar bar = activity.getSupportActionBar(); - - if (show) { - bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); - bar.setDisplayUseLogoEnabled(false); - bar.setCustomView(R.layout.custom_actionbar); - TextView title = (TextView) getActivity().findViewById(R.id.custom_actionbar_text); - title.setText(R.string.swipe_to_update); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { -// hideMenu = true; -// activity.invalidateOptionsMenu(); - } - } else { - bar.setTitle(getActivity().getTitle()); - bar.setDisplayHomeAsUpEnabled(true); - bar.setDisplayShowTitleEnabled(true); - bar.setDisplayUseLogoEnabled(true); - bar.setDisplayShowHomeEnabled(true); - bar.setDisplayShowCustomEnabled(false); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { -// hideMenu = false; -// activity.invalidateOptionsMenu(); - } - } - } - /** * Define Adapter and Loader on create of Activity */ @@ -275,7 +209,7 @@ public class KeyListFragment extends LoaderFragment } case R.id.menu_key_list_multi_export: { ids = mAdapter.getCurrentSelectedMasterKeyIds(); - ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); + ExportHelper mExportHelper = new ExportHelper(getActivity()); mExportHelper.showExportKeysDialog(ids, Constants.Path.APP_DIR_FILE, mAdapter.isAnySecretSelected()); break; @@ -301,7 +235,7 @@ public class KeyListFragment extends LoaderFragment public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { if (checked) { - mAdapter.setNewSelection(position, checked); + mAdapter.setNewSelection(position, true); } else { mAdapter.removeSelection(position); } @@ -370,14 +304,6 @@ public class KeyListFragment extends LoaderFragment whereArgs[i] = "%" + words[i] + "%"; } } - if (!mShowAllKeys) { - if (where == null) { - where = ""; - } else { - where += " AND "; - } - where += KeyRings.VERIFIED + " != 0"; - } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. @@ -441,7 +367,6 @@ public class KeyListFragment extends LoaderFragment /** * Show dialog to delete key * - * @param masterKeyIds * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not */ public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) { @@ -493,10 +418,10 @@ public class KeyListFragment extends LoaderFragment // Get the searchview MenuItem searchItem = menu.findItem(R.id.menu_key_list_search); - mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem); + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); // Execute this when searching - mSearchView.setOnQueryTextListener(this); + searchView.setOnQueryTextListener(this); // Erase search result without focus MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { @@ -594,7 +519,6 @@ public class KeyListFragment extends LoaderFragment return true; } - private void searchCloud() { Intent importIntent = new Intent(getActivity(), ImportKeysActivity.class); importIntent.putExtra(ImportKeysActivity.EXTRA_QUERY, (String) null); // hack to show only cloud tab @@ -677,6 +601,23 @@ public class KeyListFragment extends LoaderFragment } } + @Override + public void fabMoveUp(int height) { + ObjectAnimator anim = ObjectAnimator.ofFloat(mFab, "translationY", 0, -height); + // we're a little behind, so skip 1/10 of the time + anim.setDuration(270); + anim.start(); + } + + @Override + public void fabRestorePosition() { + ObjectAnimator anim = ObjectAnimator.ofFloat(mFab, "translationY", 0); + // we're a little ahead, so wait a few ms + anim.setStartDelay(70); + anim.setDuration(300); + anim.start(); + } + /** * Implements StickyListHeadersAdapter from library */ diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index 2f29f9360..b6b2fcb8a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -23,13 +23,33 @@ import android.os.Bundle; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.remote.ui.AppsListFragment; import org.sufficientlysecure.keychain.util.Preferences; +import org.sufficientlysecure.keychain.util.FabContainer; -public class MainActivity extends NavDrawerActivity { +import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer; + +public class MainActivity extends MaterialNavigationDrawer implements FabContainer { @Override public void init(Bundle savedInstanceState) { - super.init(savedInstanceState); + // don't open drawer on first run + disableLearningPattern(); + +// addMultiPaneSupport(); + + // set the header image + // create and set the header + setDrawerHeaderImage(R.drawable.drawer_header); + + // create sections + addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment())); + addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment())); + addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment())); + + // create bottom section + addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class))); + addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class))); // if this is the first time show first time activity Preferences prefs = Preferences.getPreferences(this); @@ -47,4 +67,20 @@ public class MainActivity extends NavDrawerActivity { } } + @Override + public void fabMoveUp(int height) { + Object fragment = getCurrentSection().getTargetFragment(); + if (fragment instanceof FabContainer) { + ((FabContainer) fragment).fabMoveUp(height); + } + } + + @Override + public void fabRestorePosition() { + Object fragment = getCurrentSection().getTargetFragment(); + if (fragment instanceof FabContainer) { + ((FabContainer) fragment).fabRestorePosition(); + } + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java deleted file mode 100644 index fb23c7d3a..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NavDrawerActivity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package org.sufficientlysecure.keychain.ui; - -import android.content.Intent; -import android.os.Bundle; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.remote.ui.AppsListFragment; - -import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer; - -public abstract class NavDrawerActivity extends MaterialNavigationDrawer { - - @Override - public void init(Bundle savedInstanceState) { - // don't open drawer on first run - disableLearningPattern(); - -// addMultiPaneSupport(); - - // set the header image - // create and set the header - setDrawerHeaderImage(R.drawable.drawer_header); - - // create sections - addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment())); - addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment())); - addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment())); - - // create bottom section - addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class))); - addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class))); - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index afb742079..f7d402c0b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -18,7 +18,10 @@ package org.sufficientlysecure.keychain.ui; +import android.animation.ArgbEvaluator; +import android.animation.ObjectAnimator; import android.annotation.TargetApi; +import android.app.Activity; import android.app.ActivityOptions; import android.content.Intent; import android.database.Cursor; @@ -33,6 +36,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.os.Messenger; import android.provider.ContactsContract; import android.provider.Settings; import android.support.v4.app.ActivityCompat; @@ -44,6 +48,9 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.RelativeLayout; @@ -54,11 +61,15 @@ import com.getbase.floatingactionbutton.FloatingActionButton; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.results.CertifyResult; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -68,7 +79,9 @@ import org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView; import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.ExportHelper; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Preferences; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -105,6 +118,10 @@ public class ViewKeyActivity extends BaseActivity implements private boolean mIsSecret = false; private boolean mHasEncrypt = false; private boolean mIsVerified = false; + private MenuItem mRefreshItem; + private boolean mIsRefreshing; + private Animation mRotate, mRotateSpin; + private View mRefresh; @Override protected void onCreate(Bundle savedInstanceState) { @@ -128,6 +145,51 @@ public class ViewKeyActivity extends BaseActivity implements mQrCode = (ImageView) findViewById(R.id.view_key_qr_code); mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout); + mRotateSpin = AnimationUtils.loadAnimation(this, R.anim.rotate_spin); + mRotateSpin.setAnimationListener(new AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + + } + + @Override + public void onAnimationEnd(Animation animation) { + mRefreshItem.getActionView().clearAnimation(); + mRefreshItem.setActionView(null); + mRefreshItem.setEnabled(true); + + // this is a deferred call + supportInvalidateOptionsMenu(); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + mRotate = AnimationUtils.loadAnimation(this, R.anim.rotate); + mRotate.setRepeatCount(Animation.INFINITE); + mRotate.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + + } + + @Override + public void onAnimationEnd(Animation animation) { + + } + + @Override + public void onAnimationRepeat(Animation animation) { + if (!mIsRefreshing) { + mRefreshItem.getActionView().clearAnimation(); + mRefreshItem.getActionView().startAnimation(mRotateSpin); + } + } + }); + mRefresh = getLayoutInflater().inflate(R.layout.indeterminate_progress, null); + mDataUri = getIntent().getData(); if (mDataUri == null) { Log.e(Constants.TAG, "Data missing. Should be uri of key!"); @@ -222,7 +284,7 @@ public class ViewKeyActivity extends BaseActivity implements public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.key_view, menu); - + mRefreshItem = menu.findItem(R.id.menu_key_view_refresh); return true; } @@ -324,6 +386,25 @@ public class ViewKeyActivity extends BaseActivity implements private void certifyFingeprint(Uri dataUri) { Intent intent = new Intent(this, CertifyFingerprintActivity.class); intent.setData(dataUri); + + // Message is received after signing is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + Bundle data = message.getData(); + CertifyResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); + + result.createNotify(ViewKeyActivity.this).show(); + } + } + }; + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + startActivityForResult(intent, 0); } @@ -414,16 +495,72 @@ public class ViewKeyActivity extends BaseActivity implements private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper) throws ProviderHelper.NotFoundException { + + mIsRefreshing = true; + mRefreshItem.setEnabled(false); + mRefreshItem.setActionView(mRefresh); + mRefresh.startAnimation(mRotate); + byte[] blob = (byte[]) providerHelper.getGenericData( KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri), KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB); String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob); - Intent queryIntent = new Intent(this, ImportKeysActivity.class); - queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT); - queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint); + ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null); + ArrayList<ParcelableKeyRing> entries = new ArrayList<>(); + entries.add(keyEntry); + + // Message is received after importing is done in KeychainIntentService + KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler(this) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + mIsRefreshing = false; + + if (returnData == null) { + finish(); + return; + } + final ImportKeyResult result = + returnData.getParcelable(OperationResult.EXTRA_RESULT); + result.createNotify(ViewKeyActivity.this).show(); + } + } + }; + + // fill values for this action + Bundle data = new Bundle(); + + // search config + { + Preferences prefs = Preferences.getPreferences(this); + Preferences.CloudSearchPrefs cloudPrefs = + new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); + data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + } + + data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, entries); + + // Send all information needed to service to query keys in other thread + Intent intent = new Intent(this, KeychainIntentService.class); + intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(serviceHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + serviceHandler.showProgressDialog(this); + + // start service with intent + startService(intent); - startActivityForResult(queryIntent, 0); } private void editKey(Uri dataUri) { @@ -603,6 +740,8 @@ public class ViewKeyActivity extends BaseActivity implements } } + int mPreviousColor = 0; + @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { /* TODO better error handling? May cause problems when a key is deleted, @@ -634,8 +773,12 @@ public class ViewKeyActivity extends BaseActivity implements && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date()); mIsVerified = data.getInt(INDEX_VERIFIED) > 0; - // re-create options menu based on mIsSecret, mIsVerified - supportInvalidateOptionsMenu(); + // if the refresh animation isn't playing + if (!mRotate.hasStarted() && !mRotateSpin.hasStarted()) { + // re-create options menu based on mIsSecret, mIsVerified + supportInvalidateOptionsMenu(); + // this is done at the end of the animation otherwise + } AsyncTask<String, Void, Bitmap> photoTask = new AsyncTask<String, Void, Bitmap>() { @@ -743,9 +886,31 @@ public class ViewKeyActivity extends BaseActivity implements mFab.setVisibility(View.VISIBLE); } } - mToolbar.setBackgroundColor(color); - mStatusBar.setBackgroundColor(color); - mBigToolbar.setBackgroundColor(color); + + if (mPreviousColor == 0 || mPreviousColor == color) { + mToolbar.setBackgroundColor(color); + mStatusBar.setBackgroundColor(color); + mBigToolbar.setBackgroundColor(color); + mPreviousColor = color; + } else { + ObjectAnimator colorFade1 = + ObjectAnimator.ofObject(mToolbar, "backgroundColor", + new ArgbEvaluator(), mPreviousColor, color); + ObjectAnimator colorFade2 = + ObjectAnimator.ofObject(mStatusBar, "backgroundColor", + new ArgbEvaluator(), mPreviousColor, color); + ObjectAnimator colorFade3 = + ObjectAnimator.ofObject(mBigToolbar, "backgroundColor", + new ArgbEvaluator(), mPreviousColor, color); + + colorFade1.setDuration(1200); + colorFade2.setDuration(1200); + colorFade3.setDuration(1200); + colorFade1.start(); + colorFade2.start(); + colorFade3.start(); + mPreviousColor = color; + } mStatusImage.setAlpha(80); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 894529cc5..9d79b377c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -124,16 +124,16 @@ public class ViewKeyAdvActivity extends BaseActivity implements mTabsAdapter = new PagerTabStripAdapter(this); mViewPager.setAdapter(mTabsAdapter); - Bundle mainBundle = new Bundle(); - mainBundle.putParcelable(ViewKeyAdvMainFragment.ARG_DATA_URI, dataUri); - mTabsAdapter.addTab(ViewKeyAdvMainFragment.class, - mainBundle, getString(R.string.key_view_tab_main)); - Bundle shareBundle = new Bundle(); - shareBundle.putParcelable(ViewKeyAdvMainFragment.ARG_DATA_URI, dataUri); + shareBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); mTabsAdapter.addTab(ViewKeyAdvShareFragment.class, shareBundle, getString(R.string.key_view_tab_share)); + Bundle userIdsBundle = new Bundle(); + userIdsBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); + mTabsAdapter.addTab(ViewKeyAdvUserIdsFragment.class, + userIdsBundle, getString(R.string.section_user_ids)); + Bundle keysBundle = new Bundle(); keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri); mTabsAdapter.addTab(ViewKeyAdvSubkeysFragment.class, diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index fc107d794..c4e6639a8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvMainFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -18,9 +18,7 @@ package org.sufficientlysecure.keychain.ui; -import android.content.Intent; import android.database.Cursor; -import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.LoaderManager; @@ -30,31 +28,22 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; -import android.widget.ImageView; import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment; import org.sufficientlysecure.keychain.util.Log; -import java.util.Date; - -public class ViewKeyAdvMainFragment extends LoaderFragment implements +public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks<Cursor> { public static final String ARG_DATA_URI = "uri"; - private View mActionCertify; - private View mActionCertifyText; - private ImageView mActionCertifyImage; - private ListView mUserIds; private static final int LOADER_ID_UNIFIED = 0; @@ -70,12 +59,6 @@ public class ViewKeyAdvMainFragment extends LoaderFragment implements View view = inflater.inflate(R.layout.view_key_adv_main_fragment, getContainer()); mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids); - mActionCertify = view.findViewById(R.id.view_key_action_certify); - mActionCertifyText = view.findViewById(R.id.view_key_action_certify_text); - mActionCertifyImage = (ImageView) view.findViewById(R.id.view_key_action_certify_image); - // make certify image gray, like action icons - mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light), - PorterDuff.Mode.SRC_IN); mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -120,12 +103,6 @@ public class ViewKeyAdvMainFragment extends LoaderFragment implements Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); - mActionCertify.setOnClickListener(new View.OnClickListener() { - public void onClick(View view) { - certify(mDataUri); - } - }); - mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); mUserIds.setAdapter(mUserIdsAdapter); @@ -178,21 +155,6 @@ public class ViewKeyAdvMainFragment extends LoaderFragment implements case LOADER_ID_UNIFIED: { if (data.moveToFirst()) { - // If this key is revoked, it cannot be used for anything! - if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) { - mActionCertify.setEnabled(false); - mActionCertifyText.setEnabled(false); - } else { - - Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000); - if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) { - mActionCertify.setEnabled(false); - mActionCertifyText.setEnabled(false); - } else { - mActionCertify.setEnabled(true); - mActionCertifyText.setEnabled(true); - } - } break; } @@ -219,18 +181,4 @@ public class ViewKeyAdvMainFragment extends LoaderFragment implements } } - private void certify(Uri dataUri) { - long keyId = 0; - try { - keyId = new ProviderHelper(getActivity()) - .getCachedPublicKeyRing(dataUri) - .extractOrGetMasterKeyId(); - } catch (PgpKeyNotFoundException e) { - Log.e(Constants.TAG, "key not found!", e); - } - Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId}); - startActivityForResult(certifyIntent, 0); - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java index 5483d16b8..25edc7a02 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java @@ -80,7 +80,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { View root = super.onCreateView(inflater, superContainer, savedInstanceState); - View view = inflater.inflate(R.layout.view_key_trust_fragment, getContainer()); + View view = inflater.inflate(R.layout.view_key_adv_keybase_fragment, getContainer()); mInflater = inflater; mTrustReadout = (TextView) view.findViewById(R.id.view_key_trust_readout); @@ -299,7 +299,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements int rowNumber = 1; for (CharSequence s : result.mProofs) { - TableRow row = (TableRow) mInflater.inflate(R.layout.view_key_keybase_proof, null); + TableRow row = (TableRow) mInflater.inflate(R.layout.view_key_adv_keybase_proof, null); TextView number = (TextView) row.findViewById(R.id.proof_number); TextView text = (TextView) row.findViewById(R.id.proof_text); number.setText(Integer.toString(rowNumber++) + ". "); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java index ad7c9e430..8c0ab9165 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -72,19 +72,19 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes, SaveKeyringParcel saveKeyringParcel) { - this(context, c, flags, showCheckBoxes, false, saveKeyringParcel); + this(context, c, flags, showCheckBoxes, true, saveKeyringParcel); } public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) { - this(context, c, flags, showCheckBoxes, false, null); + this(context, c, flags, showCheckBoxes, true, null); } public UserIdsAdapter(Context context, Cursor c, int flags, SaveKeyringParcel saveKeyringParcel) { - this(context, c, flags, false, false, saveKeyringParcel); + this(context, c, flags, false, true, saveKeyringParcel); } public UserIdsAdapter(Context context, Cursor c, int flags) { - this(context, c, flags, false, false, null); + this(context, c, flags, false, true, null); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java index 6f8c477c0..8686b605f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java @@ -19,14 +19,16 @@ package org.sufficientlysecure.keychain.ui.util; import android.app.Activity; import android.content.res.Resources; -import android.graphics.Color; import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.Snackbar.SnackbarDuration; import com.nispok.snackbar.SnackbarManager; +import com.nispok.snackbar.enums.SnackbarType; import com.nispok.snackbar.listeners.ActionClickListener; +import com.nispok.snackbar.listeners.EventListenerAdapter; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.util.FabContainer; /** * Notify wrapper which allows a more easy use of different notification libraries @@ -40,15 +42,13 @@ public class Notify { /** * Shows a simple in-layout notification with the CharSequence given as parameter - * @param activity * @param text Text to show * @param style Notification styling */ - public static void showNotify(Activity activity, CharSequence text, Style style) { + public static void showNotify(final Activity activity, CharSequence text, Style style) { - Snackbar bar = Snackbar.with(activity) - .text(text) - .duration(SnackbarDuration.LENGTH_LONG); + Snackbar bar = getSnackbar(activity) + .text(text); switch (style) { case OK: @@ -66,8 +66,9 @@ public class Notify { } public static Showable createNotify (Activity activity, int resId, int duration, Style style) { - final Snackbar bar = Snackbar.with(activity) + final Snackbar bar = getSnackbar(activity) .text(resId); + if (duration == LENGTH_INDEFINITE) { bar.duration(SnackbarDuration.LENGTH_INDEFINITE); } else { @@ -101,7 +102,8 @@ public class Notify { public static Showable createNotify(Activity activity, String msg, int duration, Style style, final ActionListener listener, int resIdAction) { - final Snackbar bar = Snackbar.with(activity) + + final Snackbar bar = getSnackbar(activity) .text(msg) .actionLabel(resIdAction) .actionListener(new ActionClickListener() { @@ -110,6 +112,7 @@ public class Notify { listener.onAction(); } }); + if (duration == LENGTH_INDEFINITE) { bar.duration(SnackbarDuration.LENGTH_INDEFINITE); } else { @@ -139,7 +142,6 @@ public class Notify { /** * Shows a simple in-layout notification with the resource text from given id - * @param activity * @param resId ResourceId of notification text * @param style Notification styling * @throws Resources.NotFoundException @@ -148,6 +150,27 @@ public class Notify { showNotify(activity, activity.getResources().getText(resId), style); } + private static Snackbar getSnackbar(final Activity activity) { + Snackbar bar = Snackbar.with(activity) + .type(SnackbarType.MULTI_LINE) + .duration(SnackbarDuration.LENGTH_LONG); + + if (activity instanceof FabContainer) { + bar.eventListener(new EventListenerAdapter() { + @Override + public void onShow(Snackbar snackbar) { + ((FabContainer) activity).fabMoveUp(snackbar.getHeight()); + } + + @Override + public void onDismiss(Snackbar snackbar) { + ((FabContainer) activity).fabRestorePosition(); + } + }); + } + return bar; + } + public interface Showable { public void show(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java deleted file mode 100644 index 3403208d7..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ListAwareSwipeRefreshLayout.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2014 Daniel Albert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.content.Context; -import android.support.v4.widget.NoScrollableSwipeRefreshLayout; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import se.emilsjolander.stickylistheaders.StickyListHeadersListView; - -public class ListAwareSwipeRefreshLayout extends NoScrollableSwipeRefreshLayout { - - private StickyListHeadersListView mStickyListHeadersListView = null; - private boolean mIsLocked = false; - - /** - * Constructors - */ - public ListAwareSwipeRefreshLayout(Context context) { - super(context); - } - - public ListAwareSwipeRefreshLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - /** - * Getters / Setters - */ - public void setStickyListHeadersListView(StickyListHeadersListView stickyListHeadersListView) { - mStickyListHeadersListView = stickyListHeadersListView; - } - - public StickyListHeadersListView getStickyListHeadersListView() { - return mStickyListHeadersListView; - } - - public void setIsLocked(boolean locked) { - mIsLocked = locked; - } - - public boolean getIsLocked() { - return mIsLocked; - } - - @Override - public boolean canChildScrollUp() { - if (mStickyListHeadersListView == null) { - return super.canChildScrollUp(); - } - - return (mIsLocked || ( - mStickyListHeadersListView.getWrappedList().getChildCount() > 0 - && (mStickyListHeadersListView.getWrappedList().getChildAt(0).getTop() < 0 - || mStickyListHeadersListView.getFirstVisiblePosition() > 0) - ) - ); - } - - /** Called on a touch event, this method exempts a small area in the upper right from pull to - * refresh handling. - * - * If the touch event happens somewhere in the upper right corner of the screen, we return false - * to indicate that the event was not handled. This ensures events in that area are always - * handed through to the list scrollbar handle. For all other cases, we pass the message through - * to the pull to refresh handler. - */ - @Override - public boolean onTouchEvent(MotionEvent event) { - // The device may be null. This actually happens - if (event.getDevice() != null) { - // MotionEvent.AXIS_X is api level 12, for some reason, so we use a constant 0 here - float ratioX = event.getX() / event.getDevice().getMotionRange(0).getMax(); - float ratioY = event.getY() / event.getDevice().getMotionRange(1).getMax(); - // if this is the upper right corner, don't handle as pull to refresh event - if (ratioX > 0.85f && ratioY < 0.15f) { - return false; - } - } - return super.onTouchEvent(event); - } - -}
\ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FabContainer.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FabContainer.java new file mode 100644 index 000000000..116b98d1e --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FabContainer.java @@ -0,0 +1,8 @@ +package org.sufficientlysecure.keychain.util; + +public interface FabContainer { + + void fabMoveUp(int height); + void fabRestorePosition(); + +} |