add context menu to autocrypt identity items
This commit is contained in:
parent
dc33fc7982
commit
226182e51c
|
@ -149,4 +149,8 @@ public class AutocryptPeerDataAccessObject {
|
|||
cv.put(ApiAutocryptPeer.STATE, status);
|
||||
mQueryInterface.update(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId), cv, null, null);
|
||||
}
|
||||
|
||||
public void delete(String autocryptId) {
|
||||
mQueryInterface.delete(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId), null, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -932,6 +932,25 @@ public class KeychainProvider extends ContentProvider {
|
|||
break;
|
||||
}
|
||||
|
||||
case AUTOCRYPT_PEERS_BY_PACKAGE_NAME_AND_TRUST_ID: {
|
||||
String packageName = uri.getPathSegments().get(2);
|
||||
String autocryptPeer = uri.getPathSegments().get(3);
|
||||
|
||||
String selection = ApiAutocryptPeer.PACKAGE_NAME + " = ? AND " + ApiAutocryptPeer.IDENTIFIER + " = ?";
|
||||
selectionArgs = new String[] { packageName, autocryptPeer };
|
||||
|
||||
Cursor cursor = db.query(Tables.API_AUTOCRYPT_PEERS, new String[] { ApiAutocryptPeer.MASTER_KEY_ID },
|
||||
selection, selectionArgs, null, null, null);
|
||||
Long masterKeyId = null;
|
||||
if (cursor != null && cursor.moveToNext() && !cursor.isNull(0)) {
|
||||
masterKeyId = cursor.getLong(0);
|
||||
}
|
||||
|
||||
count = db.delete(Tables.API_AUTOCRYPT_PEERS, selection, selectionArgs);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AUTOCRYPT_PEERS_BY_MASTER_KEY_ID:
|
||||
String selection = ApiAutocryptPeer.MASTER_KEY_ID + " = " + uri.getLastPathSegment();
|
||||
if (!TextUtils.isEmpty(additionalSelection)) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.os.Build.VERSION_CODES;
|
|||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
@ -53,15 +54,17 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
private final Context context;
|
||||
private final LayoutInflater layoutInflater;
|
||||
private final boolean isSecret;
|
||||
private final IdentityClickListener identityClickListener;
|
||||
|
||||
private List<IdentityInfo> data;
|
||||
|
||||
|
||||
public IdentityAdapter(Context context, boolean isSecret) {
|
||||
public IdentityAdapter(Context context, boolean isSecret, IdentityClickListener identityClickListener) {
|
||||
super();
|
||||
this.layoutInflater = LayoutInflater.from(context);
|
||||
this.context = context;
|
||||
this.isSecret = isSecret;
|
||||
this.identityClickListener = identityClickListener;
|
||||
}
|
||||
|
||||
public void setData(List<IdentityInfo> data) {
|
||||
|
@ -91,7 +94,8 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (viewType == VIEW_TYPE_USER_ID) {
|
||||
return new UserIdViewHolder(layoutInflater.inflate(R.layout.view_key_identity_user_id, parent, false));
|
||||
return new UserIdViewHolder(
|
||||
layoutInflater.inflate(R.layout.view_key_identity_user_id, parent, false), identityClickListener);
|
||||
} else if (viewType == VIEW_TYPE_LINKED_ID) {
|
||||
return new LinkedIdViewHolder(layoutInflater.inflate(R.layout.linked_id_item, parent, false));
|
||||
} else {
|
||||
|
@ -195,9 +199,9 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
private final TextView vAddress;
|
||||
private final TextView vComment;
|
||||
private final ImageView vIcon;
|
||||
private final ImageView vTrustIdAction;
|
||||
private final ImageView vMore;
|
||||
|
||||
private UserIdViewHolder(View view) {
|
||||
private UserIdViewHolder(View view, final IdentityClickListener identityClickListener) {
|
||||
super(view);
|
||||
|
||||
vName = (TextView) view.findViewById(R.id.user_id_item_name);
|
||||
|
@ -205,7 +209,21 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
vComment = (TextView) view.findViewById(R.id.user_id_item_comment);
|
||||
|
||||
vIcon = (ImageView) view.findViewById(R.id.trust_id_app_icon);
|
||||
vTrustIdAction = (ImageView) view.findViewById(R.id.trust_id_action);
|
||||
vMore = (ImageView) view.findViewById(R.id.user_id_item_more);
|
||||
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
identityClickListener.onClickIdentity(getAdapterPosition());
|
||||
}
|
||||
});
|
||||
|
||||
vMore.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
identityClickListener.onClickIdentityMore(getAdapterPosition(), v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void bind(TrustIdInfo info) {
|
||||
|
@ -220,16 +238,16 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
}
|
||||
|
||||
vIcon.setImageDrawable(info.getAppIcon());
|
||||
if (info.getTrustIdIntent() != null) {
|
||||
vTrustIdAction.setVisibility(View.VISIBLE);
|
||||
}
|
||||
vMore.setVisibility(View.VISIBLE);
|
||||
|
||||
itemView.setClickable(info.getTrustIdIntent() != null);
|
||||
}
|
||||
|
||||
public void bind(UserIdInfo info) {
|
||||
bindUserIdInfo(info);
|
||||
|
||||
vIcon.setVisibility(View.GONE);
|
||||
vTrustIdAction.setVisibility(View.GONE);
|
||||
vMore.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void bindUserIdInfo(UserIdInfo info) {
|
||||
|
@ -261,4 +279,9 @@ public class IdentityAdapter extends RecyclerView.Adapter<ViewHolder> {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IdentityClickListener {
|
||||
void onClickIdentity(int position);
|
||||
void onClickIdentityMore(int position, View anchor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,11 @@ import android.os.Handler;
|
|||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.support.v7.widget.PopupMenu.OnDismissListener;
|
||||
import android.support.v7.widget.PopupMenu.OnMenuItemClickListener;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
|
@ -44,7 +48,7 @@ import org.sufficientlysecure.keychain.ui.keyview.view.KeyserverStatusView;
|
|||
import org.sufficientlysecure.keychain.ui.keyview.view.SystemContactCardView;
|
||||
|
||||
|
||||
public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView {
|
||||
public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView, OnMenuItemClickListener {
|
||||
public static final String ARG_MASTER_KEY_ID = "master_key_id";
|
||||
public static final String ARG_IS_SECRET = "is_secret";
|
||||
|
||||
|
@ -67,6 +71,8 @@ public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView {
|
|||
KeyHealthPresenter mKeyHealthPresenter;
|
||||
KeyserverStatusPresenter mKeyserverStatusPresenter;
|
||||
|
||||
private Integer displayedContextMenuPosition;
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
*/
|
||||
|
@ -161,4 +167,37 @@ public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showContextMenu(int position, View anchor) {
|
||||
displayedContextMenuPosition = position;
|
||||
|
||||
PopupMenu menu = new PopupMenu(getContext(), anchor);
|
||||
menu.inflate(R.menu.identity_context_menu);
|
||||
menu.setOnMenuItemClickListener(this);
|
||||
menu.setOnDismissListener(new OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(PopupMenu popupMenu) {
|
||||
displayedContextMenuPosition = null;
|
||||
}
|
||||
});
|
||||
menu.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (displayedContextMenuPosition == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.autocrypt_forget:
|
||||
int position = displayedContextMenuPosition;
|
||||
displayedContextMenuPosition = null;
|
||||
mIdentitiesPresenter.onClickForgetIdentity(position);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,10 +134,10 @@ public class IdentityLoader extends AsyncTaskLoader<List<IdentityInfo>> {
|
|||
UserIdInfo associatedUserIdInfo = findUserIdMatchingTrustId(identities, autocryptPeer);
|
||||
if (associatedUserIdInfo != null) {
|
||||
int position = identities.indexOf(associatedUserIdInfo);
|
||||
TrustIdInfo autocryptPeerInfo = TrustIdInfo.create(associatedUserIdInfo, autocryptPeer, drawable, autocryptPeerIntent);
|
||||
TrustIdInfo autocryptPeerInfo = TrustIdInfo.create(associatedUserIdInfo, autocryptPeer, packageName, drawable, autocryptPeerIntent);
|
||||
identities.set(position, autocryptPeerInfo);
|
||||
} else {
|
||||
TrustIdInfo autocryptPeerInfo = TrustIdInfo.create(autocryptPeer, drawable, autocryptPeerIntent);
|
||||
TrustIdInfo autocryptPeerInfo = TrustIdInfo.create(autocryptPeer, packageName, drawable, autocryptPeerIntent);
|
||||
identities.add(autocryptPeerInfo);
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +305,7 @@ public class IdentityLoader extends AsyncTaskLoader<List<IdentityInfo>> {
|
|||
public abstract boolean isPrimary();
|
||||
|
||||
public abstract String getTrustId();
|
||||
public abstract String getPackageName();
|
||||
@Nullable
|
||||
public abstract Drawable getAppIcon();
|
||||
@Nullable
|
||||
|
@ -312,14 +313,15 @@ public class IdentityLoader extends AsyncTaskLoader<List<IdentityInfo>> {
|
|||
@Nullable
|
||||
public abstract Intent getTrustIdIntent();
|
||||
|
||||
static TrustIdInfo create(UserIdInfo userIdInfo, String autocryptPeer, Drawable appIcon, Intent autocryptPeerIntent) {
|
||||
static TrustIdInfo create(UserIdInfo userIdInfo, String autocryptPeer, String packageName,
|
||||
Drawable appIcon, Intent autocryptPeerIntent) {
|
||||
return new AutoValue_IdentityLoader_TrustIdInfo(userIdInfo.getRank(), userIdInfo.getVerified(),
|
||||
userIdInfo.isPrimary(), autocryptPeer, appIcon, userIdInfo, autocryptPeerIntent);
|
||||
userIdInfo.isPrimary(), autocryptPeer, packageName, appIcon, userIdInfo, autocryptPeerIntent);
|
||||
}
|
||||
|
||||
static TrustIdInfo create(String autocryptPeer, Drawable appIcon, Intent autocryptPeerIntent) {
|
||||
static TrustIdInfo create(String autocryptPeer, String packageName, Drawable appIcon, Intent autocryptPeerIntent) {
|
||||
return new AutoValue_IdentityLoader_TrustIdInfo(
|
||||
0, Certs.VERIFIED_SELF, false, autocryptPeer, appIcon, null, autocryptPeerIntent);
|
||||
0, Certs.VERIFIED_SELF, false, autocryptPeer, packageName, appIcon, null, autocryptPeerIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,16 @@ import android.os.Bundle;
|
|||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.View;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.provider.AutocryptPeerDataAccessObject;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.ui.EditIdentitiesActivity;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter.IdentityClickListener;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.LinkedIdViewFragment;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityLoader;
|
||||
|
@ -68,17 +71,23 @@ public class IdentitiesPresenter implements LoaderCallbacks<List<IdentityInfo>>
|
|||
this.masterKeyId = masterKeyId;
|
||||
this.isSecret = isSecret;
|
||||
|
||||
identitiesAdapter = new IdentityAdapter(context, isSecret);
|
||||
identitiesAdapter = new IdentityAdapter(context, isSecret, new IdentityClickListener() {
|
||||
@Override
|
||||
public void onClickIdentity(int position) {
|
||||
showIdentityInfo(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickIdentityMore(int position, View anchor) {
|
||||
showIdentityContextMenu(position, anchor);
|
||||
|
||||
}
|
||||
});
|
||||
view.setIdentitiesAdapter(identitiesAdapter);
|
||||
|
||||
view.setEditIdentitiesButtonVisible(isSecret);
|
||||
|
||||
view.setIdentitiesCardListener(new IdentitiesCardListener() {
|
||||
@Override
|
||||
public void onIdentityItemClick(int position) {
|
||||
showIdentityInfo(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickEditIdentities() {
|
||||
editIdentities();
|
||||
|
@ -120,10 +129,16 @@ public class IdentitiesPresenter implements LoaderCallbacks<List<IdentityInfo>>
|
|||
showUserIdInfo((UserIdInfo) info);
|
||||
} else if (info instanceof TrustIdInfo) {
|
||||
Intent autocryptPeerIntent = ((TrustIdInfo) info).getTrustIdIntent();
|
||||
viewKeyMvpView.startActivity(autocryptPeerIntent);
|
||||
if (autocryptPeerIntent != null) {
|
||||
viewKeyMvpView.startActivity(autocryptPeerIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showIdentityContextMenu(int position, View anchor) {
|
||||
viewKeyMvpView.showContextMenu(position, anchor);
|
||||
}
|
||||
|
||||
private void showLinkedId(final LinkedIdInfo info) {
|
||||
final LinkedIdViewFragment frag;
|
||||
try {
|
||||
|
@ -158,6 +173,18 @@ public class IdentitiesPresenter implements LoaderCallbacks<List<IdentityInfo>>
|
|||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public void onClickForgetIdentity(int position) {
|
||||
TrustIdInfo info = (TrustIdInfo) identitiesAdapter.getInfo(position);
|
||||
if (info == null) {
|
||||
Log.e(Constants.TAG, "got a 'forget' click on a bad trust id");
|
||||
return;
|
||||
}
|
||||
|
||||
AutocryptPeerDataAccessObject autocryptPeerDao =
|
||||
new AutocryptPeerDataAccessObject(context, info.getPackageName());
|
||||
autocryptPeerDao.delete(info.getTrustId());
|
||||
}
|
||||
|
||||
public interface IdentitiesMvpView {
|
||||
void setIdentitiesAdapter(IdentityAdapter userIdsAdapter);
|
||||
void setIdentitiesCardListener(IdentitiesCardListener identitiesCardListener);
|
||||
|
@ -165,8 +192,6 @@ public class IdentitiesPresenter implements LoaderCallbacks<List<IdentityInfo>>
|
|||
}
|
||||
|
||||
public interface IdentitiesCardListener {
|
||||
void onIdentityItemClick(int position);
|
||||
|
||||
void onClickEditIdentities();
|
||||
void onClickAddIdentity();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package org.sufficientlysecure.keychain.ui.keyview.presenter;
|
|||
import android.content.Intent;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
public interface ViewKeyMvpView {
|
||||
|
@ -13,4 +14,6 @@ public interface ViewKeyMvpView {
|
|||
void startActivityAndShowResultSnackbar(Intent intent);
|
||||
void showDialogFragment(DialogFragment dialogFragment, final String tag);
|
||||
void setContentShown(boolean show, boolean animate);
|
||||
|
||||
void showContextMenu(int position, View anchor);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter;
|
|||
import org.sufficientlysecure.keychain.ui.keyview.presenter.IdentitiesPresenter.IdentitiesCardListener;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.presenter.IdentitiesPresenter.IdentitiesMvpView;
|
||||
import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
|
||||
import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener;
|
||||
|
||||
|
||||
public class IdentitiesCardView extends CardView implements IdentitiesMvpView {
|
||||
|
@ -59,16 +58,6 @@ public class IdentitiesCardView extends CardView implements IdentitiesMvpView {
|
|||
}
|
||||
});
|
||||
|
||||
vIdentities.addOnItemTouchListener(new RecyclerItemClickListener(context,
|
||||
new RecyclerItemClickListener.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int position) {
|
||||
if (identitiesCardListener != null) {
|
||||
identitiesCardListener.onIdentityItemClick(position);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Button linkedIdsAddButton = (Button) view.findViewById(R.id.view_key_card_linked_ids_add);
|
||||
|
||||
linkedIdsAddButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
|
|
@ -53,9 +53,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:padding="8dp"
|
||||
android:id="@+id/trust_id_action"
|
||||
android:id="@+id/user_id_item_more"
|
||||
android:background="?selectableItemBackground"
|
||||
android:src="@drawable/ic_chat_black_24dp"
|
||||
android:src="@drawable/ic_more_vert_black_24dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:padding="8dp"
|
||||
android:id="@+id/trust_id_action"
|
||||
android:id="@+id/user_id_item_more"
|
||||
android:background="?selectableItemBackground"
|
||||
android:src="@drawable/ic_chat_black_24dp"
|
||||
android:visibility="gone"
|
||||
|
|
10
OpenKeychain/src/main/res/menu/identity_context_menu.xml
Normal file
10
OpenKeychain/src/main/res/menu/identity_context_menu.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/autocrypt_forget"
|
||||
android:title="@string/identity_context_forget"
|
||||
android:icon="@drawable/ic_delete_grey_24dp"
|
||||
/>
|
||||
|
||||
</menu>
|
|
@ -1886,4 +1886,6 @@
|
|||
<string name="dialog_insecure_button_view_key">View Key</string>
|
||||
<string name="dialog_insecure_button_ok">Got it</string>
|
||||
|
||||
<string name="identity_context_forget">Forget</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue