feat: Add biometric authentication toggle in ProfileScreen with state management

This commit is contained in:
k1ngsterr1
2026-01-22 15:00:33 +05:00
parent 1f6fc01a54
commit c7443a7ed7
2 changed files with 103 additions and 150 deletions

View File

@@ -43,7 +43,12 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.fragment.app.FragmentActivity
import com.rosetta.messenger.biometric.BiometricAuthManager
import com.rosetta.messenger.biometric.BiometricAvailability
import com.rosetta.messenger.biometric.BiometricPreferences
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
@@ -132,6 +137,21 @@ fun ProfileScreen(
onNavigateToLogs: () -> Unit = {},
viewModel: ProfileViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
) {
val context = LocalContext.current
val activity = context as? FragmentActivity
val biometricManager = remember { BiometricAuthManager(context) }
val biometricPrefs = remember { BiometricPreferences(context) }
val scope = rememberCoroutineScope()
// Biometric state
var biometricAvailable by remember { mutableStateOf<BiometricAvailability>(BiometricAvailability.NotAvailable("Checking...")) }
var isBiometricEnabled by remember { mutableStateOf(false) }
// Check biometric availability
LaunchedEffect(Unit) {
biometricAvailable = biometricManager.isBiometricAvailable()
isBiometricEnabled = biometricPrefs.isBiometricEnabled.first()
}
// Цвета в зависимости от темы
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
val surfaceColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F2F7)
@@ -194,9 +214,6 @@ fun ProfileScreen(
}
}
// Context
val context = LocalContext.current
// Show success toast and update local profile
LaunchedEffect(profileState.saveSuccess) {
if (profileState.saveSuccess) {
@@ -305,8 +322,41 @@ fun ProfileScreen(
icon = Icons.Outlined.Lock,
title = "Safety",
onClick = onNavigateToSafety,
isDarkTheme = isDarkTheme
isDarkTheme = isDarkTheme,
showDivider = biometricAvailable is BiometricAvailability.Available
)
// Biometric toggle (only show if available)
if (biometricAvailable is BiometricAvailability.Available && activity != null) {
TelegramBiometricItem(
isEnabled = isBiometricEnabled,
onToggle = {
scope.launch {
if (isBiometricEnabled) {
// Disable biometric
biometricPrefs.disableBiometric()
biometricPrefs.removeEncryptedPassword(accountPublicKey)
isBiometricEnabled = false
android.widget.Toast.makeText(
context,
"Biometric authentication disabled",
android.widget.Toast.LENGTH_SHORT
).show()
} else {
// Enable biometric
biometricPrefs.enableBiometric()
isBiometricEnabled = true
android.widget.Toast.makeText(
context,
"Biometric authentication enabled. Your password will be securely saved on next unlock.",
android.widget.Toast.LENGTH_LONG
).show()
}
}
},
isDarkTheme = isDarkTheme
)
}
Spacer(modifier = Modifier.height(24.dp))
@@ -831,6 +881,52 @@ private fun TelegramSettingsItem(
}
}
@Composable
private fun TelegramBiometricItem(
isEnabled: Boolean,
onToggle: () -> Unit,
isDarkTheme: Boolean
) {
val textColor = if (isDarkTheme) Color.White else Color.Black
val iconColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666)
val primaryBlue = Color(0xFF007AFF)
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onToggle)
.padding(horizontal = 16.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Outlined.Fingerprint,
contentDescription = null,
tint = iconColor,
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(20.dp))
Text(
text = "Biometric Authentication",
fontSize = 16.sp,
color = textColor,
modifier = Modifier.weight(1f)
)
Switch(
checked = isEnabled,
onCheckedChange = { onToggle() },
colors = SwitchDefaults.colors(
checkedThumbColor = Color.White,
checkedTrackColor = primaryBlue,
uncheckedThumbColor = Color.White,
uncheckedTrackColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0)
)
)
}
}
@Composable
private fun TelegramLogoutItem(
onClick: () -> Unit,