Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 20d96ae7 authored by Vincent Breitmoser's avatar Vincent Breitmoser Committed by GitHub
Browse files

Simplify crypto info in message view (#3067)

* Simplify crypto info in message view

* incorporate feedback

* Use lowercase end-to-end

* Use signer/sender as button label, get rid of e2e string repetition
parent d0c8cc3b
Loading
Loading
Loading
Loading
+22 −103
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;

@@ -29,22 +27,11 @@ import com.fsck.k9.view.ThemeUtils;
public class CryptoInfoDialog extends DialogFragment {
    public static final String ARG_DISPLAY_STATUS = "display_status";
    public static final String ARG_HAS_SECURITY_WARNING = "has_security_warning";
    public static final int ICON_ANIM_DELAY = 400;
    public static final int ICON_ANIM_DURATION = 350;


    private View dialogView;

    private View topIconFrame;
    private ImageView topIcon_1;
    private ImageView topIcon_2;
    private ImageView topIcon_3;
    private TextView topText;

    private View bottomIconFrame;
    private ImageView bottomIcon_1;
    private ImageView bottomIcon_2;
    private TextView bottomText;
    private ImageView statusIcon;
    private TextView titleText;
    private TextView descriptionText;


    public static CryptoInfoDialog newInstance(MessageCryptoDisplayStatus displayStatus, boolean hasSecurityWarning) {
@@ -63,18 +50,11 @@ public class CryptoInfoDialog extends DialogFragment {
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Builder b = new AlertDialog.Builder(getActivity());

        dialogView = LayoutInflater.from(getActivity()).inflate(R.layout.message_crypto_info_dialog, null);

        topIconFrame = dialogView.findViewById(R.id.crypto_info_top_frame);
        topIcon_1 = (ImageView) topIconFrame.findViewById(R.id.crypto_info_top_icon_1);
        topIcon_2 = (ImageView) topIconFrame.findViewById(R.id.crypto_info_top_icon_2);
        topIcon_3 = (ImageView) topIconFrame.findViewById(R.id.crypto_info_top_icon_3);
        topText = (TextView) dialogView.findViewById(R.id.crypto_info_top_text);
        View dialogView = LayoutInflater.from(getActivity()).inflate(R.layout.message_crypto_info_dialog, null);

        bottomIconFrame = dialogView.findViewById(R.id.crypto_info_bottom_frame);
        bottomIcon_1 = (ImageView) bottomIconFrame.findViewById(R.id.crypto_info_bottom_icon_1);
        bottomIcon_2 = (ImageView) bottomIconFrame.findViewById(R.id.crypto_info_bottom_icon_2);
        bottomText = (TextView) dialogView.findViewById(R.id.crypto_info_bottom_text);
        statusIcon = (ImageView) dialogView.findViewById(R.id.crypto_info_top_icon_1);
        titleText = (TextView) dialogView.findViewById(R.id.crypto_info_title);
        descriptionText = (TextView) dialogView.findViewById(R.id.crypto_info_text);

        MessageCryptoDisplayStatus displayStatus =
                MessageCryptoDisplayStatus.valueOf(getArguments().getString(ARG_DISPLAY_STATUS));
@@ -100,7 +80,9 @@ public class CryptoInfoDialog extends DialogFragment {
                }
            });
        } else if (displayStatus.hasAssociatedKey()) {
            b.setNeutralButton(R.string.crypto_info_view_key, new OnClickListener() {
            int buttonLabel = displayStatus.isUnencryptedSigned() ?
                    R.string.crypto_info_view_signer : R.string.crypto_info_view_sender;
            b.setNeutralButton(buttonLabel, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    Fragment frag = getTargetFragment();
@@ -116,90 +98,27 @@ public class CryptoInfoDialog extends DialogFragment {
    }

    private void setMessageForDisplayStatus(MessageCryptoDisplayStatus displayStatus) {
        if (displayStatus.textResTop == null) {
        if (displayStatus.titleTextRes == null) {
            throw new AssertionError("Crypto info dialog can only be displayed for items with text!");
        }

        if (displayStatus.textResBottom == null) {
            setMessageSingleLine(displayStatus.colorAttr,
                    displayStatus.textResTop, displayStatus.statusIconRes,
                    displayStatus.statusDotsRes);
        } else {
            if (displayStatus.statusDotsRes == null) {
                throw new AssertionError("second icon must be non-null if second text is non-null!");
            }
            setMessageWithAnimation(displayStatus.colorAttr,
                    displayStatus.textResTop, displayStatus.statusIconRes,
                    displayStatus.textResBottom, displayStatus.statusDotsRes);
        }
        setMessageSingleLine(displayStatus.colorAttr, displayStatus.titleTextRes, displayStatus.descriptionTextRes,
                displayStatus.statusIconRes);
    }

    private void setMessageSingleLine(@AttrRes int colorAttr,
            @StringRes int topTextRes, @DrawableRes int statusIconRes,
            @DrawableRes Integer statusDotsRes) {
    private void setMessageSingleLine(@AttrRes int colorAttr, @StringRes int titleTextRes,
            @StringRes Integer descTextRes, @DrawableRes int statusIconRes) {
        @ColorInt int color = ThemeUtils.getStyledColor(getActivity(), colorAttr);

        topIcon_1.setImageResource(statusIconRes);
        topIcon_1.setColorFilter(color);
        topText.setText(topTextRes);

        if (statusDotsRes != null) {
            topIcon_3.setImageResource(statusDotsRes);
            topIcon_3.setColorFilter(color);
            topIcon_3.setVisibility(View.VISIBLE);
        statusIcon.setImageResource(statusIconRes);
        statusIcon.setColorFilter(color);
        titleText.setText(titleTextRes);
        if (descTextRes != null) {
            descriptionText.setText(descTextRes);
            descriptionText.setVisibility(View.VISIBLE);
        } else {
            topIcon_3.setVisibility(View.GONE);
            descriptionText.setVisibility(View.GONE);
        }

        bottomText.setVisibility(View.GONE);
        bottomIconFrame.setVisibility(View.GONE);
    }

    private void setMessageWithAnimation(@AttrRes int colorAttr,
            @StringRes int topTextRes, @DrawableRes int statusIconRes,
            @StringRes int bottomTextRes, @DrawableRes int statusDotsRes) {
        topIcon_1.setImageResource(statusIconRes);
        topIcon_2.setImageResource(statusDotsRes);
        topIcon_3.setVisibility(View.GONE);
        topText.setText(topTextRes);

        bottomIcon_1.setImageResource(statusIconRes);
        bottomIcon_2.setImageResource(statusDotsRes);
        bottomText.setText(bottomTextRes);

        topIcon_1.setColorFilter(ThemeUtils.getStyledColor(getActivity(), colorAttr));
        bottomIcon_2.setColorFilter(ThemeUtils.getStyledColor(getActivity(), colorAttr));

        prepareIconAnimation();
    }

    private void prepareIconAnimation() {
        topText.setAlpha(0.0f);
        bottomText.setAlpha(0.0f);

        dialogView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
                float halfVerticalPixelDifference = (bottomIconFrame.getY() - topIconFrame.getY()) / 2.0f;
                topIconFrame.setTranslationY(halfVerticalPixelDifference);
                bottomIconFrame.setTranslationY(-halfVerticalPixelDifference);

                topIconFrame.animate().translationY(0)
                        .setStartDelay(ICON_ANIM_DELAY)
                        .setDuration(ICON_ANIM_DURATION)
                        .setInterpolator(new AccelerateDecelerateInterpolator())
                        .start();
                bottomIconFrame.animate().translationY(0)
                        .setStartDelay(ICON_ANIM_DELAY)
                        .setDuration(ICON_ANIM_DURATION)
                        .setInterpolator(new AccelerateDecelerateInterpolator())
                        .start();
                topText.animate().alpha(1.0f).setStartDelay(ICON_ANIM_DELAY + ICON_ANIM_DURATION).start();
                bottomText.animate().alpha(1.0f).setStartDelay(ICON_ANIM_DELAY + ICON_ANIM_DURATION).start();

                view.removeOnLayoutChangeListener(this);
            }
        });
    }

    public interface OnClickShowCryptoKeyListener {
+2 −60
Original line number Diff line number Diff line
@@ -11,17 +11,16 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;

import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.mailstore.CryptoResultAnnotation;
import com.fsck.k9.mailstore.MessageViewInfo;
import com.fsck.k9.view.MessageCryptoDisplayStatus;
import timber.log.Timber;


@SuppressWarnings("WeakerAccess")
public class MessageCryptoPresenter implements OnCryptoClickListener {
    public static final int REQUEST_CODE_UNKNOWN_KEY = 123;
    public static final int REQUEST_CODE_SECURITY_WARNING = 124;
@@ -80,36 +79,6 @@ public class MessageCryptoPresenter implements OnCryptoClickListener {
        messageView.getMessageHeaderView().setCryptoStatus(displayStatus);

        switch (displayStatus) {
            case UNENCRYPTED_SIGN_REVOKED:
            case ENCRYPTED_SIGN_REVOKED: {
                showMessageCryptoWarning(messageView, account, messageViewInfo,
                        R.string.messageview_crypto_warning_revoked);
                break;
            }
            case UNENCRYPTED_SIGN_EXPIRED:
            case ENCRYPTED_SIGN_EXPIRED: {
                showMessageCryptoWarning(messageView, account, messageViewInfo,
                        R.string.messageview_crypto_warning_expired);
                break;
            }
            case UNENCRYPTED_SIGN_INSECURE:
            case ENCRYPTED_SIGN_INSECURE: {
                showMessageCryptoWarning(messageView, account, messageViewInfo,
                        R.string.messageview_crypto_warning_insecure);
                break;
            }
            case UNENCRYPTED_SIGN_ERROR:
            case ENCRYPTED_SIGN_ERROR: {
                showMessageCryptoWarning(messageView, account, messageViewInfo,
                        R.string.messageview_crypto_warning_error);
                break;
            }
            case ENCRYPTED_UNSIGNED: {
                showMessageCryptoWarning(messageView, account, messageViewInfo,
                        R.string.messageview_crypto_warning_unsigned);
                break;
            }

            case CANCELLED: {
                Drawable providerIcon = getOpenPgpApiProviderIcon(messageView.getContext());
                messageView.showMessageCryptoCancelledView(messageViewInfo, providerIcon);
@@ -123,15 +92,9 @@ public class MessageCryptoPresenter implements OnCryptoClickListener {
            }

            case ENCRYPTED_ERROR:
            case ENCRYPTED_INSECURE:
            case UNSUPPORTED_ENCRYPTED: {
                Drawable providerIcon = getOpenPgpApiProviderIcon(messageView.getContext());
                if (messageViewInfo.cryptoResultAnnotation.hasReplacementData()) {
                    showMessageCryptoWarning(messageView, account, messageViewInfo,
                            R.string.messageview_crypto_warning_insecure);
                } else {
                messageView.showMessageCryptoErrorView(messageViewInfo, providerIcon);
                }
                break;
            }

@@ -155,17 +118,6 @@ public class MessageCryptoPresenter implements OnCryptoClickListener {
        return true;
    }

    private void showMessageCryptoWarning(MessageTopView messageView, Account account,
            MessageViewInfo messageViewInfo, @StringRes int warningStringRes) {
        if (overrideCryptoWarning) {
            messageView.showMessage(account, messageViewInfo);
            return;
        }
        Drawable providerIcon = getOpenPgpApiProviderIcon(messageView.getContext());
        boolean showDetailButton = cryptoResultAnnotation.hasOpenPgpInsecureWarningPendingIntent();
        messageView.showMessageCryptoWarning(messageViewInfo, providerIcon, warningStringRes, showDetailButton);
    }

    @Override
    public void onCryptoClick() {
        if (cryptoResultAnnotation == null) {
@@ -195,11 +147,6 @@ public class MessageCryptoPresenter implements OnCryptoClickListener {

            messageCryptoMvpView.restartMessageCryptoProcessing();
        } else if (requestCode == REQUEST_CODE_SECURITY_WARNING) {
            if (overrideCryptoWarning || resultCode != Activity.RESULT_OK) {
                return;
            }

            overrideCryptoWarning = true;
            messageCryptoMvpView.redisplayMessage();
        } else {
            throw new IllegalStateException("got an activity result that wasn't meant for us. this is a bug!");
@@ -239,11 +186,6 @@ public class MessageCryptoPresenter implements OnCryptoClickListener {
        messageCryptoMvpView.restartMessageCryptoProcessing();
    }

    public void onClickShowMessageOverrideWarning() {
        overrideCryptoWarning = true;
        messageCryptoMvpView.redisplayMessage();
    }

    public void onClickShowCryptoWarningDetails() {
        try {
            PendingIntent pendingIntent = cryptoResultAnnotation.getOpenPgpInsecureWarningPendingIntent();
+0 −34
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.StringRes;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -128,39 +127,6 @@ public class MessageTopView extends LinearLayout {
        }
    }

    public void showMessageCryptoWarning(final MessageViewInfo messageViewInfo, Drawable providerIcon,
            @StringRes int warningTextRes, boolean showDetailButton) {
        resetAndPrepareMessageView(messageViewInfo);
        View view = mInflater.inflate(R.layout.message_content_crypto_warning, containerView, false);
        setCryptoProviderIcon(providerIcon, view);

        View detailButton = view.findViewById(R.id.crypto_warning_details);
        if(showDetailButton) {
            detailButton.setVisibility(View.VISIBLE);
            detailButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    messageCryptoPresenter.onClickShowCryptoWarningDetails();
                }
            });
        } else {
            detailButton.setVisibility(View.GONE);
        }

        view.findViewById(R.id.crypto_warning_override).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                messageCryptoPresenter.onClickShowMessageOverrideWarning();
            }
        });

        TextView warningText = (TextView) view.findViewById(R.id.crypto_warning_text);
        warningText.setText(warningTextRes);

        containerView.addView(view);
        displayViewOnLoadFinished(false);
    }

    public void showMessageEncryptedButIncomplete(MessageViewInfo messageViewInfo, Drawable providerIcon) {
        resetAndPrepareMessageView(messageViewInfo);
        View view = mInflater.inflate(R.layout.message_content_crypto_incomplete, containerView, false);
+107 −95

File changed.

Preview size limit exceeded, changes collapsed.

+2 −26
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@ package com.fsck.k9.view;
import android.content.Context;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

@@ -14,9 +13,6 @@ import com.fsck.k9.R;
public class MessageCryptoStatusView extends FrameLayout {

    private ImageView iconSingle;
    private ImageView iconCombinedFirst;
    private ImageView iconCombinedSecond;
    private ImageView iconDotsBackground;

    public MessageCryptoStatusView(Context context) {
        super(context);
@@ -34,32 +30,12 @@ public class MessageCryptoStatusView extends FrameLayout {
    protected void onFinishInflate() {
        super.onFinishInflate();
        iconSingle = (ImageView) findViewById(R.id.crypto_status_single);
        iconCombinedFirst = (ImageView) findViewById(R.id.crypto_status_combined_1);
        iconCombinedSecond = (ImageView) findViewById(R.id.crypto_status_combined_2);
        iconDotsBackground = (ImageView) findViewById(R.id.crypto_status_dots_bg);
    }

    public void setCryptoDisplayStatus(MessageCryptoDisplayStatus displayStatus) {
        @ColorInt int color = ThemeUtils.getStyledColor(getContext(), displayStatus.colorAttr);

        if (displayStatus.statusDotsRes != null) {
            iconCombinedFirst.setVisibility(View.VISIBLE);
            iconCombinedSecond.setVisibility(View.VISIBLE);
            iconDotsBackground.setVisibility(View.VISIBLE);
            iconSingle.setVisibility(View.GONE);

            iconCombinedFirst.setImageResource(displayStatus.statusIconRes);
            iconCombinedFirst.setColorFilter(color);
            iconCombinedSecond.setImageResource(displayStatus.statusDotsRes);
            iconCombinedSecond.setColorFilter(color);
        } else {
            iconCombinedFirst.setVisibility(View.GONE);
            iconCombinedSecond.setVisibility(View.GONE);
            iconDotsBackground.setVisibility(View.GONE);
            iconSingle.setVisibility(View.VISIBLE);

        iconSingle.setImageResource(displayStatus.statusIconRes);
        iconSingle.setColorFilter(color);
    }
}
}
Loading