Cache instances of KeyInfoFormatter

This commit is contained in:
Vincent Breitmoser 2018-07-04 19:39:28 +02:00
parent a975586086
commit 75cf861674
20 changed files with 214 additions and 291 deletions

View file

@ -156,7 +156,7 @@ public class ApiPendingIntentFactory {
return createInternal(data, intent);
}
PendingIntent createSelectAuthenticationKeyIdPendingIntent(Intent data, String packageName) {
public PendingIntent createSelectAuthenticationKeyIdPendingIntent(Intent data, String packageName) {
Intent intent = new Intent(mContext, RemoteSelectAuthenticationKeyActivity.class);
intent.putExtra(RemoteSelectAuthenticationKeyActivity.EXTRA_PACKAGE_NAME, packageName);

View file

@ -89,7 +89,7 @@ public class AppSettingsAllowedKeysListFragment extends RecyclerFragment<KeyChoi
public void onLoadUnifiedKeyData(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(data, null);
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(requireContext(), data, null);
setAdapter(keyChoiceAdapter);
Set<Long> checkedIds = apiAppDao.getAllowedKeyIdsForApp(packageName);
keyChoiceAdapter.setSelectionByIds(checkedIds);

View file

@ -123,7 +123,7 @@ public class SelectPublicKeyFragment extends RecyclerFragment<KeyChoiceAdapter>
public void onLoadUnifiedKeyData(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(data, (keyInfo -> {
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(requireContext(), data, (keyInfo -> {
if (keyInfo.is_revoked()) {
return R.string.keychoice_revoked;
} else if (keyInfo.is_expired()) {

View file

@ -116,7 +116,7 @@ public class SelectSignKeyIdListFragment extends RecyclerFragment<KeyChoiceAdapt
public void onLoadUnifiedKeyData(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createSingleClickableAdapter(data, this::onSelectKeyItemClicked, (keyInfo -> {
keyChoiceAdapter = KeyChoiceAdapter.createSingleClickableAdapter(requireContext(), data, this::onSelectKeyItemClicked, (keyInfo -> {
if (keyInfo.is_revoked()) {
return R.string.keychoice_revoked;
} else if (keyInfo.is_expired()) {

View file

@ -0,0 +1,109 @@
package org.sufficientlysecure.keychain.remote.ui.dialog;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.remote.ui.dialog.DialogKeyChoiceAdapter.KeyChoiceViewHolder;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
class DialogKeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
private final LayoutInflater layoutInflater;
private List<UnifiedKeyInfo> data;
private Drawable iconUnselected;
private Drawable iconSelected;
private Integer activeItem;
private KeyInfoFormatter keyInfoFormatter;
DialogKeyChoiceAdapter(Context context, LayoutInflater layoutInflater) {
this.layoutInflater = layoutInflater;
this.keyInfoFormatter = new KeyInfoFormatter(context);
}
@NonNull
@Override
public KeyChoiceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View keyChoiceItemView = layoutInflater.inflate(R.layout.api_select_identity_item, parent, false);
return new KeyChoiceViewHolder(keyChoiceItemView);
}
void setActiveItem(Integer activeItem) {
this.activeItem = activeItem;
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(@NonNull KeyChoiceViewHolder holder, int position) {
UnifiedKeyInfo keyInfo = data.get(position);
boolean hasActiveItem = activeItem != null;
boolean isActiveItem = hasActiveItem && position == activeItem;
Drawable icon = isActiveItem ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon);
holder.itemView.setVisibility(!hasActiveItem || isActiveItem ? View.VISIBLE : View.INVISIBLE);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
public void setData(List<UnifiedKeyInfo> data) {
this.data = data;
notifyDataSetChanged();
}
void setSelectionDrawables(Drawable iconSelected, Drawable iconUnselected) {
this.iconSelected = iconSelected;
this.iconUnselected = iconUnselected;
notifyDataSetChanged();
}
class KeyChoiceViewHolder extends RecyclerView.ViewHolder {
private final TextView vName;
private final TextView vCreation = (TextView) itemView.findViewById(R.id.key_list_item_creation);
private final ImageView vIcon;
KeyChoiceViewHolder(View itemView) {
super(itemView);
vName = itemView.findViewById(R.id.key_list_item_name);
vIcon = itemView.findViewById(R.id.key_list_item_icon);
}
void bind(UnifiedKeyInfo keyInfo, Drawable selectionIcon) {
Context context = vCreation.getContext();
keyInfoFormatter.setKeyInfo(keyInfo);
String email = keyInfo.email();
String name = keyInfo.name();
if (email != null) {
vName.setText(context.getString(R.string.use_key, email));
} else if (name != null) {
vName.setText(context.getString(R.string.use_key, name));
} else {
vName.setText(context.getString(R.string.use_key_no_name));
}
keyInfoFormatter.formatCreationDate(vCreation);
vIcon.setImageDrawable(selectionIcon);
}
}
}

View file

@ -63,7 +63,7 @@ class RemoteDeduplicatePresenter {
private void onLoadKeyInfos(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createSingleChoiceAdapter(data, (keyInfo -> {
keyChoiceAdapter = KeyChoiceAdapter.createSingleChoiceAdapter(context, data, (keyInfo -> {
if (keyInfo.is_revoked()) {
return R.string.keychoice_revoked;
} else if (keyInfo.is_expired()) {

View file

@ -40,27 +40,22 @@ import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.text.format.DateUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.mikepenz.materialdrawer.util.KeyboardUtil;
import org.openintents.ssh.authentication.SshAuthenticationApi;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.daos.ApiAppDao;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.remote.ui.RemoteSecurityTokenOperationActivity;
import org.sufficientlysecure.keychain.remote.ui.dialog.RemoteSelectAuthenticationKeyPresenter.RemoteSelectAuthenticationKeyView;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener;
@ -203,7 +198,7 @@ public class RemoteSelectAuthenticationKeyActivity extends FragmentActivity {
@NonNull
private RemoteSelectAuthenticationKeyView createMvpView(View view, LayoutInflater layoutInflater) {
final ImageView iconClientApp = view.findViewById(R.id.icon_client_app);
final KeyChoiceAdapter keyChoiceAdapter = new KeyChoiceAdapter(layoutInflater, getResources());
final DialogKeyChoiceAdapter keyChoiceAdapter = new DialogKeyChoiceAdapter(requireContext(), layoutInflater);
keyChoiceList.setAdapter(keyChoiceAdapter);
return new RemoteSelectAuthenticationKeyView() {
@ -231,7 +226,14 @@ public class RemoteSelectAuthenticationKeyActivity extends FragmentActivity {
@Override
public void setTitleClientIcon(Drawable drawable) {
iconClientApp.setImageDrawable(drawable);
keyChoiceAdapter.setSelectionDrawable(drawable);
Resources resources = getResources();
ConstantState constantState = drawable.getConstantState();
Drawable iconSelected = constantState.newDrawable(resources);
Drawable iconUnselected = constantState.newDrawable(resources);
DrawableCompat.setTint(iconUnselected.mutate(), ResourcesCompat.getColor(resources, R.color.md_grey_300, null));
keyChoiceAdapter.setSelectionDrawables(iconSelected, iconUnselected);
}
@Override
@ -258,92 +260,4 @@ public class RemoteSelectAuthenticationKeyActivity extends FragmentActivity {
(view, position) -> presenter.onKeyItemClick(position)));
}
}
private static class KeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
private final LayoutInflater layoutInflater;
private final Resources resources;
private List<UnifiedKeyInfo> data;
private Drawable iconUnselected;
private Drawable iconSelected;
private Integer activeItem;
KeyChoiceAdapter(LayoutInflater layoutInflater, Resources resources) {
this.layoutInflater = layoutInflater;
this.resources = resources;
}
@NonNull
@Override
public KeyChoiceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View keyChoiceItemView = layoutInflater.inflate(R.layout.authentication_key_item, parent, false);
return new KeyChoiceViewHolder(keyChoiceItemView);
}
@Override
public void onBindViewHolder(@NonNull KeyChoiceViewHolder holder, int position) {
UnifiedKeyInfo keyInfo = data.get(position);
Drawable icon = (activeItem != null && position == activeItem) ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
public void setData(List<UnifiedKeyInfo> data) {
this.data = data;
notifyDataSetChanged();
}
void setSelectionDrawable(Drawable drawable) {
ConstantState constantState = drawable.getConstantState();
if (constantState == null) {
return;
}
iconSelected = constantState.newDrawable(resources);
iconUnselected = constantState.newDrawable(resources);
DrawableCompat.setTint(iconUnselected.mutate(), ResourcesCompat.getColor(resources, R.color.md_grey_300, null));
notifyDataSetChanged();
}
void setActiveItem(Integer newActiveItem) {
Integer prevActiveItem = this.activeItem;
this.activeItem = newActiveItem;
if (prevActiveItem != null) {
notifyItemChanged(prevActiveItem);
}
if (newActiveItem != null) {
notifyItemChanged(newActiveItem);
}
}
}
private static class KeyChoiceViewHolder extends RecyclerView.ViewHolder {
private final TextView vName;
private final TextView vCreation;
private final ImageView vIcon;
KeyChoiceViewHolder(View itemView) {
super(itemView);
vName = itemView.findViewById(R.id.key_list_item_name);
vCreation = itemView.findViewById(R.id.key_list_item_creation);
vIcon = itemView.findViewById(R.id.key_list_item_icon);
}
void bind(UnifiedKeyInfo keyInfo, Drawable selectionIcon) {
vName.setText(keyInfo.name());
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(itemView.getContext(), keyInfo, null);
keyInfoFormatter.formatCreationDate(vCreation);
vIcon.setImageDrawable(selectionIcon);
}
}
}

View file

@ -45,8 +45,6 @@ import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.text.format.DateUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
@ -60,18 +58,17 @@ import android.widget.Toast;
import com.mikepenz.materialdrawer.util.KeyboardUtil;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
import org.sufficientlysecure.keychain.livedata.PgpKeyGenerationLiveData;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.remote.ui.dialog.RemoteSelectIdentityKeyPresenter.RemoteSelectIdentityKeyView;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.MainActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.AbstractCallback;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener;
@ -246,7 +243,7 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
@NonNull
private RemoteSelectIdentityKeyView createMvpView(final ViewGroup rootView, LayoutInflater layoutInflater) {
// final ImageView iconClientApp = rootView.findViewById(R.id.icon_client_app);
final KeyChoiceAdapter keyChoiceAdapter = new KeyChoiceAdapter(layoutInflater);
final DialogKeyChoiceAdapter keyChoiceAdapter = new DialogKeyChoiceAdapter(requireContext(), layoutInflater);
final TextView titleText = rootView.findViewById(R.id.text_title_select_key);
final TextView addressText = rootView.findViewById(R.id.text_user_id);
final TextView autocryptHint = rootView.findViewById(R.id.key_import_autocrypt_hint);
@ -446,91 +443,6 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
importOpHelper.cryptoOperation();
}
private static class KeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
private final LayoutInflater layoutInflater;
private List<UnifiedKeyInfo> data;
private Drawable iconUnselected;
private Drawable iconSelected;
private Integer activeItem;
KeyChoiceAdapter(LayoutInflater layoutInflater) {
this.layoutInflater = layoutInflater;
}
@NonNull
@Override
public KeyChoiceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View keyChoiceItemView = layoutInflater.inflate(R.layout.api_select_identity_item, parent, false);
return new KeyChoiceViewHolder(keyChoiceItemView);
}
void setActiveItem(Integer activeItem) {
this.activeItem = activeItem;
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(@NonNull KeyChoiceViewHolder holder, int position) {
UnifiedKeyInfo keyInfo = data.get(position);
boolean hasActiveItem = activeItem != null;
boolean isActiveItem = hasActiveItem && position == activeItem;
Drawable icon = isActiveItem ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon);
holder.itemView.setVisibility(!hasActiveItem || isActiveItem ? View.VISIBLE : View.INVISIBLE);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
public void setData(List<UnifiedKeyInfo> data) {
this.data = data;
notifyDataSetChanged();
}
void setSelectionDrawables(Drawable iconSelected, Drawable iconUnselected) {
this.iconSelected = iconSelected;
this.iconUnselected = iconUnselected;
notifyDataSetChanged();
}
}
private static class KeyChoiceViewHolder extends RecyclerView.ViewHolder {
private final TextView vName;
private final TextView vCreation = (TextView) itemView.findViewById(R.id.key_list_item_creation);
private final ImageView vIcon;
KeyChoiceViewHolder(View itemView) {
super(itemView);
vName = itemView.findViewById(R.id.key_list_item_name);
vIcon = itemView.findViewById(R.id.key_list_item_icon);
}
void bind(UnifiedKeyInfo keyInfo, Drawable selectionIcon) {
Context context = vCreation.getContext();
String email = keyInfo.email();
String name = keyInfo.name();
if (email != null) {
vName.setText(context.getString(R.string.use_key, email));
} else if (name != null) {
vName.setText(context.getString(R.string.use_key, name));
} else {
vName.setText(context.getString(R.string.use_key_no_name));
}
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(itemView.getContext(), keyInfo, null);
keyInfoFormatter.formatCreationDate(vCreation);
vIcon.setImageDrawable(selectionIcon);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (importOpHelper.handleActivityResult(requestCode, resultCode, data)) {

View file

@ -110,6 +110,11 @@ public class DebugActionsActivity extends Activity {
new Intent(), BuildConfig.APPLICATION_ID, getPackageSig(), "test@openkeychain.org", false);
startPendingIntent(pendingIntent);
});
addButtonToLayout(context, verticalLayout, "Select Authentication Key").setOnClickListener((v) -> {
PendingIntent pendingIntent = pendingIntentFactory.createSelectAuthenticationKeyIdPendingIntent(
new Intent(), BuildConfig.APPLICATION_ID);
startPendingIntent(pendingIntent);
});
addButtonToLayout(context, verticalLayout, "Select Signing Key (Autocrypt)").setOnClickListener((v) -> {
PendingIntent pendingIntent = pendingIntentFactory.createSelectSignKeyIdPendingIntent(
new Intent(), BuildConfig.APPLICATION_ID, getPackageSig(), "test@openkeychain.org", true);

View file

@ -75,6 +75,7 @@ import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.base.RecyclerFragment;
import org.sufficientlysecure.keychain.ui.keyview.GenericViewModel;
import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.FabContainer;
@ -141,6 +142,7 @@ public class KeyListFragment extends RecyclerFragment<FlexibleAdapter<FlexibleKe
}
};
private FastScroller fastScroller;
private KeyInfoFormatter keyInfoFormatter;
private void multiSelectDelete(long[] keyIds, boolean hasSecret) {
Intent intent = new Intent(getActivity(), DeleteKeyDialogActivity.class);

View file

@ -75,6 +75,7 @@ public class FlexibleKeyDetailsItem extends FlexibleSectionableKeyItem<FlexibleK
private final TextView vCreationDate;
private final ImageView vStatusIcon;
private final ImageView vTrustIdIcon;
private final KeyInfoFormatter keyInfoFormatter;
FlexibleKeyItemViewHolder(View itemView, FlexibleAdapter adapter) {
super(itemView, adapter);
@ -84,12 +85,15 @@ public class FlexibleKeyDetailsItem extends FlexibleSectionableKeyItem<FlexibleK
vStatusIcon = itemView.findViewById(R.id.key_list_item_status_icon);
vCreationDate = itemView.findViewById(R.id.key_list_item_creation);
vTrustIdIcon = itemView.findViewById(R.id.key_list_item_tid_icon);
keyInfoFormatter = new KeyInfoFormatter(itemView.getContext());
}
public void bind(UnifiedKeyInfo keyInfo, String highlightString) {
setEnabled(true);
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(itemView.getContext(), keyInfo, highlightString);
keyInfoFormatter.setKeyInfo(keyInfo);
keyInfoFormatter.setHighlightString(highlightString);
keyInfoFormatter.formatUserId(vMainUserId, vMainUserIdRest);
keyInfoFormatter.formatCreationDate(vCreationDate);
keyInfoFormatter.greyInvalidKeys(Arrays.asList(vMainUserId, vMainUserIdRest, vCreationDate));

View file

@ -1,6 +1,13 @@
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;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.widget.RecyclerView;
@ -10,21 +17,14 @@ import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.ui.adapter.KeyChoiceAdapter.KeyChoiceItem;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
import eu.davidea.flexibleadapter.items.IFlexible;
import eu.davidea.viewholders.FlexibleViewHolder;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.ui.adapter.KeyChoiceAdapter.KeyChoiceItem;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
public class KeyChoiceAdapter extends FlexibleAdapter<KeyChoiceItem> {
@ -34,41 +34,40 @@ public class KeyChoiceAdapter extends FlexibleAdapter<KeyChoiceItem> {
private final KeyDisabledPredicate keyDisabledPredicate;
@Nullable
private Integer activeItem;
private KeyInfoFormatter keyInfoFormatter;
public static KeyChoiceAdapter createSingleClickableAdapter(List<UnifiedKeyInfo> items,
OnKeyClickListener onKeyClickListener) {
return new KeyChoiceAdapter(items, Objects.requireNonNull(onKeyClickListener), Mode.IDLE, null);
public static KeyChoiceAdapter createSingleClickableAdapter(Context context, List<UnifiedKeyInfo> items,
OnKeyClickListener onKeyClickListener,
KeyDisabledPredicate keyDisabledPredicate) {
return new KeyChoiceAdapter(context, items, Objects.requireNonNull(onKeyClickListener), Mode.IDLE,
keyDisabledPredicate
);
}
public static KeyChoiceAdapter createSingleClickableAdapter(List<UnifiedKeyInfo> items,
OnKeyClickListener onKeyClickListener,
KeyDisabledPredicate keyDisabledPredicate) {
return new KeyChoiceAdapter(items, Objects.requireNonNull(onKeyClickListener), Mode.IDLE, keyDisabledPredicate);
public static KeyChoiceAdapter createSingleChoiceAdapter(Context context, List<UnifiedKeyInfo> items,
KeyDisabledPredicate keyDisabledPredicate) {
return new KeyChoiceAdapter(context, items, null, Mode.SINGLE, keyDisabledPredicate);
}
public static KeyChoiceAdapter createSingleChoiceAdapter(List<UnifiedKeyInfo> items) {
return new KeyChoiceAdapter(items, null, Mode.SINGLE, null);
public static KeyChoiceAdapter createMultiChoiceAdapter(Context context, List<UnifiedKeyInfo> items,
KeyDisabledPredicate keyDisabledPredicate) {
return new KeyChoiceAdapter(context, items, null, Mode.MULTI, keyDisabledPredicate);
}
public static KeyChoiceAdapter createSingleChoiceAdapter(List<UnifiedKeyInfo> items, KeyDisabledPredicate keyDisabledPredicate) {
return new KeyChoiceAdapter(items, null, Mode.SINGLE, keyDisabledPredicate);
}
public static KeyChoiceAdapter createMultiChoiceAdapter(List<UnifiedKeyInfo> items, KeyDisabledPredicate keyDisabledPredicate) {
return new KeyChoiceAdapter(items, null, Mode.MULTI, keyDisabledPredicate);
}
private KeyChoiceAdapter(List<UnifiedKeyInfo> items, @Nullable OnKeyClickListener onKeyClickListener, int idle,
private KeyChoiceAdapter(Context context, List<UnifiedKeyInfo> items,
@Nullable OnKeyClickListener onKeyClickListener, int idle,
@Nullable KeyDisabledPredicate keyDisabledPredicate) {
super(getKeyChoiceItems(items, keyDisabledPredicate));
super(null, null, true);
setMode(idle);
addListener((OnItemClickListener) (view, position) -> onClickItem(position));
updateDataSet(getKeyChoiceItems(items, keyDisabledPredicate), false);
this.keyInfoFormatter = new KeyInfoFormatter(context);
this.onKeyClickListener = onKeyClickListener;
this.keyDisabledPredicate = keyDisabledPredicate;
}
@Nullable
private static ArrayList<KeyChoiceItem> getKeyChoiceItems(@Nullable List<UnifiedKeyInfo> items,
private ArrayList<KeyChoiceItem> getKeyChoiceItems(@Nullable List<UnifiedKeyInfo> items,
@Nullable KeyDisabledPredicate keyDisabledPredicate) {
if (items == null) {
return null;
@ -174,7 +173,7 @@ public class KeyChoiceAdapter extends FlexibleAdapter<KeyChoiceItem> {
return result;
}
public static class KeyChoiceItem extends AbstractFlexibleItem<KeyChoiceViewHolder> {
public class KeyChoiceItem extends AbstractFlexibleItem<KeyChoiceViewHolder> {
private UnifiedKeyInfo keyInfo;
@StringRes
private Integer disabledStringRes;
@ -220,7 +219,7 @@ public class KeyChoiceAdapter extends FlexibleAdapter<KeyChoiceItem> {
}
}
public static class KeyChoiceViewHolder extends FlexibleViewHolder {
public class KeyChoiceViewHolder extends FlexibleViewHolder {
private final TextView vName;
private final TextView vCreation;
private final CheckBox vCheckbox;
@ -236,9 +235,10 @@ public class KeyChoiceAdapter extends FlexibleAdapter<KeyChoiceItem> {
}
void bind(UnifiedKeyInfo keyInfo, int choiceMode, boolean isActive, boolean isEnabled) {
keyInfoFormatter.setKeyInfo(keyInfo);
vName.setText(keyInfo.user_id());
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(itemView.getContext(), keyInfo, null);
keyInfoFormatter.formatCreationDate(vCreation);
switch (choiceMode) {

View file

@ -31,7 +31,8 @@ public class ImportKeysBindingsUtils {
public static Highlighter getHighlighter(Context context, String query) {
Highlighter highlighter = highlighterCache.get(query);
if (highlighter == null) {
highlighter = new Highlighter(context, query);
highlighter = new Highlighter(context);
highlighter.setQuery(query);
highlighterCache.put(query, highlighter);
}

View file

@ -21,11 +21,13 @@ import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
public class EncryptRecipientDropdownAdapter extends ChipsInput.ChipDropdownAdapter<EncryptRecipientChip, ItemViewHolder> {
private final LayoutInflater layoutInflater;
private final KeyInfoFormatter keyInfoFormatter;
EncryptRecipientDropdownAdapter(Context context, List<EncryptRecipientChip> keyInfoChips) {
super(keyInfoChips);
layoutInflater = LayoutInflater.from(context);
keyInfoFormatter = new KeyInfoFormatter(context);
}
class ItemViewHolder extends RecyclerView.ViewHolder {
@ -42,6 +44,14 @@ public class EncryptRecipientDropdownAdapter extends ChipsInput.ChipDropdownAdap
vStatusIcon = itemView.findViewById(R.id.key_list_item_status_icon);
vCreationDate = itemView.findViewById(R.id.key_list_item_creation);
}
public void bind(EncryptRecipientChip chip) {
keyInfoFormatter.setKeyInfo(chip.keyInfo);
keyInfoFormatter.formatUserId(vMainUserId, vMainUserIdRest);
keyInfoFormatter.formatCreationDate(vCreationDate);
keyInfoFormatter.formatStatusIcon(vStatusIcon);
}
}
@NonNull
@ -54,10 +64,6 @@ public class EncryptRecipientDropdownAdapter extends ChipsInput.ChipDropdownAdap
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
EncryptRecipientChip chip = getItem(position);
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(layoutInflater.getContext(), chip.keyInfo, null);
keyInfoFormatter.formatUserId(holder.vMainUserId, holder.vMainUserIdRest);
keyInfoFormatter.formatCreationDate(holder.vCreationDate);
keyInfoFormatter.formatStatusIcon(holder.vStatusIcon);
holder.bind(chip);
}
}

View file

@ -30,9 +30,12 @@ public class Highlighter {
private Context mContext;
private String mQuery;
public Highlighter(Context context, String query) {
public Highlighter(Context context) {
mContext = context;
mQuery = query;
}
public void setQuery(String mQuery) {
this.mQuery = mQuery;
}
public Spannable highlight(CharSequence text) {

View file

@ -11,6 +11,7 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.SubKey;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import java.util.List;
@ -19,13 +20,20 @@ public class KeyInfoFormatter {
private static final long JUST_NOW_THRESHOLD = DateUtils.MINUTE_IN_MILLIS * 5;
private Context context;
private SubKey.UnifiedKeyInfo keyInfo;
private Highlighter highlighter;
private UnifiedKeyInfo keyInfo;
public KeyInfoFormatter(Context context, SubKey.UnifiedKeyInfo keyInfo, String highlightString) {
public KeyInfoFormatter(Context context) {
this.context = context;
highlighter = new Highlighter(context);
}
public void setKeyInfo(UnifiedKeyInfo keyInfo) {
this.keyInfo = keyInfo;
highlighter = new Highlighter(context, highlightString);
}
public void setHighlightString(String highlight) {
highlighter.setQuery(highlight);
}
public void formatUserId(TextView name, TextView email) {

View file

@ -19,14 +19,17 @@ import java.util.List;
class KeyChoiceSpinnerAdapter extends BaseAdapter {
private final LayoutInflater layoutInflater;
private final KeyInfoFormatter keyInfoFormatter;
private Integer noneItemString;
private List<UnifiedKeyInfo> data;
private final LayoutInflater layoutInflater;
KeyChoiceSpinnerAdapter(Context context) {
super();
layoutInflater = LayoutInflater.from(context);
keyInfoFormatter = new KeyInfoFormatter(context);
}
public void setData(List<UnifiedKeyInfo> data) {
@ -114,28 +117,26 @@ class KeyChoiceSpinnerAdapter extends BaseAdapter {
}
UnifiedKeyInfo keyInfo = getItem(position);
viewHolder.bind(view.getContext(), keyInfo, isEnabled(position));
viewHolder.bind(keyInfo, isEnabled(position));
return view;
}
public static class KeyChoiceViewHolder {
private View mView;
public class KeyChoiceViewHolder {
private TextView mMainUserId;
private TextView mMainUserIdRest;
private TextView mCreationDate;
private ImageView mStatus;
KeyChoiceViewHolder(View view) {
mView = view;
mMainUserId = view.findViewById(R.id.key_list_item_name);
mMainUserIdRest = view.findViewById(R.id.key_list_item_email);
mStatus = view.findViewById(R.id.key_list_item_status_icon);
mCreationDate = view.findViewById(R.id.key_list_item_creation);
}
public void bind(Context context, UnifiedKeyInfo keyInfo, boolean enabled) {
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(context, keyInfo, null);
public void bind(UnifiedKeyInfo keyInfo, boolean enabled) {
keyInfoFormatter.setKeyInfo(keyInfo);
keyInfoFormatter.formatUserId(mMainUserId, mMainUserIdRest);
keyInfoFormatter.formatCreationDate(mCreationDate);
keyInfoFormatter.formatStatusIcon(mStatus);

View file

@ -85,7 +85,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/authentication_key_list"
tools:listitem="@layout/authentication_key_item"
tools:listitem="@layout/key_choice_item"
tools:layout_height="100dp"
/>

View file

@ -1,44 +0,0 @@
<?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:paddingTop="6dp"
android:paddingBottom="6dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:id="@+id/key_list_item_icon"
tools:tint="@color/md_grey_600"
tools:src="@drawable/apps_k9"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/key_list_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/label_main_user_id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/key_list_item_creation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:visibility="visible"
tools:text="Created on 10/10/2010 10:00" />
</LinearLayout>
</LinearLayout>

View file

@ -6,7 +6,9 @@
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:gravity="center_vertical"
android:orientation="horizontal">
android:orientation="horizontal"
android:background="?selectableItemBackground"
android:minHeight="?listPreferredItemHeight">
<RadioButton
android:id="@+id/radio_keychoice"