Merge pull request #661 from mchllngr/keyboard-enter-finishes-task

pressing enter on a physical keyboard finished the selected task
This commit is contained in:
Jakob Nixdorf 2021-02-26 07:40:40 +01:00 committed by GitHub
commit cdd9bf63f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 4 deletions

View file

@ -56,6 +56,7 @@ import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Tasks.AuthenticationTask; import org.shadowice.flocke.andotp.Tasks.AuthenticationTask;
import org.shadowice.flocke.andotp.Tasks.AuthenticationTask.Result; import org.shadowice.flocke.andotp.Tasks.AuthenticationTask.Result;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.EditorActionHelper;
import static org.shadowice.flocke.andotp.Utilities.Constants.AuthMethod; import static org.shadowice.flocke.andotp.Utilities.Constants.AuthMethod;
@ -237,7 +238,7 @@ public class AuthenticateActivity extends BaseActivity
@Override @Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) { if (EditorActionHelper.isActionDoneOrKeyboardEnter(actionId, event)) {
startAuthTask(v.getText().toString()); startAuthTask(v.getText().toString());
return true; return true;
} }

View file

@ -32,6 +32,7 @@ import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.method.PasswordTransformationMethod; import android.text.method.PasswordTransformationMethod;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -57,6 +58,7 @@ import com.heinrichreimersoftware.materialintro.slide.SimpleSlide;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.ConfirmedPasswordTransformationHelper; import org.shadowice.flocke.andotp.Utilities.ConfirmedPasswordTransformationHelper;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.EditorActionHelper;
import org.shadowice.flocke.andotp.Utilities.Settings; import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.UIHelper; import org.shadowice.flocke.andotp.Utilities.UIHelper;
@ -266,7 +268,7 @@ public class IntroScreenActivity extends IntroActivity {
} }
} }
public static class AuthenticationFragment extends SlideFragment { public static class AuthenticationFragment extends SlideFragment implements TextView.OnEditorActionListener {
private Constants.EncryptionType encryptionType = Constants.EncryptionType.KEYSTORE; private Constants.EncryptionType encryptionType = Constants.EncryptionType.KEYSTORE;
private int slidePos = -1; private int slidePos = -1;
@ -488,11 +490,27 @@ public class IntroScreenActivity extends IntroActivity {
passwordInput.addTextChangedListener(textWatcher); passwordInput.addTextChangedListener(textWatcher);
passwordConfirm.addTextChangedListener(textWatcher); passwordConfirm.addTextChangedListener(textWatcher);
passwordConfirm.setOnEditorActionListener(this);
selection.setSelection(selectionMapping.indexOfValue(Constants.AuthMethod.PASSWORD)); selection.setSelection(selectionMapping.indexOfValue(Constants.AuthMethod.PASSWORD));
return root; return root;
} }
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (EditorActionHelper.isActionDoneOrKeyboardEnter(actionId, event)) {
nextSlide();
return true;
} else if (EditorActionHelper.isActionUpKeyboardEnter(event)) {
// Ignore action up after keyboard enter. Otherwise the go-back button would be selected
// after pressing enter with an invalid password.
return true;
}
return false;
}
@Override @Override
public boolean canGoForward() { public boolean canGoForward() {
Constants.AuthMethod authMethod = selectionMapping.get(selection.getSelectedItemPosition()); Constants.AuthMethod authMethod = selectionMapping.get(selection.getSelectedItemPosition());

View file

@ -10,16 +10,19 @@ import android.os.Build;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.ConfirmedPasswordTransformationHelper; import org.shadowice.flocke.andotp.Utilities.ConfirmedPasswordTransformationHelper;
import org.shadowice.flocke.andotp.Utilities.EditorActionHelper;
import org.shadowice.flocke.andotp.Utilities.Tools; import org.shadowice.flocke.andotp.Utilities.Tools;
public class PasswordEntryDialog extends AppCompatDialog public class PasswordEntryDialog extends AppCompatDialog
implements View.OnClickListener, TextWatcher { implements View.OnClickListener, TextWatcher, TextView.OnEditorActionListener {
public enum Mode { ENTER, UPDATE } public enum Mode { ENTER, UPDATE }
@ -69,8 +72,10 @@ public class PasswordEntryDialog extends AppCompatDialog
passwordConfirm.setVisibility(View.VISIBLE); passwordConfirm.setVisibility(View.VISIBLE);
passwordInput.addTextChangedListener(this); passwordInput.addTextChangedListener(this);
passwordConfirm.addTextChangedListener(this); passwordConfirm.addTextChangedListener(this);
passwordConfirm.setOnEditorActionListener(this);
} else if (this.dialogMode == Mode.ENTER) { } else if (this.dialogMode == Mode.ENTER) {
passwordConfirm.setVisibility(View.GONE); passwordConfirm.setVisibility(View.GONE);
passwordInput.setOnEditorActionListener(this);
} }
} }
@ -85,6 +90,20 @@ public class PasswordEntryDialog extends AppCompatDialog
public void afterTextChanged(Editable s) {} public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (EditorActionHelper.isActionDoneOrKeyboardEnter(actionId, event)) {
if (okButton.isEnabled()) okButton.performClick();
return true;
} else if (EditorActionHelper.isActionUpKeyboardEnter(event)) {
// Ignore action up after keyboard enter. Otherwise the cancel button would be selected
// after pressing enter with an invalid password.
return true;
}
return false;
}
// View.OnClickListener // View.OnClickListener
public void onClick(View view) { public void onClick(View view) {
if (view.getId() == R.id.buttonOk) { if (view.getId() == R.id.buttonOk) {

View file

@ -31,6 +31,7 @@ import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
@ -47,6 +48,7 @@ import com.google.android.material.textfield.TextInputLayout;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.ConfirmedPasswordTransformationHelper; import org.shadowice.flocke.andotp.Utilities.ConfirmedPasswordTransformationHelper;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.EditorActionHelper;
import org.shadowice.flocke.andotp.Utilities.Settings; import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.UIHelper; import org.shadowice.flocke.andotp.Utilities.UIHelper;
@ -59,7 +61,7 @@ import static org.shadowice.flocke.andotp.Utilities.Constants.AuthMethod;
import static org.shadowice.flocke.andotp.Utilities.Constants.EncryptionType; import static org.shadowice.flocke.andotp.Utilities.Constants.EncryptionType;
public class CredentialsPreference extends DialogPreference public class CredentialsPreference extends DialogPreference
implements AdapterView.OnItemClickListener, View.OnClickListener, TextWatcher { implements AdapterView.OnItemClickListener, View.OnClickListener, TextWatcher, TextView.OnEditorActionListener {
public static final AuthMethod DEFAULT_VALUE = AuthMethod.NONE; public static final AuthMethod DEFAULT_VALUE = AuthMethod.NONE;
public interface EncryptionChangeCallback { public interface EncryptionChangeCallback {
@ -143,6 +145,7 @@ public class CredentialsPreference extends DialogPreference
passwordInput.addTextChangedListener(this); passwordInput.addTextChangedListener(this);
passwordConfirm.addTextChangedListener(this); passwordConfirm.addTextChangedListener(this);
passwordConfirm.setOnEditorActionListener(this);
Button btnCancel = view.findViewById(R.id.btnCancel); Button btnCancel = view.findViewById(R.id.btnCancel);
btnSave = view.findViewById(R.id.btnSave); btnSave = view.findViewById(R.id.btnSave);
@ -290,6 +293,20 @@ public class CredentialsPreference extends DialogPreference
passwordConfirm.setText(null); passwordConfirm.setText(null);
} }
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (EditorActionHelper.isActionDoneOrKeyboardEnter(actionId, event)) {
if (btnSave.isEnabled()) btnSave.performClick();
return true;
} else if (EditorActionHelper.isActionUpKeyboardEnter(event)) {
// Ignore action up after keyboard enter. Otherwise the cancel button would be selected
// after pressing enter with an invalid password.
return true;
}
return false;
}
// Needed stub functions // Needed stub functions
@Override @Override
public void afterTextChanged(Editable s) {} public void afterTextChanged(Editable s) {}

View file

@ -0,0 +1,23 @@
package org.shadowice.flocke.andotp.Utilities;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.ACTION_UP;
import static android.view.KeyEvent.KEYCODE_ENTER;
import static android.view.KeyEvent.KEYCODE_NUMPAD_ENTER;
public class EditorActionHelper {
private EditorActionHelper() { /* not allowed */ }
public static boolean isActionDoneOrKeyboardEnter(int actionId, KeyEvent event) {
return actionId == EditorInfo.IME_ACTION_DONE
|| event.getAction() == ACTION_DOWN && (event.getKeyCode() == KEYCODE_ENTER || event.getKeyCode() == KEYCODE_NUMPAD_ENTER);
}
public static boolean isActionUpKeyboardEnter(KeyEvent event) {
return event.getAction() == ACTION_UP && (event.getKeyCode() == KEYCODE_ENTER || event.getKeyCode() == KEYCODE_NUMPAD_ENTER);
}
}