feat: Implement baseline profile generation and startup benchmarking
- Added baseline profile generator for Rosetta Messenger to optimize startup performance. - Created startup benchmark tests to measure cold start times under different compilation modes. - Introduced a new Gradle module for baseline profile and benchmark tests. - Updated ChatsListViewModel to show loading skeleton while data is being fetched. - Improved keyboard handling in MessageInputBar by using SHOW_IMPLICIT instead of SHOW_FORCED. - Minor code cleanups and optimizations across various components.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -117,11 +117,18 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
return
|
||||
}
|
||||
|
||||
// 🔥 Показываем skeleton пока данные грузятся
|
||||
_isLoading.value = true
|
||||
|
||||
// 🔥 Очищаем кэш запрошенных user info при смене аккаунта
|
||||
requestedUserInfoKeys.clear()
|
||||
|
||||
currentAccount = publicKey
|
||||
currentPrivateKey = privateKey
|
||||
|
||||
// 🚀 Pre-warm PBKDF2 ключ — чтобы к моменту дешифровки кэш был горячий
|
||||
viewModelScope.launch(Dispatchers.Default) { CryptoManager.getPbkdf2Key(privateKey) }
|
||||
|
||||
// Подписываемся на обычные диалоги
|
||||
@OptIn(FlowPreview::class)
|
||||
viewModelScope.launch {
|
||||
@@ -268,6 +275,8 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
.distinctUntilChanged() // 🔥 ИСПРАВЛЕНИЕ: Игнорируем дублирующиеся списки
|
||||
.collect { decryptedDialogs ->
|
||||
_dialogs.value = decryptedDialogs
|
||||
// 🚀 Убираем skeleton после первой загрузки
|
||||
if (_isLoading.value) _isLoading.value = false
|
||||
|
||||
// 🟢 Подписываемся на онлайн-статусы всех собеседников
|
||||
// 📁 Исключаем Saved Messages - не нужно подписываться на свой собственный
|
||||
|
||||
@@ -25,7 +25,7 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -89,7 +89,6 @@ fun MessageInputBar(
|
||||
inputFocusTrigger: Int = 0
|
||||
) {
|
||||
val hasReply = replyMessages.isNotEmpty()
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
@@ -206,7 +205,8 @@ fun MessageInputBar(
|
||||
showKeyboard = {
|
||||
editTextView?.let { editText ->
|
||||
editText.requestFocus()
|
||||
imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED)
|
||||
@Suppress("DEPRECATION")
|
||||
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
|
||||
}
|
||||
},
|
||||
hideEmoji = { onToggleEmojiPicker(false) }
|
||||
|
||||
@@ -214,7 +214,7 @@ private fun OnlineIndicator(modifier: Modifier = Modifier) {
|
||||
*/
|
||||
@Composable
|
||||
fun AvatarPicker(
|
||||
onAvatarSelected: (String) -> Unit
|
||||
@Suppress("UNUSED_PARAMETER") onAvatarSelected: (String) -> Unit
|
||||
) {
|
||||
// TODO: Реализовать выбор изображения через ActivityResultContract
|
||||
// 1. Использовать rememberLauncherForActivityResult с ActivityResultContracts.GetContent()
|
||||
|
||||
@@ -129,7 +129,6 @@ object OptimizedEmojiCache {
|
||||
isPreloading = true
|
||||
|
||||
// Берем первые N эмодзи из категории Smileys (самые популярные)
|
||||
val smileyCategory = EMOJI_CATEGORIES.find { it.key == "Smileys" }
|
||||
val smileysToPreload = emojisByCategory?.get("Smileys")
|
||||
?.take(PRELOAD_COUNT)
|
||||
?: emptyList()
|
||||
|
||||
Reference in New Issue
Block a user