Add keyboard type toggle with preference persistence

Closes #10
Closes #13
This commit is contained in:
mimi89999
2025-12-21 18:51:18 +01:00
parent dfb2821cbc
commit 17391a0de0
5 changed files with 80 additions and 1 deletions
@@ -1,8 +1,10 @@
package pl.lebihan.authnkey
import android.animation.ObjectAnimator
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -12,6 +14,7 @@ import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.content.edit
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
@@ -60,6 +63,10 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
var onPinEntered: ((String) -> Unit)? = null
var onAccountSelected: ((Int) -> Unit)? = null
private val useNumericKeyboard: Boolean
get() = requireContext().getSharedPreferences("authnkey_prefs", Context.MODE_PRIVATE)
.getBoolean("use_numeric_keyboard", true)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -99,6 +106,7 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
if (pendingShowPinInput) {
pinInputLayout.visibility = View.VISIBLE
btnContinue.visibility = View.VISIBLE
applyKeyboardMode(useNumericKeyboard)
pinEditText.requestFocus()
}
@@ -121,6 +129,10 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
}
}
pinInputLayout.setStartIconOnClickListener {
onKeyboardModeToggled()
}
(dialog as? BottomSheetDialog)?.behavior?.apply {
state = BottomSheetBehavior.STATE_EXPANDED
skipCollapsed = true
@@ -147,6 +159,50 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
}
}
private fun applyKeyboardMode(numeric: Boolean) {
pinInputLayout.setStartIconDrawable(
if (numeric) R.drawable.keyboard_24 else R.drawable.dialpad_24
)
pinEditText.inputType = if (numeric) {
InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
} else {
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
}
}
private fun onKeyboardModeToggled() {
val newMode = !useNumericKeyboard
requireContext().getSharedPreferences("authnkey_prefs", Context.MODE_PRIVATE)
.edit {
putBoolean("use_numeric_keyboard", newMode)
}
pinEditText.inputType = if (newMode) {
InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
} else {
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
}
val iconRes = if (newMode) R.drawable.keyboard_24 else R.drawable.dialpad_24
pinInputLayout.findViewById<View>(com.google.android.material.R.id.text_input_start_icon)?.let { iconView ->
iconView.animate()
.alpha(0f)
.setDuration(100)
.withEndAction {
pinInputLayout.setStartIconDrawable(iconRes)
iconView.alpha = 1f
}
.start()
} ?: pinInputLayout.setStartIconDrawable(iconRes)
pinEditText.post {
val imm = requireContext().getSystemService(InputMethodManager::class.java)
imm?.restartInput(pinEditText)
}
}
fun setState(state: State) {
if (::iconStatus.isInitialized) {
applyState(state)
@@ -224,6 +280,7 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
hideAccounts()
pinEditText.text?.clear()
pinInputLayout.error = null
applyKeyboardMode(useNumericKeyboard)
pinEditText.requestFocus()
setState(State.PIN)
pinEditText.post {
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,920Q447,920 423.5,896.5Q400,873 400,840Q400,807 423.5,783.5Q447,760 480,760Q513,760 536.5,783.5Q560,807 560,840Q560,873 536.5,896.5Q513,920 480,920ZM240,200Q207,200 183.5,176.5Q160,153 160,120Q160,87 183.5,63.5Q207,40 240,40Q273,40 296.5,63.5Q320,87 320,120Q320,153 296.5,176.5Q273,200 240,200ZM240,440Q207,440 183.5,416.5Q160,393 160,360Q160,327 183.5,303.5Q207,280 240,280Q273,280 296.5,303.5Q320,327 320,360Q320,393 296.5,416.5Q273,440 240,440ZM240,680Q207,680 183.5,656.5Q160,633 160,600Q160,567 183.5,543.5Q207,520 240,520Q273,520 296.5,543.5Q320,567 320,600Q320,633 296.5,656.5Q273,680 240,680ZM720,200Q687,200 663.5,176.5Q640,153 640,120Q640,87 663.5,63.5Q687,40 720,40Q753,40 776.5,63.5Q800,87 800,120Q800,153 776.5,176.5Q753,200 720,200ZM480,680Q447,680 423.5,656.5Q400,633 400,600Q400,567 423.5,543.5Q447,520 480,520Q513,520 536.5,543.5Q560,567 560,600Q560,633 536.5,656.5Q513,680 480,680ZM720,680Q687,680 663.5,656.5Q640,633 640,600Q640,567 663.5,543.5Q687,520 720,520Q753,520 776.5,543.5Q800,567 800,600Q800,633 776.5,656.5Q753,680 720,680ZM720,440Q687,440 663.5,416.5Q640,393 640,360Q640,327 663.5,303.5Q687,280 720,280Q753,280 776.5,303.5Q800,327 800,360Q800,393 776.5,416.5Q753,440 720,440ZM480,440Q447,440 423.5,416.5Q400,393 400,360Q400,327 423.5,303.5Q447,280 480,280Q513,280 536.5,303.5Q560,327 560,360Q560,393 536.5,416.5Q513,440 480,440ZM480,200Q447,200 423.5,176.5Q400,153 400,120Q400,87 423.5,63.5Q447,40 480,40Q513,40 536.5,63.5Q560,87 560,120Q560,153 536.5,176.5Q513,200 480,200Z"/>
</vector>
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M160,760Q127,760 103.5,736.5Q80,713 80,680L80,280Q80,247 103.5,223.5Q127,200 160,200L800,200Q833,200 856.5,223.5Q880,247 880,280L880,680Q880,713 856.5,736.5Q833,760 800,760L160,760ZM160,680L800,680Q800,680 800,680Q800,680 800,680L800,280Q800,280 800,280Q800,280 800,280L160,280Q160,280 160,280Q160,280 160,280L160,680Q160,680 160,680Q160,680 160,680ZM320,640L640,640L640,560L320,560L320,640ZM200,520L280,520L280,440L200,440L200,520ZM320,520L400,520L400,440L320,440L320,520ZM440,520L520,520L520,440L440,440L440,520ZM560,520L640,520L640,440L560,440L560,520ZM680,520L760,520L760,440L680,440L680,520ZM200,400L280,400L280,320L200,320L200,400ZM320,400L400,400L400,320L320,320L320,400ZM440,400L520,400L520,320L440,320L440,400ZM560,400L640,400L640,320L560,320L560,400ZM680,400L760,400L760,320L680,320L680,400ZM160,680Q160,680 160,680Q160,680 160,680L160,280Q160,280 160,280Q160,280 160,280L160,280Q160,280 160,280Q160,280 160,280L160,680Q160,680 160,680Q160,680 160,680Z"/>
</vector>
@@ -76,6 +76,8 @@
android:layout_marginBottom="16dp"
android:visibility="gone"
android:hint="@string/pin_hint"
app:startIconDrawable="@drawable/keyboard_24"
app:startIconContentDescription="@string/toggle_keyboard_type"
app:endIconMode="password_toggle"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox">
@@ -83,7 +85,6 @@
android:id="@+id/pinEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:imeOptions="actionDone" />
</com.google.android.material.textfield.TextInputLayout>
+1
View File
@@ -52,6 +52,7 @@
<!-- Content descriptions -->
<string name="security_key_icon_desc">Security Key</string>
<string name="drag_handle_desc">Drag handle</string>
<string name="toggle_keyboard_type">Toggle keyboard type</string>
<!-- MainActivity (Debug) -->
<string name="usb_permission_denied">USB permission denied</string>