localisation: app biometric lock

This commit is contained in:
2026-06-12 21:44:43 +02:00
parent 4546844ea9
commit c3490808c0
6 changed files with 75 additions and 17 deletions
@@ -469,6 +469,19 @@ val EnHomeStrings = AppStrings(
failedToCreateConnection = "Failed to create connection", failedToCreateConnection = "Failed to create connection",
failedToDeleteConnection = "Failed to delete connection", failedToDeleteConnection = "Failed to delete connection",
failedToLoadConnection = "Failed to load connection", failedToLoadConnection = "Failed to load connection",
) ),
lock = LockStrings(
appLockTitle = "App Lock",
appLockDescription = "Require biometric authentication (fingerprint, face, or PIN) every time you open Gudari Wallet.",
appLockToggleLabel = "Lock app on open",
appLockToggleEnabled = "Enabled (recommended)",
appLockToggleDisabled = "Disabled",
appName = "Gudari Wallet",
authenticateToContinue = "Authenticate to continue",
unlockButton = "Unlock",
biometricPromptTitle = "Unlock Gudari Wallet",
biometricPromptSubtitle = "Authenticate to access your wallet",
),
) )
@@ -470,5 +470,17 @@ val EsHomeStrings = AppStrings(
failedToCreateConnection = "Error al crear la conexión", failedToCreateConnection = "Error al crear la conexión",
failedToDeleteConnection = "Error al eliminar la conexión", failedToDeleteConnection = "Error al eliminar la conexión",
failedToLoadConnection = "Error al cargar la conexión", failedToLoadConnection = "Error al cargar la conexión",
) ),
lock = LockStrings(
appLockTitle = "Bloqueo de App",
appLockDescription = "Solicitar autenticación biométrica (huella, cara o PIN) cada vez que se abra Gudari Wallet.",
appLockToggleLabel = "Bloquear al abrir",
appLockToggleEnabled = "Activado (recomendado)",
appLockToggleDisabled = "Desactivado",
appName = "Gudari Wallet",
authenticateToContinue = "Autentícate para continuar",
unlockButton = "Desbloquear",
biometricPromptTitle = "Desbloquear Gudari Wallet",
biometricPromptSubtitle = "Autentícate para acceder a tu cartera",
),
) )
@@ -470,5 +470,17 @@ val EuStrings = AppStrings(
failedToCreateConnection = "Huts egin du konexioa sortzean", failedToCreateConnection = "Huts egin du konexioa sortzean",
failedToDeleteConnection = "Huts egin du konexioa ezabatzean", failedToDeleteConnection = "Huts egin du konexioa ezabatzean",
failedToLoadConnection = "Huts egin du konexioa kargatzean", failedToLoadConnection = "Huts egin du konexioa kargatzean",
),
lock = LockStrings(
appLockTitle = "App Blokeoa",
appLockDescription = "Autentifikazio biometrikoa (hatz-marka, aurpegia edo PINa) eskatu Gudari Wallet irekitzen den bakoitzean.",
appLockToggleLabel = "Aplikazioa irekitzean blokeatu",
appLockToggleEnabled = "Gaituta (gomendatua)",
appLockToggleDisabled = "Desgaituta",
appName = "Gudari Wallet",
authenticateToContinue = "Autentifikatu jarraitzeko",
unlockButton = "Desblokeatu",
biometricPromptTitle = "Desblokeatu Gudari Wallet",
biometricPromptSubtitle = "Autentifikatu zure zorrora sartzeko",
) )
) )
@@ -154,7 +154,8 @@ data class AppStrings(
val onboarding: OnboardingStrings, val onboarding: OnboardingStrings,
val receive: ReceiveStrings, val receive: ReceiveStrings,
val history: HistoryStrings, val history: HistoryStrings,
val nwc: NwcStrings val nwc: NwcStrings,
val lock: LockStrings
) )
data class OnboardingStrings( data class OnboardingStrings(
@@ -480,3 +481,16 @@ data class NwcStrings(
val failedToDeleteConnection : String, val failedToDeleteConnection : String,
val failedToLoadConnection : String, val failedToLoadConnection : String,
) )
data class LockStrings(
val appLockTitle: String,
val appLockDescription: String,
val appLockToggleLabel: String,
val appLockToggleEnabled: String,
val appLockToggleDisabled: String,
val appName: String,
val authenticateToContinue: String,
val unlockButton: String,
val biometricPromptTitle: String,
val biometricPromptSubtitle: String,
)
@@ -15,14 +15,17 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.bitcointxoko.gudariwallet.LocalAppStrings
import com.bitcointxoko.gudariwallet.i18n.LockStrings
@Composable @Composable
fun BiometricLockScreen(onUnlocked: () -> Unit) { fun BiometricLockScreen(onUnlocked: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
val activity = context as FragmentActivity val activity = context as FragmentActivity
val strings = LocalAppStrings.current.lock
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
showBiometricPrompt(activity, onUnlocked) showBiometricPrompt(activity, onUnlocked, strings)
} }
Scaffold { innerPadding -> Scaffold { innerPadding ->
@@ -47,7 +50,7 @@ fun BiometricLockScreen(onUnlocked: () -> Unit) {
Spacer(Modifier.height(24.dp)) Spacer(Modifier.height(24.dp))
Text( Text(
text = "Gudari Wallet", text = strings.appName,
style = MaterialTheme.typography.displaySmall, style = MaterialTheme.typography.displaySmall,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
textAlign = TextAlign.Center textAlign = TextAlign.Center
@@ -56,7 +59,7 @@ fun BiometricLockScreen(onUnlocked: () -> Unit) {
Spacer(Modifier.height(8.dp)) Spacer(Modifier.height(8.dp))
Text( Text(
text = "Authenticate to continue", text = strings.authenticateToContinue,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant, color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center textAlign = TextAlign.Center
@@ -65,7 +68,7 @@ fun BiometricLockScreen(onUnlocked: () -> Unit) {
Spacer(Modifier.height(32.dp)) Spacer(Modifier.height(32.dp))
FilledTonalButton( FilledTonalButton(
onClick = { showBiometricPrompt(activity, onUnlocked) } onClick = { showBiometricPrompt(activity, onUnlocked, strings) }
) { ) {
Icon( Icon(
imageVector = Icons.Filled.Fingerprint, imageVector = Icons.Filled.Fingerprint,
@@ -73,7 +76,7 @@ fun BiometricLockScreen(onUnlocked: () -> Unit) {
modifier = Modifier.size(ButtonDefaults.IconSize) modifier = Modifier.size(ButtonDefaults.IconSize)
) )
Spacer(Modifier.width(ButtonDefaults.IconSpacing)) Spacer(Modifier.width(ButtonDefaults.IconSpacing))
Text("Unlock") Text(strings.unlockButton)
} }
} }
} }
@@ -82,7 +85,8 @@ fun BiometricLockScreen(onUnlocked: () -> Unit) {
private fun showBiometricPrompt( private fun showBiometricPrompt(
activity: FragmentActivity, activity: FragmentActivity,
onUnlocked: () -> Unit onUnlocked: () -> Unit,
strings: LockStrings
) { ) {
val executor = ContextCompat.getMainExecutor(activity) val executor = ContextCompat.getMainExecutor(activity)
@@ -95,8 +99,8 @@ private fun showBiometricPrompt(
val prompt = BiometricPrompt(activity, executor, callback) val prompt = BiometricPrompt(activity, executor, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder() val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock Gudari Wallet") .setTitle(strings.biometricPromptTitle)
.setSubtitle("Authenticate to access your wallet") .setSubtitle(strings.biometricPromptSubtitle)
.setAllowedAuthenticators( .setAllowedAuthenticators(
BiometricManager.Authenticators.BIOMETRIC_STRONG BiometricManager.Authenticators.BIOMETRIC_STRONG
or BiometricManager.Authenticators.DEVICE_CREDENTIAL or BiometricManager.Authenticators.DEVICE_CREDENTIAL
@@ -9,12 +9,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.bitcointxoko.gudariwallet.LocalAppStrings
@Composable @Composable
fun BiometricLockPage( fun BiometricLockPage(
appLockEnabled: Boolean, appLockEnabled: Boolean,
onAppLockChanged: (Boolean) -> Unit onAppLockChanged: (Boolean) -> Unit
) { ) {
val strings = LocalAppStrings.current.lock
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@@ -32,7 +34,7 @@ fun BiometricLockPage(
Spacer(Modifier.height(24.dp)) Spacer(Modifier.height(24.dp))
Text( Text(
text = "App Lock", text = strings.appLockTitle,
style = MaterialTheme.typography.headlineMedium, style = MaterialTheme.typography.headlineMedium,
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
@@ -40,7 +42,7 @@ fun BiometricLockPage(
Spacer(Modifier.height(12.dp)) Spacer(Modifier.height(12.dp))
Text( Text(
text = "Require biometric authentication (fingerprint, face, or PIN) every time you open Gudari Wallet.", text = strings.appLockDescription,
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
@@ -63,11 +65,12 @@ fun BiometricLockPage(
) { ) {
Column(modifier = Modifier.weight(1f)) { Column(modifier = Modifier.weight(1f)) {
Text( Text(
text = "Lock app on open", text = strings.appLockToggleLabel,
style = MaterialTheme.typography.bodyLarge style = MaterialTheme.typography.bodyLarge
) )
Text( Text(
text = if (appLockEnabled) "Enabled (recommended)" else "Disabled", text = if (appLockEnabled) strings.appLockToggleEnabled
else strings.appLockToggleDisabled,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )