mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Disable keyboard suggestions when typing PIN.
Converts `PinKeyboardType` to Kotlin and introduces methods to consistently configure PIN entry fields throughout the app, including a fix to disable keyboard suggestions.
This commit is contained in:
@@ -3,13 +3,11 @@ package org.thoughtcrime.securesms.lock;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.method.PasswordTransformationMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
@@ -74,15 +72,7 @@ public final class SignalPinReminderDialog {
|
||||
|
||||
ViewUtil.focusAndShowKeyboard(pinEditText);
|
||||
|
||||
switch (SignalStore.pin().getKeyboardType()) {
|
||||
case NUMERIC:
|
||||
pinEditText.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
break;
|
||||
case ALPHA_NUMERIC:
|
||||
pinEditText.setInputType(InputType.TYPE_CLASS_TEXT );
|
||||
break;
|
||||
}
|
||||
pinEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
|
||||
SignalStore.pin().getKeyboardType().applyInputTypeTo(pinEditText);
|
||||
|
||||
ClickableSpan clickableSpan = new ClickableSpan() {
|
||||
@Override
|
||||
|
||||
@@ -2,8 +2,6 @@ package org.thoughtcrime.securesms.lock.v2;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.text.method.PasswordTransformationMethod;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -71,9 +69,8 @@ public abstract class BaseSvrPinFragment<ViewModel extends BaseSvrPinViewModel>
|
||||
});
|
||||
|
||||
viewModel.getKeyboard().observe(getViewLifecycleOwner(), keyboardType -> {
|
||||
updateKeyboard(keyboardType);
|
||||
keyboardType.applyTo(input, keyboardToggle);
|
||||
keyboardToggle.setText(resolveKeyboardToggleText(keyboardType));
|
||||
keyboardToggle.setIconResource(keyboardType.getOther().getIconResource());
|
||||
});
|
||||
|
||||
description.setOnLinkClickListener(v -> {
|
||||
@@ -190,15 +187,8 @@ public abstract class BaseSvrPinFragment<ViewModel extends BaseSvrPinViewModel>
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateKeyboard(@NonNull PinKeyboardType keyboard) {
|
||||
boolean isAlphaNumeric = keyboard == PinKeyboardType.ALPHA_NUMERIC;
|
||||
|
||||
input.setInputType(isAlphaNumeric ? InputType.TYPE_CLASS_TEXT : InputType.TYPE_CLASS_NUMBER);
|
||||
input.setTransformationMethod(PasswordTransformationMethod.getInstance());
|
||||
}
|
||||
|
||||
private @StringRes int resolveKeyboardToggleText(@NonNull PinKeyboardType keyboard) {
|
||||
if (keyboard == PinKeyboardType.ALPHA_NUMERIC) {
|
||||
private @StringRes int resolveKeyboardToggleText(@NonNull PinKeyboardType keyboardType) {
|
||||
if (keyboardType == PinKeyboardType.ALPHA_NUMERIC) {
|
||||
return R.string.BaseKbsPinFragment__create_numeric_pin;
|
||||
} else {
|
||||
return R.string.BaseKbsPinFragment__create_alphanumeric_pin;
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package org.thoughtcrime.securesms.lock.v2;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public enum PinKeyboardType {
|
||||
NUMERIC("numeric"),
|
||||
ALPHA_NUMERIC("alphaNumeric");
|
||||
|
||||
private final String code;
|
||||
|
||||
PinKeyboardType(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public PinKeyboardType getOther() {
|
||||
if (this == NUMERIC) return ALPHA_NUMERIC;
|
||||
else return NUMERIC;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static PinKeyboardType fromCode(@Nullable String code) {
|
||||
for (PinKeyboardType type : PinKeyboardType.values()) {
|
||||
if (type.code.equals(code)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return NUMERIC;
|
||||
}
|
||||
|
||||
public int getIconResource() {
|
||||
if (this == ALPHA_NUMERIC) return R.drawable.ic_keyboard_24;
|
||||
else return R.drawable.ic_number_pad_conversation_filter_24;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.lock.v2
|
||||
|
||||
import android.text.InputType
|
||||
import android.text.method.PasswordTransformationMethod
|
||||
import android.widget.EditText
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
/**
|
||||
* The available keyboard input types for Signal PIN entry.
|
||||
*/
|
||||
enum class PinKeyboardType(val code: String) {
|
||||
NUMERIC("numeric"),
|
||||
ALPHA_NUMERIC("alphaNumeric");
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Gets the PinKeyboardType that is associated with a string code representation.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromCode(code: String?): PinKeyboardType = entries.firstOrNull { it.code == code } ?: NUMERIC
|
||||
|
||||
/**
|
||||
* Gets the keyboard type that is associated with an [EditText]'s current input type.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromEditText(editText: EditText): PinKeyboardType = when {
|
||||
(editText.inputType and InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_NUMBER -> NUMERIC
|
||||
else -> ALPHA_NUMERIC
|
||||
}
|
||||
}
|
||||
|
||||
private val inputType: Int by lazy {
|
||||
when (this) {
|
||||
NUMERIC -> InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
|
||||
ALPHA_NUMERIC -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
}
|
||||
}
|
||||
|
||||
private val toggleIconResource: Int by lazy {
|
||||
when (this) {
|
||||
NUMERIC -> R.drawable.ic_number_pad_conversation_filter_24
|
||||
ALPHA_NUMERIC -> R.drawable.ic_keyboard_24
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the opposite keyboard type to the current one.
|
||||
*/
|
||||
val other: PinKeyboardType
|
||||
get() {
|
||||
return when (this) {
|
||||
NUMERIC -> ALPHA_NUMERIC
|
||||
ALPHA_NUMERIC -> NUMERIC
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures an [EditText] and toggle button for this keyboard type.
|
||||
*/
|
||||
fun applyTo(pinEditText: EditText, toggleTypeButton: MaterialButton) {
|
||||
applyInputTypeTo(pinEditText)
|
||||
applyToggleIconTo(toggleTypeButton)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures an [EditText] for this keyboard type.
|
||||
*/
|
||||
fun applyInputTypeTo(editText: EditText) {
|
||||
val currentInputClass = editText.inputType and InputType.TYPE_MASK_CLASS
|
||||
val desiredInputClass = this.inputType and InputType.TYPE_MASK_CLASS
|
||||
if (currentInputClass != desiredInputClass) {
|
||||
editText.getText().clear()
|
||||
}
|
||||
|
||||
editText.inputType = this.inputType
|
||||
editText.transformationMethod = PasswordTransformationMethod.getInstance()
|
||||
}
|
||||
|
||||
private fun applyToggleIconTo(toggleTypeButton: MaterialButton) {
|
||||
toggleTypeButton.setIconResource(this.other.toggleIconResource)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user