Refactor image handling and decoding logic

- Introduced a maximum bitmap decode dimension to prevent excessive memory usage.
- Enhanced base64 to bitmap conversion by extracting payload and applying EXIF orientation.
- Improved error handling for image downloads and decoding processes.
- Simplified media picker and chat input components to manage keyboard visibility more effectively.
- Updated color selection grid to adaptively adjust based on available width.
- Added safety checks for notifications and call actions in profile screens.
- Optimized bitmap decoding in uriToBase64Image to handle large images more efficiently.
This commit is contained in:
2026-02-20 02:45:00 +05:00
parent 5cf8b2866f
commit 88e2084f8b
26 changed files with 943 additions and 464 deletions

View File

@@ -863,7 +863,7 @@ class MessageRepository private constructor(private val context: Context) {
currentList[existingIndex] = message
} else {
currentList.add(message)
currentList.sortBy { it.timestamp }
currentList.sortWith(compareBy<Message>({ it.timestamp }, { it.messageId }))
}
flow.value = currentList
}
@@ -1018,12 +1018,13 @@ class MessageRepository private constructor(private val context: Context) {
val decryptedText =
if (privateKey != null && plainMessage.isNotEmpty()) {
try {
CryptoManager.decryptWithPassword(plainMessage, privateKey) ?: plainMessage
CryptoManager.decryptWithPassword(plainMessage, privateKey)
?: safePlainMessageFallback(plainMessage)
} catch (e: Exception) {
plainMessage // Fallback на зашифрованный текст если расшифровка не удалась
safePlainMessageFallback(plainMessage)
}
} else {
plainMessage
safePlainMessageFallback(plainMessage)
}
return Message(
@@ -1040,6 +1041,27 @@ class MessageRepository private constructor(private val context: Context) {
)
}
/**
* Не показываем пользователю шифротекст (`CHNK:`/`iv:ciphertext`) если дешифровка не удалась.
*/
private fun safePlainMessageFallback(raw: String): String {
if (raw.isBlank()) return ""
return if (isProbablyEncryptedPayload(raw)) "" else raw
}
private fun isProbablyEncryptedPayload(value: String): Boolean {
val trimmed = value.trim()
if (trimmed.startsWith("CHNK:")) return true
val parts = trimmed.split(":")
if (parts.size != 2) return false
return parts.all { part ->
part.length >= 16 && part.all { ch ->
ch.isLetterOrDigit() || ch == '+' || ch == '/' || ch == '='
}
}
}
private fun DialogEntity.toDialog() =
Dialog(
opponentKey = opponentKey,