enc-backup: handle bad code more nicely
This commit is contained in:
@@ -28,6 +28,7 @@ import android.animation.ObjectAnimator;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
@@ -53,7 +54,7 @@ public class BackupCodeEntryFragment extends Fragment {
|
|||||||
|
|
||||||
private ExportHelper mExportHelper;
|
private ExportHelper mExportHelper;
|
||||||
private EditText[] mCodeEditText;
|
private EditText[] mCodeEditText;
|
||||||
private ViewAnimator mStatusAnimator;
|
private ViewAnimator mStatusAnimator, mTitleAnimator;
|
||||||
|
|
||||||
public static BackupCodeEntryFragment newInstance(String backupCode) {
|
public static BackupCodeEntryFragment newInstance(String backupCode) {
|
||||||
BackupCodeEntryFragment frag = new BackupCodeEntryFragment();
|
BackupCodeEntryFragment frag = new BackupCodeEntryFragment();
|
||||||
@@ -96,24 +97,18 @@ public class BackupCodeEntryFragment extends Fragment {
|
|||||||
setupEditTextSuccessListener(mCodeEditText);
|
setupEditTextSuccessListener(mCodeEditText);
|
||||||
|
|
||||||
mStatusAnimator = (ViewAnimator) view.findViewById(R.id.status_animator);
|
mStatusAnimator = (ViewAnimator) view.findViewById(R.id.status_animator);
|
||||||
|
mTitleAnimator = (ViewAnimator) view.findViewById(R.id.title_animator);
|
||||||
|
|
||||||
View backupAll = view.findViewById(R.id.backup_all);
|
View backupSave = view.findViewById(R.id.button_backup_save);
|
||||||
View backupPublicKeys = view.findViewById(R.id.backup_public_keys);
|
View backupShare = view.findViewById(R.id.button_backup_share);
|
||||||
|
|
||||||
backupAll.setOnClickListener(new View.OnClickListener() {
|
backupSave.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
startBackup(true);
|
startBackup(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
backupPublicKeys.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
startBackup(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +135,9 @@ public class BackupCodeEntryFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
// we could do this in better granularity in onTextChanged, but it's not worth it
|
// we could do this in better granularity in onTextChanged, but it's not worth it
|
||||||
mCurrentCodeInput.replace(index, index +s.length(), s.toString());
|
mCurrentCodeInput.replace(index, index +s.length(), s.toString());
|
||||||
checkIfMatchingCode();
|
// if (s.length() == 6) {
|
||||||
|
checkIfMatchingCode();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -149,15 +146,30 @@ public class BackupCodeEntryFragment extends Fragment {
|
|||||||
|
|
||||||
private void checkIfMatchingCode() {
|
private void checkIfMatchingCode() {
|
||||||
|
|
||||||
|
for (EditText editText : mCodeEditText) {
|
||||||
|
if (editText.getText().length() < 6) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if they don't match, do nothing
|
// if they don't match, do nothing
|
||||||
if (mCurrentCodeInput.toString().equals(mBackupCode)) {
|
if (mCurrentCodeInput.toString().equals(mBackupCode)) {
|
||||||
codeInputSuccessful();
|
codeInputSuccessful();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCurrentCodeInput.toString().startsWith("ABC")) {
|
if (mCurrentCodeInput.toString().startsWith("ABC")) {
|
||||||
codeInputSuccessful();
|
codeInputSuccessful();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we know all fields are filled, so if it's not the *right* one it's a *wrong* one!
|
||||||
|
@ColorInt int black = mCodeEditText[0].getCurrentTextColor();
|
||||||
|
@ColorInt int red = getResources().getColor(R.color.android_red_dark);
|
||||||
|
for (EditText editText : mCodeEditText) {
|
||||||
|
animateFlashText(editText, black, red, false);
|
||||||
|
}
|
||||||
|
mStatusAnimator.setDisplayedChild(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,21 +182,33 @@ public class BackupCodeEntryFragment extends Fragment {
|
|||||||
|
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
|
|
||||||
|
mTitleAnimator.setDisplayedChild(1);
|
||||||
|
mStatusAnimator.setDisplayedChild(2);
|
||||||
|
|
||||||
@ColorInt int black = mCodeEditText[0].getCurrentTextColor();
|
@ColorInt int black = mCodeEditText[0].getCurrentTextColor();
|
||||||
@ColorInt int green = getResources().getColor(R.color.android_green_dark);
|
@ColorInt int green = getResources().getColor(R.color.android_green_dark);
|
||||||
for (EditText editText : mCodeEditText) {
|
for (EditText editText : mCodeEditText) {
|
||||||
|
animateFlashText(editText, black, green, true);
|
||||||
ObjectAnimator anim = ObjectAnimator.ofArgb(editText, "textColor",
|
|
||||||
black, green, black, green, black, green)
|
|
||||||
.setDuration(1000);
|
|
||||||
anim.setInterpolator(new LinearInterpolator());
|
|
||||||
anim.start();
|
|
||||||
|
|
||||||
editText.setEnabled(false);
|
editText.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mStatusAnimator.setDisplayedChild(2);
|
}
|
||||||
|
|
||||||
|
private void animateFlashText(EditText editText, int color1, int color2, boolean staySecondColor) {
|
||||||
|
|
||||||
|
ObjectAnimator anim;
|
||||||
|
if (staySecondColor) {
|
||||||
|
anim = ObjectAnimator.ofArgb(editText, "textColor",
|
||||||
|
color1, color2, color1, color2, color1, color2);
|
||||||
|
} else {
|
||||||
|
anim = ObjectAnimator.ofArgb(editText, "textColor",
|
||||||
|
color1, color2, color1, color2, color1);
|
||||||
|
}
|
||||||
|
|
||||||
|
anim.setDuration(1000);
|
||||||
|
anim.setStartDelay(200);
|
||||||
|
anim.setInterpolator(new LinearInterpolator());
|
||||||
|
anim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupEditTextFocusNext(final EditText[] backupCodes) {
|
private void setupEditTextFocusNext(final EditText[] backupCodes) {
|
||||||
|
|||||||
8
OpenKeychain/src/main/res/anim/fade_in_delayed.xml
Normal file
8
OpenKeychain/src/main/res/anim/fade_in_delayed.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||||
|
android:interpolator="@android:anim/bounce_interpolator"
|
||||||
|
android:duration="700"
|
||||||
|
android:startOffset="400"
|
||||||
|
/>
|
||||||
|
</set>
|
||||||
8
OpenKeychain/src/main/res/anim/fade_out_delayed.xml
Normal file
8
OpenKeychain/src/main/res/anim/fade_out_delayed.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||||
|
android:interpolator="@android:anim/accelerate_interpolator"
|
||||||
|
android:duration="300"
|
||||||
|
android:startOffset="400"
|
||||||
|
/>
|
||||||
|
</set>
|
||||||
@@ -4,8 +4,7 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingTop="10dp"
|
android:paddingTop="50dp">
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
Reference in New Issue
Block a user