fix: remove logs
This commit is contained in:
@@ -123,7 +123,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
Arrays.fill(passwordBytes, 0.toByte())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Encryption failed", e)
|
||||
onError("Ошибка шифрования: ${e.message}")
|
||||
}
|
||||
},
|
||||
@@ -131,11 +130,9 @@ class BiometricAuthManager(private val context: Context) {
|
||||
onCancel = onCancel
|
||||
)
|
||||
} catch (e: KeyPermanentlyInvalidatedException) {
|
||||
Log.e(TAG, "Key invalidated, removing and retrying", e)
|
||||
removeBiometricData()
|
||||
onError("Биометрические данные изменились. Пожалуйста, настройте заново.")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to initialize encryption", e)
|
||||
onError("Ошибка инициализации: ${e.message}")
|
||||
}
|
||||
}
|
||||
@@ -185,7 +182,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
decrypted = authenticatedCipher.doFinal(encrypted)
|
||||
onSuccess(String(decrypted, Charsets.UTF_8))
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Decryption failed", e)
|
||||
onError("Ошибка расшифровки: ${e.message}")
|
||||
} finally {
|
||||
// Secure memory wipe - обнуляем расшифрованные данные
|
||||
@@ -196,11 +192,9 @@ class BiometricAuthManager(private val context: Context) {
|
||||
onCancel = onCancel
|
||||
)
|
||||
} catch (e: KeyPermanentlyInvalidatedException) {
|
||||
Log.e(TAG, "Key permanently invalidated", e)
|
||||
removeBiometricData()
|
||||
onError("Биометрические данные изменились. Пожалуйста, войдите с паролем и настройте биометрию заново.")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to initialize decryption", e)
|
||||
onError("Ошибка инициализации: ${e.message}")
|
||||
}
|
||||
}
|
||||
@@ -222,8 +216,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
val callback = object : BiometricPrompt.AuthenticationCallback() {
|
||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||
super.onAuthenticationError(errorCode, errString)
|
||||
Log.d(TAG, "Authentication error: $errorCode - $errString")
|
||||
|
||||
when (errorCode) {
|
||||
BiometricPrompt.ERROR_USER_CANCELED,
|
||||
BiometricPrompt.ERROR_NEGATIVE_BUTTON,
|
||||
@@ -237,8 +229,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
|
||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||
super.onAuthenticationSucceeded(result)
|
||||
Log.d(TAG, "Authentication succeeded")
|
||||
|
||||
// Получаем аутентифицированный Cipher из CryptoObject
|
||||
val authenticatedCipher = result.cryptoObject?.cipher
|
||||
if (authenticatedCipher != null) {
|
||||
@@ -250,8 +240,7 @@ class BiometricAuthManager(private val context: Context) {
|
||||
|
||||
override fun onAuthenticationFailed() {
|
||||
super.onAuthenticationFailed()
|
||||
Log.d(TAG, "Authentication failed (user can retry)")
|
||||
// Не вызываем onError - пользователь может попробовать снова
|
||||
// Не вызываем onError - пользователь может попробовать снова
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +301,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
try {
|
||||
builder.setAttestationChallenge(generateAttestationChallenge())
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Key attestation not supported", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +309,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
try {
|
||||
builder.setIsStrongBoxBacked(true)
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "StrongBox not available, using TEE", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +323,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
return try {
|
||||
keyStore.getKey(KEY_ALIAS, null) as? SecretKey
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to get key from Keystore", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
@@ -349,10 +335,8 @@ class BiometricAuthManager(private val context: Context) {
|
||||
try {
|
||||
if (keyStore.containsAlias(KEY_ALIAS)) {
|
||||
keyStore.deleteEntry(KEY_ALIAS)
|
||||
Log.d(TAG, "Biometric key removed from Keystore")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to remove key from Keystore", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,7 +380,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
try {
|
||||
certificateChain[i].verify(certificateChain[i + 1].publicKey)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Certificate chain verification failed at index $i", e)
|
||||
return KeyAttestationResult.Invalid("Цепочка сертификатов недействительна")
|
||||
}
|
||||
}
|
||||
@@ -406,14 +389,12 @@ class BiometricAuthManager(private val context: Context) {
|
||||
if (leafCert != null) {
|
||||
val attestationExtension = leafCert.getExtensionValue("1.3.6.1.4.1.11129.2.1.17")
|
||||
if (attestationExtension != null) {
|
||||
Log.d(TAG, "Key attestation verified - key is in secure hardware")
|
||||
return KeyAttestationResult.Valid(isStrongBox = isKeyInStrongBox())
|
||||
}
|
||||
}
|
||||
|
||||
KeyAttestationResult.NotSupported
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Key attestation verification failed", e)
|
||||
KeyAttestationResult.Invalid(e.message ?: "Unknown error")
|
||||
}
|
||||
}
|
||||
@@ -437,7 +418,6 @@ class BiometricAuthManager(private val context: Context) {
|
||||
keyInfo.isInsideSecureHardware
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Could not determine if key is in StrongBox", e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ class BiometricPreferences(private val context: Context) {
|
||||
try {
|
||||
_isBiometricEnabled.value = encryptedPrefs.getBoolean(KEY_BIOMETRIC_ENABLED, false)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to read biometric enabled state", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +62,6 @@ class BiometricPreferences(private val context: Context) {
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to create EncryptedSharedPreferences, falling back", e)
|
||||
// Fallback на обычные SharedPreferences в случае ошибки (не должно произойти)
|
||||
return context.getSharedPreferences(PREFS_FILE_NAME + "_fallback", Context.MODE_PRIVATE)
|
||||
}
|
||||
@@ -97,7 +95,6 @@ class BiometricPreferences(private val context: Context) {
|
||||
suspend fun saveEncryptedPassword(publicKey: String, encryptedPassword: String) = withContext(Dispatchers.IO) {
|
||||
val key = "$ENCRYPTED_PASSWORD_PREFIX$publicKey"
|
||||
encryptedPrefs.edit().putString(key, encryptedPassword).apply()
|
||||
Log.d(TAG, "Encrypted password saved for account")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +111,6 @@ class BiometricPreferences(private val context: Context) {
|
||||
suspend fun removeEncryptedPassword(publicKey: String) = withContext(Dispatchers.IO) {
|
||||
val key = "$ENCRYPTED_PASSWORD_PREFIX$publicKey"
|
||||
encryptedPrefs.edit().remove(key).apply()
|
||||
Log.d(TAG, "Encrypted password removed for account")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +119,6 @@ class BiometricPreferences(private val context: Context) {
|
||||
suspend fun clearAll() = withContext(Dispatchers.IO) {
|
||||
encryptedPrefs.edit().clear().apply()
|
||||
_isBiometricEnabled.value = false
|
||||
Log.d(TAG, "All biometric data cleared")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -347,7 +347,6 @@ fun ChatDetailScreen(
|
||||
// 🔥 КРИТИЧНО: Дедупликация по ID перед сортировкой!
|
||||
val uniqueMessages = messages.distinctBy { it.id }
|
||||
if (uniqueMessages.size != messages.size) {
|
||||
android.util.Log.e("ChatDetailScreen", "🚨 DEDUPLICATED ${messages.size - uniqueMessages.size} messages in UI! Original: ${messages.map { it.id }}")
|
||||
}
|
||||
|
||||
// Сортируем по времени (новые -> старые) для reversed layout
|
||||
|
||||
@@ -264,9 +264,6 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val allIds = newList.map { it.id }
|
||||
val duplicates = allIds.groupBy { it }.filter { it.value.size > 1 }.keys
|
||||
if (duplicates.isNotEmpty()) {
|
||||
android.util.Log.e("ChatViewModel", "🚨 DUPLICATE IDS FOUND in pollLatestMessages: $duplicates")
|
||||
android.util.Log.e("ChatViewModel", " currentList ids: ${currentList.map { it.id }}")
|
||||
android.util.Log.e("ChatViewModel", " newMessages ids: ${newMessages.map { it.id }}")
|
||||
}
|
||||
|
||||
_messages.value = newList
|
||||
@@ -377,13 +374,10 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private fun addMessageSafely(message: ChatMessage): Boolean {
|
||||
val currentMessages = _messages.value
|
||||
val currentIds = currentMessages.map { it.id }.toSet()
|
||||
android.util.Log.d("ChatViewModel", "🔍 addMessageSafely: id=${message.id}, currentCount=${currentMessages.size}, ids=${currentIds.take(5)}...")
|
||||
if (message.id in currentIds) {
|
||||
android.util.Log.e("ChatViewModel", "🚨 BLOCKED DUPLICATE: id=${message.id} already exists in ${currentIds.size} messages!")
|
||||
if (message.id in currentIds) {
|
||||
return false
|
||||
}
|
||||
_messages.value = currentMessages + message
|
||||
android.util.Log.d("ChatViewModel", "✅ Added message: id=${message.id}, newCount=${_messages.value.size}")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -595,22 +589,17 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
withContext(Dispatchers.Main.immediate) {
|
||||
val dbIds = messages.map { it.id }.toSet()
|
||||
val currentMsgs = _messages.value
|
||||
android.util.Log.d("ChatViewModel", "📥 loadMessages: dbCount=${messages.size}, currentCount=${currentMsgs.size}")
|
||||
android.util.Log.d("ChatViewModel", " DB ids: ${dbIds.take(5)}...")
|
||||
android.util.Log.d("ChatViewModel", " Current ids: ${currentMsgs.map { it.id }.take(5)}...")
|
||||
android.util.Log.d("ChatViewModel", " Current ids: ${currentMsgs.map { it.id }.take(5)}...")
|
||||
|
||||
val optimisticMessages = currentMsgs.filter { msg ->
|
||||
msg.status == MessageStatus.SENDING && msg.id !in dbIds
|
||||
}
|
||||
android.util.Log.d("ChatViewModel", " Optimistic (SENDING, not in DB): ${optimisticMessages.size} - ${optimisticMessages.map { it.id }}")
|
||||
|
||||
val newList = messages + optimisticMessages
|
||||
val newList = messages + optimisticMessages
|
||||
|
||||
// 🔍 Финальная дедупликация по ID (на всякий случай)
|
||||
val deduplicatedList = newList.distinctBy { it.id }
|
||||
|
||||
if (deduplicatedList.size != newList.size) {
|
||||
android.util.Log.e("ChatViewModel", "🚨 DEDUPLICATED ${newList.size - deduplicatedList.size} messages!")
|
||||
}
|
||||
|
||||
_messages.value = deduplicatedList
|
||||
|
||||
@@ -242,9 +242,7 @@ fun ImageEditorScreen(
|
||||
lastStableKeyboardHeight = currentImeHeight
|
||||
}
|
||||
// 📊 Log IME height changes
|
||||
Log.d(TAG, "⌨️ IME: height=${currentImeHeight.value}dp, wasVisible=$wasKeyboardVisible, isVisible=$isKeyboardVisible, emojiBoxVisible=${coordinator.isEmojiBoxVisible}")
|
||||
if (wasKeyboardVisible != isKeyboardVisible) {
|
||||
Log.d(TAG, "⌨️ KEYBOARD STATE CHANGED: $wasKeyboardVisible → $isKeyboardVisible")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,12 +271,8 @@ fun ImageEditorScreen(
|
||||
lastToggleTime = currentTime
|
||||
|
||||
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
|
||||
Log.d(TAG, "toggleEmojiPicker: isEmojiVisible=${coordinator.isEmojiVisible}, isEmojiBoxVisible=${coordinator.isEmojiBoxVisible}, showEmojiPicker=$showEmojiPicker")
|
||||
|
||||
if (coordinator.isEmojiVisible) {
|
||||
// EMOJI → KEYBOARD
|
||||
Log.d(TAG, "TRANSITION: EMOJI → KEYBOARD")
|
||||
coordinator.requestShowKeyboard(
|
||||
showKeyboard = {
|
||||
editTextView?.let { editText ->
|
||||
@@ -290,7 +284,6 @@ fun ImageEditorScreen(
|
||||
)
|
||||
} else {
|
||||
// KEYBOARD → EMOJI
|
||||
Log.d(TAG, "TRANSITION: KEYBOARD → EMOJI")
|
||||
coordinator.requestShowEmoji(
|
||||
hideKeyboard = { imm.hideSoftInputFromWindow(view.windowToken, 0) },
|
||||
showEmoji = { showEmojiPicker = true }
|
||||
@@ -1165,7 +1158,7 @@ private fun TelegramCaptionBar(
|
||||
}
|
||||
}
|
||||
|
||||
/** Save edited image and return the URI - crops black bars from FIT_CENTER */
|
||||
/** Save edited image and return the URI - returns original if no edits, otherwise crops black bars */
|
||||
private suspend fun saveEditedImage(
|
||||
context: Context,
|
||||
photoEditor: PhotoEditor?,
|
||||
@@ -1174,12 +1167,15 @@ private suspend fun saveEditedImage(
|
||||
onResult: (Uri?) -> Unit
|
||||
) {
|
||||
if (photoEditor == null || photoEditorView == null) {
|
||||
onResult(null)
|
||||
// Нет редактора - возвращаем оригинал
|
||||
onResult(imageUri)
|
||||
return
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
// Загружаем оригинальное изображение и сохраняем его напрямую
|
||||
// PhotoEditor с setClipSourceImage(true) должен обрезать черные полосы автоматически
|
||||
val tempFile = File(context.cacheDir, "temp_${System.currentTimeMillis()}.png")
|
||||
|
||||
val saveSettings = SaveSettings.Builder()
|
||||
@@ -1187,7 +1183,6 @@ private suspend fun saveEditedImage(
|
||||
.setTransparencyEnabled(true)
|
||||
.build()
|
||||
|
||||
// Сохраняем полный view (с черными полосами)
|
||||
val savedPath = suspendCancellableCoroutine<String?> { continuation ->
|
||||
photoEditor.saveAsFile(
|
||||
tempFile.absolutePath,
|
||||
@@ -1204,7 +1199,8 @@ private suspend fun saveEditedImage(
|
||||
}
|
||||
|
||||
if (savedPath == null) {
|
||||
withContext(Dispatchers.Main) { onResult(null) }
|
||||
// Ошибка сохранения - возвращаем оригинал
|
||||
withContext(Dispatchers.Main) { onResult(imageUri) }
|
||||
return@withContext
|
||||
}
|
||||
|
||||
@@ -1215,7 +1211,7 @@ private suspend fun saveEditedImage(
|
||||
return@withContext
|
||||
}
|
||||
|
||||
// Получаем РЕАЛЬНЫЕ размеры изображения из URI (не из drawable!)
|
||||
// Получаем размеры оригинального изображения
|
||||
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
context.contentResolver.openInputStream(imageUri)?.use { stream ->
|
||||
BitmapFactory.decodeStream(stream, null, options)
|
||||
@@ -1232,6 +1228,17 @@ private suspend fun saveEditedImage(
|
||||
val viewWidth = savedBitmap.width
|
||||
val viewHeight = savedBitmap.height
|
||||
|
||||
// Соотношение сторон оригинала и сохраненного
|
||||
val originalRatio = imageWidth.toFloat() / imageHeight
|
||||
val savedRatio = viewWidth.toFloat() / viewHeight
|
||||
|
||||
// Если соотношения примерно равны - черных полос нет, возвращаем как есть
|
||||
if (kotlin.math.abs(originalRatio - savedRatio) < 0.01f) {
|
||||
savedBitmap.recycle()
|
||||
withContext(Dispatchers.Main) { onResult(Uri.fromFile(tempFile)) }
|
||||
return@withContext
|
||||
}
|
||||
|
||||
// Вычисляем где находится изображение (FIT_CENTER логика)
|
||||
val scale = minOf(
|
||||
viewWidth.toFloat() / imageWidth,
|
||||
@@ -1244,13 +1251,15 @@ private suspend fun saveEditedImage(
|
||||
val left = ((viewWidth - scaledWidth) / 2).coerceAtLeast(0)
|
||||
val top = ((viewHeight - scaledHeight) / 2).coerceAtLeast(0)
|
||||
|
||||
// Обрезаем черные полосы
|
||||
val cropWidth = scaledWidth.coerceIn(1, viewWidth - left)
|
||||
val cropHeight = scaledHeight.coerceIn(1, viewHeight - top)
|
||||
// Обрезаем черные полосы
|
||||
val croppedBitmap = Bitmap.createBitmap(
|
||||
savedBitmap,
|
||||
left,
|
||||
top,
|
||||
scaledWidth.coerceAtMost(viewWidth - left),
|
||||
scaledHeight.coerceAtMost(viewHeight - top)
|
||||
cropWidth,
|
||||
cropHeight
|
||||
)
|
||||
|
||||
// Сохраняем обрезанное изображение
|
||||
@@ -1267,19 +1276,23 @@ private suspend fun saveEditedImage(
|
||||
onResult(Uri.fromFile(finalFile))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) { onResult(null) }
|
||||
// При ошибке возвращаем оригинал
|
||||
withContext(Dispatchers.Main) { onResult(imageUri) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Save edited image synchronously - crops black bars from FIT_CENTER */
|
||||
/** Save edited image synchronously - returns original if no edits, otherwise crops black bars */
|
||||
private suspend fun saveEditedImageSync(
|
||||
context: Context,
|
||||
photoEditor: PhotoEditor?,
|
||||
photoEditorView: PhotoEditorView?,
|
||||
imageUri: Uri
|
||||
): Uri? {
|
||||
if (photoEditor == null || photoEditorView == null) return null
|
||||
if (photoEditor == null || photoEditorView == null) {
|
||||
// Нет редактора - возвращаем оригинал
|
||||
return imageUri
|
||||
}
|
||||
|
||||
return withContext(Dispatchers.IO) {
|
||||
try {
|
||||
@@ -1308,13 +1321,16 @@ private suspend fun saveEditedImageSync(
|
||||
)
|
||||
}
|
||||
|
||||
if (savedPath == null) return@withContext null
|
||||
if (savedPath == null) {
|
||||
// Ошибка - возвращаем оригинал
|
||||
return@withContext imageUri
|
||||
}
|
||||
|
||||
// Загружаем сохраненное изображение
|
||||
val savedBitmap = BitmapFactory.decodeFile(savedPath)
|
||||
?: return@withContext Uri.fromFile(tempFile)
|
||||
|
||||
// Получаем РЕАЛЬНЫЕ размеры изображения из URI (не из drawable!)
|
||||
// Получаем размеры оригинального изображения
|
||||
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
context.contentResolver.openInputStream(imageUri)?.use { stream ->
|
||||
BitmapFactory.decodeStream(stream, null, options)
|
||||
@@ -1330,6 +1346,16 @@ private suspend fun saveEditedImageSync(
|
||||
val viewWidth = savedBitmap.width
|
||||
val viewHeight = savedBitmap.height
|
||||
|
||||
// Соотношение сторон оригинала и сохраненного
|
||||
val originalRatio = imageWidth.toFloat() / imageHeight
|
||||
val savedRatio = viewWidth.toFloat() / viewHeight
|
||||
|
||||
// Если соотношения примерно равны - черных полос нет
|
||||
if (kotlin.math.abs(originalRatio - savedRatio) < 0.01f) {
|
||||
savedBitmap.recycle()
|
||||
return@withContext Uri.fromFile(tempFile)
|
||||
}
|
||||
|
||||
// Вычисляем где находится изображение (FIT_CENTER логика)
|
||||
val scale = minOf(
|
||||
viewWidth.toFloat() / imageWidth,
|
||||
@@ -1342,13 +1368,15 @@ private suspend fun saveEditedImageSync(
|
||||
val left = ((viewWidth - scaledWidth) / 2).coerceAtLeast(0)
|
||||
val top = ((viewHeight - scaledHeight) / 2).coerceAtLeast(0)
|
||||
|
||||
// Обрезаем черные полосы
|
||||
val cropWidth = scaledWidth.coerceIn(1, viewWidth - left)
|
||||
val cropHeight = scaledHeight.coerceIn(1, viewHeight - top)
|
||||
// Обрезаем черные полосы
|
||||
val croppedBitmap = Bitmap.createBitmap(
|
||||
savedBitmap,
|
||||
left,
|
||||
top,
|
||||
scaledWidth.coerceAtMost(viewWidth - left),
|
||||
scaledHeight.coerceAtMost(viewHeight - top)
|
||||
cropWidth,
|
||||
cropHeight
|
||||
)
|
||||
|
||||
// Сохраняем обрезанное изображение
|
||||
@@ -1366,7 +1394,8 @@ private suspend fun saveEditedImageSync(
|
||||
|
||||
Uri.fromFile(finalFile)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
// При ошибке возвращаем оригинал
|
||||
imageUri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,7 +1440,6 @@ fun PhotoPreviewWithCaptionScreen(
|
||||
coordinator.syncHeights()
|
||||
lastStableKeyboardHeight = currentImeHeight
|
||||
}
|
||||
Log.d("PhotoPreview", "IME height: ${currentImeHeight.value}dp, isKeyboardVisible: $isKeyboardVisible, emojiHeight: ${coordinator.emojiHeight.value}dp, isEmojiBoxVisible: ${coordinator.isEmojiBoxVisible}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1464,7 +1463,6 @@ fun PhotoPreviewWithCaptionScreen(
|
||||
fun toggleEmojiPicker() {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastToggleTime < toggleCooldownMs) {
|
||||
Log.d("PhotoPreview", "Toggle blocked by cooldown")
|
||||
return
|
||||
}
|
||||
lastToggleTime = currentTime
|
||||
@@ -1473,30 +1471,24 @@ fun PhotoPreviewWithCaptionScreen(
|
||||
|
||||
if (coordinator.isEmojiVisible) {
|
||||
// EMOJI → KEYBOARD
|
||||
Log.d("PhotoPreview", "TOGGLE: Emoji → Keyboard")
|
||||
coordinator.requestShowKeyboard(
|
||||
showKeyboard = {
|
||||
Log.d("PhotoPreview", "Showing keyboard...")
|
||||
editTextView?.let { editText ->
|
||||
editText.requestFocus()
|
||||
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
|
||||
}
|
||||
},
|
||||
hideEmoji = {
|
||||
Log.d("PhotoPreview", "Hiding emoji picker")
|
||||
showEmojiPicker = false
|
||||
}
|
||||
)
|
||||
} else {
|
||||
// KEYBOARD → EMOJI
|
||||
Log.d("PhotoPreview", "TOGGLE: Keyboard → Emoji")
|
||||
coordinator.requestShowEmoji(
|
||||
hideKeyboard = {
|
||||
Log.d("PhotoPreview", "Hiding keyboard...")
|
||||
imm.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
},
|
||||
showEmoji = {
|
||||
Log.d("PhotoPreview", "Showing emoji picker")
|
||||
showEmojiPicker = true
|
||||
}
|
||||
)
|
||||
@@ -1508,8 +1500,6 @@ fun PhotoPreviewWithCaptionScreen(
|
||||
val shouldAddNavBarPadding = !isKeyboardVisible && !coordinator.isEmojiBoxVisible
|
||||
|
||||
// Логируем состояние при каждой рекомпозиции
|
||||
Log.d("PhotoPreview", "RENDER: showEmoji=$showEmojiPicker, isKeyboard=$isKeyboardVisible, isEmojiBoxVisible=${coordinator.isEmojiBoxVisible}, useImePadding=$shouldUseImePadding, emojiHeight=${coordinator.emojiHeight.value}dp")
|
||||
|
||||
Surface(
|
||||
color = backgroundColor,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
|
||||
@@ -286,9 +286,6 @@ private fun computeAvatarState(
|
||||
val showBlob = collapseProgress < ProfileMetaballConstants.MERGE_COMPLETE_PROGRESS && radius > 1f
|
||||
|
||||
// DEBUG LOG
|
||||
Log.d("Metaball", "collapse=$collapseProgress, expansion=$expansionProgress, radius=$radius, diff=$diff")
|
||||
Log.d("Metaball", "centerY=$centerY, cornerRadius=$cornerRadius, isDrawing=$isDrawing, isNear=$isNear")
|
||||
|
||||
return AvatarState(
|
||||
centerX = centerX,
|
||||
centerY = centerY,
|
||||
|
||||
@@ -259,8 +259,6 @@ fun OtherProfileScreen(
|
||||
}
|
||||
|
||||
// DEBUG LOGS
|
||||
Log.d("OtherProfileScroll", "expansionProgress=$expansionProgress, isPulledDown=$isPulledDown, isDragging=$isDragging")
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// NESTED SCROLL - Telegram style with overscroll support
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -588,7 +588,6 @@ private suspend fun loadPhotos(context: Context): List<PhotoItem> = withContext(
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.e(TAG, "Error loading photos: ${e.message}", e)
|
||||
}
|
||||
|
||||
items
|
||||
|
||||
@@ -401,8 +401,6 @@ fun ProfileScreen(
|
||||
}
|
||||
|
||||
// DEBUG LOGS
|
||||
Log.d("ProfileScroll", "expansionProgress=$expansionProgress, isPulledDown=$isPulledDown, isDragging=$isDragging")
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// NESTED SCROLL - Telegram style
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user