use mvp pattern for linked id card
This commit is contained in:
@@ -84,7 +84,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.service.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.ViewKeyFragment.PostponeType;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseSecurityTokenActivity;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
|
||||
@@ -111,7 +110,6 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
|
||||
public static final String EXTRA_SECURITY_TOKEN_AID = "security_token_aid";
|
||||
public static final String EXTRA_SECURITY_TOKEN_VERSION = "security_token_version";
|
||||
public static final String EXTRA_SECURITY_TOKEN_FINGERPRINTS = "security_token_fingerprints";
|
||||
private boolean mLinkedTransition;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({REQUEST_QR_FINGERPRINT, REQUEST_BACKUP, REQUEST_CERTIFY, REQUEST_DELETE})
|
||||
@@ -332,11 +330,6 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
|
||||
return;
|
||||
}
|
||||
|
||||
mLinkedTransition = getIntent().getBooleanExtra(EXTRA_LINKED_TRANSITION, false);
|
||||
if (mLinkedTransition && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
postponeEnterTransition();
|
||||
}
|
||||
|
||||
if (Preferences.getPreferences(this).getExperimentalEnableKeybase()) {
|
||||
FragmentManager manager = getSupportFragmentManager();
|
||||
final ViewKeyKeybaseFragment keybaseFrag = ViewKeyKeybaseFragment.newInstance(mDataUri);
|
||||
@@ -742,8 +735,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
|
||||
}
|
||||
|
||||
// if the main fragment doesn't exist, or is not of the correct type, (re)create it
|
||||
frag = ViewKeyFragment.newInstance(mMasterKeyId, mIsSecret,
|
||||
mLinkedTransition ? PostponeType.LINKED : PostponeType.NONE);
|
||||
frag = ViewKeyFragment.newInstance(mMasterKeyId, mIsSecret);
|
||||
// get rid of possible backstack, this fragment is always at the bottom
|
||||
manager.popBackStack("security_token", FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
manager.beginTransaction()
|
||||
|
||||
@@ -19,67 +19,49 @@
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.transition.Fade;
|
||||
import android.transition.Transition;
|
||||
import android.transition.TransitionInflater;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver.OnPreDrawListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.LinkedIdsAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.base.LoaderFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
|
||||
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment.OnIdentityLoadedListener;
|
||||
import org.sufficientlysecure.keychain.ui.linked.LinkedIdWizard;
|
||||
import org.sufficientlysecure.keychain.ui.widget.KeyHealthCardView;
|
||||
import org.sufficientlysecure.keychain.ui.widget.KeyHealthPresenter;
|
||||
import org.sufficientlysecure.keychain.ui.widget.LinkedIdentitiesCardView;
|
||||
import org.sufficientlysecure.keychain.ui.widget.LinkedIdentitiesPresenter;
|
||||
import org.sufficientlysecure.keychain.ui.widget.LinkedIdentitiesPresenter.LinkedIdsFragMvpView;
|
||||
import org.sufficientlysecure.keychain.ui.widget.SystemContactCardView;
|
||||
import org.sufficientlysecure.keychain.ui.widget.SystemContactPresenter;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
|
||||
public class ViewKeyFragment extends LoaderFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
public class ViewKeyFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks<Cursor>,
|
||||
LinkedIdsFragMvpView {
|
||||
|
||||
public static final String ARG_MASTER_KEY_ID = "master_key_id";
|
||||
public static final String ARG_IS_SECRET = "is_secret";
|
||||
public static final String ARG_POSTPONE_TYPE = "postpone_type";
|
||||
|
||||
private ListView mUserIds;
|
||||
|
||||
enum PostponeType {
|
||||
NONE, LINKED
|
||||
}
|
||||
|
||||
boolean mIsSecret = false;
|
||||
|
||||
private static final int LOADER_ID_USER_IDS = 1;
|
||||
@@ -88,16 +70,11 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
private static final int LOADER_ID_SUBKEY_STATUS = 4;
|
||||
|
||||
private UserIdsAdapter mUserIdsAdapter;
|
||||
private LinkedIdsAdapter mLinkedIdsAdapter;
|
||||
|
||||
private Uri mDataUri;
|
||||
|
||||
private PostponeType mPostponeType;
|
||||
|
||||
private ListView mLinkedIds;
|
||||
private CardView mLinkedIdsCard;
|
||||
private TextView mLinkedIdsEmpty;
|
||||
private TextView mLinkedIdsExpander;
|
||||
LinkedIdentitiesCardView mLinkedIdsCard;
|
||||
LinkedIdentitiesPresenter mLinkedIdentitiesPresenter;
|
||||
|
||||
SystemContactCardView mSystemContactCard;
|
||||
SystemContactPresenter mSystemContactPresenter;
|
||||
@@ -110,12 +87,11 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
*/
|
||||
public static ViewKeyFragment newInstance(long masterKeyId, boolean isSecret, PostponeType postponeType) {
|
||||
public static ViewKeyFragment newInstance(long masterKeyId, boolean isSecret) {
|
||||
ViewKeyFragment frag = new ViewKeyFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putLong(ARG_MASTER_KEY_ID, masterKeyId);
|
||||
args.putBoolean(ARG_IS_SECRET, isSecret);
|
||||
args.putString(ARG_POSTPONE_TYPE, postponeType.toString());
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
@@ -129,11 +105,7 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
|
||||
mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids);
|
||||
Button userIdsEditButton = (Button) view.findViewById(R.id.view_key_card_user_ids_edit);
|
||||
mLinkedIdsCard = (CardView) view.findViewById(R.id.card_linked_ids);
|
||||
mLinkedIds = (ListView) view.findViewById(R.id.view_key_linked_ids);
|
||||
mLinkedIdsExpander = (TextView) view.findViewById(R.id.view_key_linked_ids_expander);
|
||||
mLinkedIdsEmpty = (TextView) view.findViewById(R.id.view_key_linked_ids_empty);
|
||||
Button linkedIdsAddButton = (Button) view.findViewById(R.id.view_key_card_linked_ids_add);
|
||||
mLinkedIdsCard = (LinkedIdentitiesCardView) view.findViewById(R.id.card_linked_ids);
|
||||
|
||||
userIdsEditButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -142,25 +114,12 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
}
|
||||
});
|
||||
|
||||
linkedIdsAddButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
addLinkedIdentity(mDataUri);
|
||||
}
|
||||
});
|
||||
|
||||
mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
showUserIdInfo(position);
|
||||
}
|
||||
});
|
||||
mLinkedIds.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
showLinkedId(position);
|
||||
}
|
||||
});
|
||||
|
||||
mSystemContactCard = (SystemContactCardView) view.findViewById(R.id.linked_system_contact_card);
|
||||
mKeyHealthCard = (KeyHealthCardView) view.findViewById(R.id.subkey_status_card);
|
||||
@@ -174,53 +133,6 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
startActivityForResult(editIntent, 0);
|
||||
}
|
||||
|
||||
private void addLinkedIdentity(Uri dataUri) {
|
||||
Intent intent = new Intent(getActivity(), LinkedIdWizard.class);
|
||||
intent.setData(dataUri);
|
||||
startActivity(intent);
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private void showLinkedId(final int position) {
|
||||
final LinkedIdViewFragment frag;
|
||||
try {
|
||||
frag = mLinkedIdsAdapter.getLinkedIdFragment(mDataUri, position, mMasterKeyId);
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "IOException", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Transition trans = TransitionInflater.from(getActivity())
|
||||
.inflateTransition(R.transition.linked_id_card_trans);
|
||||
// setSharedElementReturnTransition(trans);
|
||||
setExitTransition(new Fade());
|
||||
frag.setSharedElementEnterTransition(trans);
|
||||
}
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(R.id.view_key_fragment, frag)
|
||||
.hide(frag)
|
||||
.commit();
|
||||
|
||||
frag.setOnIdentityLoadedListener(new OnIdentityLoadedListener() {
|
||||
@Override
|
||||
public void onIdentityLoaded() {
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getFragmentManager().beginTransaction()
|
||||
.show(frag)
|
||||
.addSharedElement(mLinkedIdsCard, "card_linked_ids")
|
||||
.remove(ViewKeyFragment.this)
|
||||
.addToBackStack("linked_id")
|
||||
.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
@@ -228,7 +140,6 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID);
|
||||
mDataUri = KeyRings.buildGenericKeyRingUri(mMasterKeyId);
|
||||
mIsSecret = getArguments().getBoolean(ARG_IS_SECRET);
|
||||
mPostponeType = PostponeType.valueOf(getArguments().getString(ARG_POSTPONE_TYPE));
|
||||
|
||||
// load user ids after we know if it's a secret key
|
||||
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, !mIsSecret, null);
|
||||
@@ -236,9 +147,14 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
|
||||
// initialize loaders, which will take care of auto-refresh on change
|
||||
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
||||
initLinkedIds(mIsSecret);
|
||||
initCardButtonsVisibility(mIsSecret);
|
||||
|
||||
if (Preferences.getPreferences(getActivity()).getExperimentalEnableLinkedIdentities()) {
|
||||
mLinkedIdentitiesPresenter = new LinkedIdentitiesPresenter(
|
||||
getContext(), mLinkedIdsCard, this, LOADER_ID_LINKED_IDS, mMasterKeyId, mIsSecret);
|
||||
mLinkedIdentitiesPresenter.startLoader(getLoaderManager());
|
||||
}
|
||||
|
||||
mSystemContactPresenter = new SystemContactPresenter(
|
||||
getContext(), mSystemContactCard, LOADER_ID_LINKED_CONTACT, mMasterKeyId, mIsSecret);
|
||||
mSystemContactPresenter.startLoader(getLoaderManager());
|
||||
@@ -248,6 +164,20 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
mKeyHealthPresenter.startLoader(getLoaderManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchToFragment(final Fragment frag, final String backStackName) {
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getFragmentManager().beginTransaction()
|
||||
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
|
||||
.replace(R.id.view_key_fragment, frag)
|
||||
.addToBackStack(backStackName)
|
||||
.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showUserIdInfo(final int position) {
|
||||
if (!mIsSecret) {
|
||||
final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position);
|
||||
@@ -283,10 +213,7 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
return UserIdsAdapter.createLoader(getActivity(), mDataUri);
|
||||
}
|
||||
|
||||
case LOADER_ID_LINKED_IDS: {
|
||||
return LinkedIdsAdapter.createLoader(getActivity(), mDataUri);
|
||||
}
|
||||
|
||||
case LOADER_ID_LINKED_IDS:
|
||||
case LOADER_ID_LINKED_CONTACT:
|
||||
case LOADER_ID_SUBKEY_STATUS: {
|
||||
throw new IllegalStateException("This callback should never end up here!");
|
||||
@@ -315,31 +242,7 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
break;
|
||||
}
|
||||
|
||||
case LOADER_ID_LINKED_IDS: {
|
||||
mLinkedIdsAdapter.swapCursor(data);
|
||||
|
||||
if (mIsSecret) {
|
||||
mLinkedIdsCard.setVisibility(View.VISIBLE);
|
||||
mLinkedIdsEmpty.setVisibility(mLinkedIdsAdapter.getCount() > 0 ? View.GONE : View.VISIBLE);
|
||||
} else {
|
||||
mLinkedIdsCard.setVisibility(mLinkedIdsAdapter.getCount() > 0 ? View.VISIBLE : View.GONE);
|
||||
mLinkedIdsEmpty.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mPostponeType == PostponeType.LINKED) {
|
||||
mLinkedIdsCard.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
|
||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
mLinkedIdsCard.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
getActivity().startPostponedEnterTransition();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LOADER_ID_LINKED_IDS:
|
||||
case LOADER_ID_LINKED_CONTACT:
|
||||
case LOADER_ID_SUBKEY_STATUS: {
|
||||
throw new IllegalStateException("This callback should never end up here!");
|
||||
@@ -347,16 +250,6 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
}
|
||||
}
|
||||
|
||||
private void initLinkedIds(boolean isSecret) {
|
||||
if (!Preferences.getPreferences(getActivity()).getExperimentalEnableLinkedIdentities()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLinkedIdsAdapter = new LinkedIdsAdapter(getActivity(), null, 0, isSecret, mLinkedIdsExpander);
|
||||
mLinkedIds.setAdapter(mLinkedIdsAdapter);
|
||||
getLoaderManager().initLoader(LOADER_ID_LINKED_IDS, null, this);
|
||||
}
|
||||
|
||||
private void initCardButtonsVisibility(boolean isSecret) {
|
||||
LinearLayout buttonsUserIdsLayout =
|
||||
(LinearLayout) getActivity().findViewById(R.id.view_key_card_user_ids_buttons);
|
||||
@@ -382,10 +275,6 @@ public class ViewKeyFragment extends LoaderFragment implements
|
||||
mUserIdsAdapter.swapCursor(null);
|
||||
break;
|
||||
}
|
||||
case LOADER_ID_LINKED_IDS: {
|
||||
mLinkedIdsAdapter.swapCursor(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,11 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui.adapter;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
@@ -37,6 +40,7 @@ import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.linked.LinkedAttribute;
|
||||
import org.sufficientlysecure.keychain.linked.UriAttribute;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
@@ -45,45 +49,22 @@ import org.sufficientlysecure.keychain.ui.util.SubtleAttentionSeeker;
|
||||
import org.sufficientlysecure.keychain.util.FilterCursorWrapper;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class LinkedIdsAdapter extends UserAttributesAdapter {
|
||||
private final boolean mIsSecret;
|
||||
protected LayoutInflater mInflater;
|
||||
WeakHashMap<Integer,UriAttribute> mLinkedIdentityCache = new WeakHashMap<>();
|
||||
|
||||
private Cursor mUnfilteredCursor;
|
||||
|
||||
private TextView mExpander;
|
||||
|
||||
public LinkedIdsAdapter(Context context, Cursor c, int flags,
|
||||
boolean isSecret, TextView expander) {
|
||||
public LinkedIdsAdapter(Context context, Cursor c, int flags, boolean isSecret) {
|
||||
super(context, c, flags);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mIsSecret = isSecret;
|
||||
|
||||
if (expander != null) {
|
||||
expander.setVisibility(View.GONE);
|
||||
/* don't show an expander (maybe in some sort of advanced view?)
|
||||
mExpander = expander;
|
||||
mExpander.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showUnfiltered();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor swapCursor(Cursor cursor) {
|
||||
if (cursor == null) {
|
||||
mUnfilteredCursor = null;
|
||||
return super.swapCursor(null);
|
||||
}
|
||||
mUnfilteredCursor = cursor;
|
||||
FilterCursorWrapper filteredCursor = new FilterCursorWrapper(cursor) {
|
||||
@Override
|
||||
public boolean isVisible(Cursor cursor) {
|
||||
@@ -92,25 +73,9 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
|
||||
}
|
||||
};
|
||||
|
||||
if (mExpander != null) {
|
||||
int hidden = filteredCursor.getHiddenCount();
|
||||
if (hidden == 0) {
|
||||
mExpander.setVisibility(View.GONE);
|
||||
} else {
|
||||
mExpander.setVisibility(View.VISIBLE);
|
||||
mExpander.setText(mContext.getResources().getQuantityString(
|
||||
R.plurals.linked_id_expand, hidden));
|
||||
}
|
||||
}
|
||||
|
||||
return super.swapCursor(filteredCursor);
|
||||
}
|
||||
|
||||
private void showUnfiltered() {
|
||||
mExpander.setVisibility(View.GONE);
|
||||
super.swapCursor(mUnfilteredCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
|
||||
@@ -183,18 +148,18 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
|
||||
// don't show revoked user ids, irrelevant for average users
|
||||
public static final String LINKED_IDS_WHERE = UserPackets.IS_REVOKED + " = 0";
|
||||
|
||||
public static CursorLoader createLoader(Activity activity, Uri dataUri) {
|
||||
public static CursorLoader createLoader(Context context, Uri dataUri) {
|
||||
Uri baseUri = UserPackets.buildLinkedIdsUri(dataUri);
|
||||
return new CursorLoader(activity, baseUri,
|
||||
return new CursorLoader(context, baseUri,
|
||||
UserIdsAdapter.USER_PACKETS_PROJECTION, LINKED_IDS_WHERE, null, null);
|
||||
}
|
||||
|
||||
public LinkedIdViewFragment getLinkedIdFragment(Uri baseUri, int position, long masterKeyId) throws IOException {
|
||||
public LinkedIdViewFragment getLinkedIdFragment(int position, long masterKeyId) throws IOException {
|
||||
Cursor c = getCursor();
|
||||
c.moveToPosition(position);
|
||||
int rank = c.getInt(UserIdsAdapter.INDEX_RANK);
|
||||
|
||||
Uri dataUri = UserPackets.buildLinkedIdsUri(baseUri);
|
||||
Uri dataUri = UserPackets.buildLinkedIdsUri(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||
return LinkedIdViewFragment.newInstance(dataUri, rank, mIsSecret, masterKeyId);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
||||
private Uri mDataUri;
|
||||
private ViewHolder mViewHolder;
|
||||
private int mLidRank;
|
||||
private OnIdentityLoadedListener mIdLoadedListener;
|
||||
private long mCertifyKeyId;
|
||||
|
||||
public static LinkedIdViewFragment newInstance(Uri dataUri, int rank,
|
||||
@@ -156,11 +155,6 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
||||
|
||||
// Nothing to load means break if we are *expected* to load
|
||||
if (!cursor.moveToFirst()) {
|
||||
if (mIdLoadedListener != null) {
|
||||
Notify.create(getActivity(), "Error loading identity!",
|
||||
Notify.LENGTH_LONG, Style.ERROR).show();
|
||||
finishFragment();
|
||||
}
|
||||
// Or just ignore, this is probably some intermediate state during certify
|
||||
break;
|
||||
}
|
||||
@@ -173,11 +167,6 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
||||
|
||||
loadIdentity(linkedId, certStatus);
|
||||
|
||||
if (mIdLoadedListener != null) {
|
||||
mIdLoadedListener.onIdentityLoaded();
|
||||
mIdLoadedListener = null;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "error parsing identity", e);
|
||||
Notify.create(getActivity(), "Error parsing identity!",
|
||||
@@ -200,14 +189,6 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
|
||||
});
|
||||
}
|
||||
|
||||
public interface OnIdentityLoadedListener {
|
||||
void onIdentityLoaded();
|
||||
}
|
||||
|
||||
public void setOnIdentityLoadedListener(OnIdentityLoadedListener listener) {
|
||||
mIdLoadedListener = listener;
|
||||
}
|
||||
|
||||
private void loadIdentity(UriAttribute linkedId, int certStatus) {
|
||||
mLinkedId = linkedId;
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
*
|
||||
* 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.v7.widget.CardView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.LinkedIdsAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.widget.LinkedIdentitiesPresenter.LinkedIdsClickListener;
|
||||
import org.sufficientlysecure.keychain.ui.widget.LinkedIdentitiesPresenter.LinkedIdsMvpView;
|
||||
|
||||
|
||||
public class LinkedIdentitiesCardView extends CardView implements LinkedIdsMvpView {
|
||||
private ListView vLinkedIds;
|
||||
private TextView vLinkedIdsEmpty;
|
||||
|
||||
private LinkedIdsClickListener linkedIdsClickListener;
|
||||
|
||||
public LinkedIdentitiesCardView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.linked_identities_card, this, true);
|
||||
|
||||
vLinkedIds = (ListView) view.findViewById(R.id.view_key_linked_ids);
|
||||
vLinkedIdsEmpty = (TextView) view.findViewById(R.id.view_key_linked_ids_empty);
|
||||
Button linkedIdsAddButton = (Button) view.findViewById(R.id.view_key_card_linked_ids_add);
|
||||
|
||||
linkedIdsAddButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (linkedIdsClickListener != null) {
|
||||
linkedIdsClickListener.onClickAddIdentity();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
vLinkedIds.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (linkedIdsClickListener != null) {
|
||||
linkedIdsClickListener.onLinkedIdItemClick(position);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSystemContactClickListener(LinkedIdsClickListener linkedIdsClickListener) {
|
||||
this.linkedIdsClickListener = linkedIdsClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLinkedIdsAdapter(LinkedIdsAdapter linkedIdsAdapter) {
|
||||
vLinkedIds.setAdapter(linkedIdsAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCard(boolean visible) {
|
||||
setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView(boolean visible) {
|
||||
vLinkedIdsEmpty.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
*
|
||||
* 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 java.io.IOException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.LinkedIdsAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
|
||||
import org.sufficientlysecure.keychain.ui.linked.LinkedIdWizard;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
|
||||
public class LinkedIdentitiesPresenter implements LoaderCallbacks<Cursor> {
|
||||
private final Context context;
|
||||
private final LinkedIdsMvpView view;
|
||||
private final int loaderId;
|
||||
private final LinkedIdsFragMvpView fragView;
|
||||
|
||||
private LinkedIdsAdapter linkedIdsAdapter;
|
||||
|
||||
private final long masterKeyId;
|
||||
private final boolean isSecret;
|
||||
|
||||
public LinkedIdentitiesPresenter(
|
||||
Context context, LinkedIdsMvpView view, LinkedIdsFragMvpView fragView, int loaderId, long masterKeyId, boolean isSecret) {
|
||||
this.context = context;
|
||||
this.view = view;
|
||||
this.fragView = fragView;
|
||||
this.loaderId = loaderId;
|
||||
|
||||
this.masterKeyId = masterKeyId;
|
||||
this.isSecret = isSecret;
|
||||
|
||||
linkedIdsAdapter = new LinkedIdsAdapter(context, null, 0, isSecret);
|
||||
view.setLinkedIdsAdapter(linkedIdsAdapter);
|
||||
|
||||
view.setSystemContactClickListener(new LinkedIdsClickListener() {
|
||||
@Override
|
||||
public void onLinkedIdItemClick(int position) {
|
||||
showLinkedId(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickAddIdentity() {
|
||||
addLinkedIdentity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void startLoader(LoaderManager loaderManager) {
|
||||
loaderManager.restartLoader(loaderId, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return LinkedIdsAdapter.createLoader(context, KeyRings.buildUnifiedKeyRingUri(masterKeyId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||
linkedIdsAdapter.swapCursor(data);
|
||||
|
||||
boolean hasLinkedIdentities = linkedIdsAdapter.getCount() > 0;
|
||||
if (isSecret) {
|
||||
view.showCard(true);
|
||||
view.showEmptyView(!hasLinkedIdentities);
|
||||
} else {
|
||||
view.showCard(hasLinkedIdentities);
|
||||
view.showEmptyView(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader loader) {
|
||||
linkedIdsAdapter.swapCursor(null);
|
||||
}
|
||||
|
||||
private void showLinkedId(final int position) {
|
||||
final LinkedIdViewFragment frag;
|
||||
try {
|
||||
frag = linkedIdsAdapter.getLinkedIdFragment(position, masterKeyId);
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "IOException", e);
|
||||
return;
|
||||
}
|
||||
|
||||
fragView.switchToFragment(frag, "linked_id");
|
||||
}
|
||||
|
||||
interface LinkedIdsMvpView {
|
||||
void setSystemContactClickListener(LinkedIdsClickListener linkedIdsClickListener);
|
||||
void setLinkedIdsAdapter(LinkedIdsAdapter linkedIdsAdapter);
|
||||
|
||||
void showCard(boolean visible);
|
||||
void showEmptyView(boolean visible);
|
||||
}
|
||||
|
||||
public interface LinkedIdsFragMvpView {
|
||||
void switchToFragment(Fragment frag, String backStackName);
|
||||
}
|
||||
|
||||
interface LinkedIdsClickListener {
|
||||
void onLinkedIdItemClick(int position);
|
||||
void onClickAddIdentity();
|
||||
}
|
||||
|
||||
private void addLinkedIdentity() {
|
||||
Intent intent = new Intent(context, LinkedIdWizard.class);
|
||||
intent.setData(KeyRings.buildUnifiedKeyRingUri(masterKeyId));
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
50
OpenKeychain/src/main/res/layout/linked_identities_card.xml
Normal file
50
OpenKeychain/src/main/res/layout/linked_identities_card.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/CardViewHeader"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/section_linked_identities" />
|
||||
|
||||
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
||||
android:id="@+id/view_key_linked_ids"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/view_key_linked_ids_empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/linked_empty" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/view_key_card_linked_ids_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="left|start"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/view_key_card_linked_ids_add"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/menu_linked_add_identity"
|
||||
android:textColor="@color/card_view_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -22,88 +22,17 @@
|
||||
card_view:cardCornerRadius="4dp"
|
||||
/>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
<org.sufficientlysecure.keychain.ui.widget.LinkedIdentitiesCardView
|
||||
android:id="@+id/card_linked_ids"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:transitionName="card_linked_ids"
|
||||
android:visibility="gone"
|
||||
card_view:cardBackgroundColor="?attr/colorCardViewBackground"
|
||||
card_view:cardCornerRadius="4dp"
|
||||
card_view:cardElevation="2dp"
|
||||
card_view:cardUseCompatPadding="true"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/CardViewHeader"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/section_linked_identities" />
|
||||
|
||||
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
||||
android:id="@+id/view_key_linked_ids"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/view_key_linked_ids_empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/linked_empty" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/view_key_linked_ids_expander"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:drawableEnd="@drawable/ic_expand_more_black_24dp"
|
||||
android:drawablePadding="3dp"
|
||||
android:drawableRight="@drawable/ic_expand_more_black_24dp"
|
||||
android:drawableTop="@drawable/divider"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:text="@string/linked_ids_more_unknown"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/view_key_card_linked_ids_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="left|start"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/view_key_card_linked_ids_add"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/menu_linked_add_identity"
|
||||
android:textColor="@color/card_view_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
tools:visibility="visible" />
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/view_key_card_user_ids"
|
||||
|
||||
Reference in New Issue
Block a user