feat: Enhance avatar management with detailed logging and error handling

This commit is contained in:
k1ngsterr1
2026-01-24 00:26:23 +05:00
parent b08bea2c14
commit 1367864008
11 changed files with 107 additions and 324 deletions

View File

@@ -735,24 +735,28 @@ fun UnlockScreen(
onUnlocking = { isUnlocking = it },
onError = { error = it },
onSuccess = { decryptedAccount ->
// If biometric is enabled, save password
// If biometric is enabled and password not saved yet, save password
if (biometricAvailable is BiometricAvailability.Available &&
isBiometricEnabled && activity != null) {
scope.launch {
biometricManager.encryptPassword(
activity = activity,
password = password,
onSuccess = { encryptedPassword ->
scope.launch {
biometricPrefs.saveEncryptedPassword(
decryptedAccount.publicKey,
encryptedPassword
)
}
},
onError = { /* Ignore save errors */ },
onCancel = { /* User cancelled */ }
)
// Check if password is already saved
val hasPassword = biometricPrefs.hasEncryptedPassword(decryptedAccount.publicKey)
if (!hasPassword) {
biometricManager.encryptPassword(
activity = activity,
password = password,
onSuccess = { encryptedPassword ->
scope.launch {
biometricPrefs.saveEncryptedPassword(
decryptedAccount.publicKey,
encryptedPassword
)
}
},
onError = { /* Ignore save errors */ },
onCancel = { /* User cancelled */ }
)
}
}
}
onUnlocked(decryptedAccount)

View File

@@ -144,7 +144,8 @@ fun ProfileScreen(
onNavigateToSafety: () -> Unit = {},
onNavigateToLogs: () -> Unit = {},
viewModel: ProfileViewModel = androidx.lifecycle.viewmodel.compose.viewModel(),
avatarRepository: AvatarRepository? = null
avatarRepository: AvatarRepository? = null,
dialogDao: com.rosetta.messenger.database.DialogDao? = null
) {
val context = LocalContext.current
val activity = context as? FragmentActivity
@@ -169,32 +170,46 @@ fun ProfileScreen(
val imagePickerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent()
) { uri: Uri? ->
Log.d(TAG, "🖼️ Image picker result: uri=$uri")
uri?.let {
scope.launch {
try {
Log.d(TAG, "📁 Reading image from URI: $uri")
// Читаем файл изображения
val inputStream = context.contentResolver.openInputStream(uri)
val imageBytes = inputStream?.readBytes()
inputStream?.close()
Log.d(TAG, "📊 Image bytes read: ${imageBytes?.size ?: 0} bytes")
if (imageBytes != null) {
Log.d(TAG, "🔄 Converting to PNG Base64...")
// Конвертируем в PNG Base64 (кросс-платформенная совместимость)
val base64Png = withContext(Dispatchers.IO) {
AvatarFileManager.imagePrepareForNetworkTransfer(context, imageBytes)
}
Log.d(TAG, "✅ Converted to Base64: ${base64Png.length} chars")
Log.d(TAG, "🔐 Avatar repository available: ${avatarRepository != null}")
Log.d(TAG, "👤 Current public key: ${accountPublicKey.take(16)}...")
// Сохраняем аватар через репозиторий
Log.d(TAG, "💾 Calling avatarRepository.changeMyAvatar()...")
avatarRepository?.changeMyAvatar(base64Png)
Log.d(TAG, "🎉 Avatar update completed")
// Показываем успешное сообщение
android.widget.Toast.makeText(
context,
"Avatar updated successfully",
android.widget.Toast.LENGTH_SHORT
).show()
} else {
Log.e(TAG, "❌ Image bytes are null")
}
} catch (e: Exception) {
Log.e(TAG, "Failed to upload avatar", e)
Log.e(TAG, "Failed to upload avatar", e)
android.widget.Toast.makeText(
context,
"Failed to update avatar: ${e.message}",
@@ -202,7 +217,7 @@ fun ProfileScreen(
).show()
}
}
}
} ?: Log.w(TAG, "⚠️ URI is null, image picker cancelled")
}
// Цвета в зависимости от темы