From abac3b2445e005696e6118b06864ee914d3c3c3a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 27 Jun 2018 23:02:14 +0200 Subject: [PATCH] use KeyChoiceAdapter in SelectSignKeyIdListFragment --- .../AppSettingsAllowedKeysListFragment.java | 2 +- .../remote/ui/SelectPublicKeyFragment.java | 2 +- .../ui/SelectSignKeyIdListFragment.java | 160 +++++++----------- .../ui/dialog/RemoteDeduplicatePresenter.java | 2 +- .../keychain/ui/adapter/KeyChoiceAdapter.java | 33 +++- .../keychain/ui/base/RecyclerFragment.java | 13 +- 6 files changed, 106 insertions(+), 106 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java index 4206d458f..80682729c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java @@ -89,7 +89,7 @@ public class AppSettingsAllowedKeysListFragment extends RecyclerFragment data) { if (keyChoiceAdapter == null) { - keyChoiceAdapter = new KeyChoiceAdapter(true, data); + keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(data); setAdapter(keyChoiceAdapter); Set checkedIds = apiAppDao.getAllowedKeyIdsForApp(packageName); keyChoiceAdapter.setSelectionByIds(checkedIds); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectPublicKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectPublicKeyFragment.java index 847321f16..c9726bd40 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectPublicKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectPublicKeyFragment.java @@ -123,7 +123,7 @@ public class SelectPublicKeyFragment extends RecyclerFragment public void onLoadUnifiedKeyData(List data) { if (keyChoiceAdapter == null) { - keyChoiceAdapter = new KeyChoiceAdapter(true, data); + keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(data); setAdapter(keyChoiceAdapter); keyChoiceAdapter.setSelectionByIds(selectedMasterKeyIds); } else { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java index 38110e624..f42b2079e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java @@ -18,39 +18,45 @@ package org.sufficientlysecure.keychain.remote.ui; +import java.util.List; + import android.app.Activity; +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.ViewModelProviders; import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; import android.os.Bundle; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; import android.support.v7.widget.LinearLayoutManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpUtils; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.ApiAppDao; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.remote.ui.adapter.SelectSignKeyAdapter; +import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.ui.CreateKeyActivity; +import org.sufficientlysecure.keychain.ui.adapter.KeyChoiceAdapter; import org.sufficientlysecure.keychain.ui.base.RecyclerFragment; -import org.sufficientlysecure.keychain.ui.util.adapter.CursorAdapter; +import org.sufficientlysecure.keychain.ui.keyview.GenericViewModel; -public class SelectSignKeyIdListFragment extends RecyclerFragment - implements SelectSignKeyAdapter.SelectSignKeyListener, LoaderManager.LoaderCallbacks { - +public class SelectSignKeyIdListFragment extends RecyclerFragment { private static final String ARG_PACKAGE_NAME = "package_name"; private static final String ARG_PREF_UID = "pref_uid"; public static final String ARG_DATA = "data"; - private Intent mResult; - private String mPrefUid; - private ApiAppDao mApiAppDao; - private String mPackageName; + private ApiAppDao apiAppDao; + private KeyRepository keyRepository; + + private KeyChoiceAdapter keyChoiceAdapter; + + private Intent resultIntent; + private String prefUid; + private String packageName; public static SelectSignKeyIdListFragment newInstance(String packageName, Intent data, String preferredUserId) { SelectSignKeyIdListFragment frag = new SelectSignKeyIdListFragment(); @@ -68,112 +74,74 @@ public class SelectSignKeyIdListFragment extends RecyclerFragment onCreateKeyDummyClicked()); + + return linearLayout; } - /** - * Define Adapter and Loader on create of Activity - */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mResult = getArguments().getParcelable(ARG_DATA); - mPrefUid = getArguments().getString(ARG_PREF_UID); - mPackageName = getArguments().getString(ARG_PACKAGE_NAME); + resultIntent = getArguments().getParcelable(ARG_DATA); + prefUid = getArguments().getString(ARG_PREF_UID); + packageName = getArguments().getString(ARG_PACKAGE_NAME); - // Give some text to display if there is no data. In a real - // application this would come from a resource. setEmptyText(getString(R.string.list_empty)); - - SelectSignKeyAdapter adapter = new SelectSignKeyAdapter(getContext(), null); - adapter.setListener(this); - - setAdapter(adapter); setLayoutManager(new LinearLayoutManager(getContext())); - - // Start out with a progress indicator. hideList(false); - // Prepare the loader. Either re-connect with an existing one, - // or start a new one. - getLoaderManager().initLoader(0, null, this); + GenericViewModel viewModel = ViewModelProviders.of(this).get(GenericViewModel.class); + LiveData> liveData = viewModel.getGenericLiveData( + requireContext(), keyRepository::getAllUnifiedKeyInfoWithSecret); + liveData.observe(this, this::onLoadUnifiedKeyData); } - @Override - public Loader onCreateLoader(int id, Bundle args) { - Uri baseUri = KeyRings.buildUnifiedKeyRingsUri(); - - // These are the rows that we will retrieve. - String[] projection = new String[]{ - KeyRings._ID, - KeyRings.MASTER_KEY_ID, - KeyRings.USER_ID, - KeyRings.IS_EXPIRED, - KeyRings.IS_REVOKED, - KeyRings.HAS_ENCRYPT, - KeyRings.VERIFIED, - KeyRings.HAS_ANY_SECRET, - KeyRings.HAS_DUPLICATE_USER_ID, - KeyRings.CREATION, - KeyRings.NAME, - KeyRings.EMAIL, - KeyRings.COMMENT - }; - - String selection = KeyRings.HAS_ANY_SECRET + " != 0"; - - String orderBy = KeyRings.USER_ID + " ASC"; - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, projection, selection, null, orderBy); - } - - @Override - public void onLoadFinished(Loader loader, Cursor data) { - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - getAdapter().swapCursor(CursorAdapter.KeyCursor.wrap(data)); - - // The list should now be shown. - if (isResumed()) { - showList(true); + public void onLoadUnifiedKeyData(List data) { + if (keyChoiceAdapter == null) { + keyChoiceAdapter = KeyChoiceAdapter.createSingleClickableAdapter(data, this::onSelectKeyItemClicked); + setAdapter(keyChoiceAdapter); } else { - showList(false); + keyChoiceAdapter.setUnifiedKeyInfoItems(data); } + boolean animateShowList = !isResumed(); + showList(animateShowList); } - @Override - public void onLoaderReset(Loader loader) { - // This is called when the last Cursor provided to onLoadFinished() - // above is about to be closed. We need to make sure we are no - // longer using it. - getAdapter().swapCursor(null); - } - - @Override - public void onDestroy() { - getAdapter().setListener(null); - super.onDestroy(); - } - - @Override public void onCreateKeyDummyClicked() { - OpenPgpUtils.UserId userIdSplit = KeyRing.splitUserId(mPrefUid); + OpenPgpUtils.UserId userIdSplit = KeyRing.splitUserId(prefUid); Intent intent = new Intent(getActivity(), CreateKeyActivity.class); intent.putExtra(CreateKeyActivity.EXTRA_NAME, userIdSplit.name); intent.putExtra(CreateKeyActivity.EXTRA_EMAIL, userIdSplit.email); - getActivity().startActivityForResult(intent, SelectSignKeyIdActivity.REQUEST_CODE_CREATE_KEY); + + requireActivity().startActivityForResult(intent, SelectSignKeyIdActivity.REQUEST_CODE_CREATE_KEY); } - @Override - public void onSelectKeyItemClicked(long masterKeyId) { - mApiAppDao.addAllowedKeyIdForApp(mPackageName, masterKeyId); - mResult.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, masterKeyId); + private void onSelectKeyItemClicked(UnifiedKeyInfo keyInfo) { + apiAppDao.addAllowedKeyIdForApp(packageName, keyInfo.master_key_id()); + resultIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, keyInfo.master_key_id()); - getActivity().setResult(Activity.RESULT_OK, mResult); - getActivity().finish(); + Activity activity = requireActivity(); + activity.setResult(Activity.RESULT_OK, resultIntent); + activity.finish(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java index d51a5b0a1..43ec37551 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java @@ -62,7 +62,7 @@ class RemoteDeduplicatePresenter { private void onLoadKeyInfos(List data) { if (keyChoiceAdapter == null) { - keyChoiceAdapter = new KeyChoiceAdapter(false, data); + keyChoiceAdapter = KeyChoiceAdapter.createSingleChoiceAdapter(data); view.setKeyListAdapter(keyChoiceAdapter); } else { keyChoiceAdapter.setUnifiedKeyInfoItems(data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyChoiceAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyChoiceAdapter.java index d495cb4e9..107628eab 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyChoiceAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyChoiceAdapter.java @@ -4,6 +4,7 @@ package org.sufficientlysecure.keychain.ui.adapter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import android.content.Context; @@ -25,12 +26,27 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyChoiceAdapter.KeyChoiceItem public class KeyChoiceAdapter extends FlexibleAdapter { + private final OnKeyClickListener onKeyClickListener; private Integer activeItem; - public KeyChoiceAdapter(boolean isMultiChoice, List items) { + public static KeyChoiceAdapter createSingleClickableAdapter(List items, + OnKeyClickListener onKeyClickListener) { + return new KeyChoiceAdapter(items, Objects.requireNonNull(onKeyClickListener), Mode.IDLE); + } + + public static KeyChoiceAdapter createSingleChoiceAdapter(List items) { + return new KeyChoiceAdapter(items, null, Mode.SINGLE); + } + + public static KeyChoiceAdapter createMultiChoiceAdapter(List items) { + return new KeyChoiceAdapter(items, null, Mode.MULTI); + } + + private KeyChoiceAdapter(List items, OnKeyClickListener onKeyClickListener, int idle) { super(getKeyChoiceItems(items)); - setMode(isMultiChoice ? Mode.MULTI : Mode.SINGLE); + setMode(idle); addListener((OnItemClickListener) (view, position) -> onClickItem(position)); + this.onKeyClickListener = onKeyClickListener; } @Nullable @@ -50,10 +66,15 @@ public class KeyChoiceAdapter extends FlexibleAdapter { if (getMode() == Mode.MULTI) { toggleSelection(position); notifyItemChanged(position); - } else { + return true; + } else if (getMode() == Mode.SINGLE) { setActiveItem(position); + return true; } - return true; + + KeyChoiceItem item = getItem(position); + onKeyClickListener.onKeyClick(item.keyInfo); + return false; } public void setActiveItem(Integer newActiveItem) { @@ -212,4 +233,8 @@ public class KeyChoiceAdapter extends FlexibleAdapter { } } } + + public interface OnKeyClickListener { + void onKeyClick(UnifiedKeyInfo keyInfo); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/RecyclerFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/RecyclerFragment.java index 171db0849..091d073be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/RecyclerFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/RecyclerFragment.java @@ -16,10 +16,10 @@ package org.sufficientlysecure.keychain.ui.base; + import android.content.Context; import android.os.Bundle; import android.os.Handler; -import android.support.annotation.LayoutRes; import android.support.v4.app.Fragment; import android.support.v7.widget.RecyclerView; import android.view.Gravity; @@ -32,7 +32,7 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; -import org.sufficientlysecure.keychain.ui.util.FormattingUtils; +import org.sufficientlysecure.keychain.R; import timber.log.Timber; @@ -124,9 +124,16 @@ public class RecyclerFragment extends Fragment { ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - FrameLayout listContainer = new FrameLayout(context); + LinearLayout listContainer = new LinearLayout(context); + listContainer.setOrientation(LinearLayout.VERTICAL); listContainer.setId(INTERNAL_LIST_CONTAINER_ID); + LinearLayout headerLayout = new LinearLayout(context); + headerLayout.setId(R.id.headerlayout); + + listContainer.addView(headerLayout, new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + TextView textView = new TextView(context); textView.setId(INTERNAL_EMPTY_VIEW_ID); textView.setGravity(Gravity.CENTER);