fix: add detailed logging for unlock process to improve debugging and performance tracking

This commit is contained in:
2026-02-05 01:56:18 +05:00
parent e307e8d35d
commit 4dc7c6e9bc
13 changed files with 640 additions and 169 deletions

View File

@@ -294,7 +294,8 @@ fun ChatDetailScreen(
val isOnline by viewModel.opponentOnline.collectAsState()
val isLoading by viewModel.isLoading.collectAsState() // 🔥 Для скелетона
// 🔥 Reply/Forward state
// <20>🔥 Reply/Forward state
val replyMessages by viewModel.replyMessages.collectAsState()
val hasReply = replyMessages.isNotEmpty()
val isForwardMode by viewModel.isForwardMode.collectAsState()

View File

@@ -251,12 +251,21 @@ fun ChatsListScreen(
// Load dialogs when account is available
LaunchedEffect(accountPublicKey, accountPrivateKey) {
if (accountPublicKey.isNotEmpty() && accountPrivateKey.isNotEmpty()) {
val launchStart = System.currentTimeMillis()
android.util.Log.d("ChatsListScreen", "🚀 LaunchedEffect started")
chatsViewModel.setAccount(accountPublicKey, accountPrivateKey)
android.util.Log.d("ChatsListScreen", "📋 setAccount took ${System.currentTimeMillis() - launchStart}ms")
// Устанавливаем аккаунт для RecentSearchesManager
RecentSearchesManager.setAccount(accountPublicKey)
// 🔥 КРИТИЧНО: Инициализируем MessageRepository для обработки входящих
// сообщений
val initStart = System.currentTimeMillis()
ProtocolManager.initializeAccount(accountPublicKey, accountPrivateKey)
android.util.Log.d("ChatsListScreen", "🌐 initializeAccount took ${System.currentTimeMillis() - initStart}ms")
android.util.Log.d("ChatsListScreen", "✅ Total LaunchedEffect: ${System.currentTimeMillis() - launchStart}ms")
}
}

View File

@@ -105,11 +105,17 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
private val _isLoading = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
private val TAG = "ChatsListVM"
/**
* Установить текущий аккаунт и загрузить диалоги
*/
fun setAccount(publicKey: String, privateKey: String) {
val setAccountStart = System.currentTimeMillis()
android.util.Log.d(TAG, "📋 setAccount called for: ${publicKey.take(8)}...")
if (currentAccount == publicKey) {
android.util.Log.d(TAG, "📋 Account already set, skipping")
return
}
@@ -119,11 +125,15 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
currentAccount = publicKey
currentPrivateKey = privateKey
android.util.Log.d(TAG, "📋 Starting dialogs subscription...")
// Подписываемся на обычные диалоги
viewModelScope.launch {
dialogDao.getDialogsFlow(publicKey)
.flowOn(Dispatchers.IO) // 🚀 Flow работает на IO
.map { dialogsList ->
val mapStart = System.currentTimeMillis()
android.util.Log.d(TAG, "🔄 Processing ${dialogsList.size} dialogs...")
// <20> ОПТИМИЗАЦИЯ: Параллельная расшифровка всех сообщений
withContext(Dispatchers.Default) {
dialogsList.map { dialog ->
@@ -194,10 +204,14 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
)
}
}.awaitAll()
}.also {
val mapTime = System.currentTimeMillis() - mapStart
android.util.Log.d(TAG, "🔄 Dialogs processed in ${mapTime}ms (${dialogsList.size} items)")
}
}
.distinctUntilChanged() // 🔥 ИСПРАВЛЕНИЕ: Игнорируем дублирующиеся списки
.collect { decryptedDialogs ->
android.util.Log.d(TAG, "✅ Dialogs collected: ${decryptedDialogs.size} items")
_dialogs.value = decryptedDialogs
// 🟢 Подписываемся на онлайн-статусы всех собеседников

View File

@@ -704,43 +704,43 @@ fun MessageBubble(
}
)
} else if (!hasOnlyMedia && !hasImageWithCaption && message.text.isNotEmpty()) {
// Telegram-style: текст + время с автоматическим переносом
TelegramStyleMessageContent(
textContent = {
AppleEmojiText(
text = message.text,
color = textColor,
fontSize = 17.sp,
linkColor = linkColor
)
},
timeContent = {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(2.dp)
) {
Text(
text = timeFormat.format(message.timestamp),
color = timeColor,
fontSize = 11.sp,
fontStyle =
androidx.compose.ui.text.font.FontStyle.Italic
// Telegram-style: текст + время с автоматическим переносом
TelegramStyleMessageContent(
textContent = {
AppleEmojiText(
text = message.text,
color = textColor,
fontSize = 17.sp,
linkColor = linkColor
)
if (message.isOutgoing) {
val displayStatus =
if (isSavedMessages) MessageStatus.READ
else message.status
AnimatedMessageStatus(
status = displayStatus,
timeColor = timeColor,
timestamp = message.timestamp.time,
onRetry = onRetry,
onDelete = onDelete
},
timeContent = {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(2.dp)
) {
Text(
text = timeFormat.format(message.timestamp),
color = timeColor,
fontSize = 11.sp,
fontStyle =
androidx.compose.ui.text.font.FontStyle.Italic
)
if (message.isOutgoing) {
val displayStatus =
if (isSavedMessages) MessageStatus.READ
else message.status
AnimatedMessageStatus(
status = displayStatus,
timeColor = timeColor,
timestamp = message.timestamp.time,
onRetry = onRetry,
onDelete = onDelete
)
}
}
}
}
)
)
}
}
}

View File

@@ -116,6 +116,15 @@ fun MediaPickerBottomSheet(
val context = LocalContext.current
val scope = rememberCoroutineScope()
val density = LocalDensity.current
val focusManager = LocalFocusManager.current
val keyboardView = LocalView.current
// Function to hide keyboard
fun hideKeyboard() {
focusManager.clearFocus()
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(keyboardView.windowToken, 0)
}
// Media items from gallery
var mediaItems by remember { mutableStateOf<List<MediaItem>>(emptyList()) }
@@ -496,6 +505,7 @@ fun MediaPickerBottomSheet(
QuickActionsRow(
isDarkTheme = isDarkTheme,
onCameraClick = {
hideKeyboard()
animatedClose()
onOpenCamera()
},
@@ -578,6 +588,7 @@ fun MediaPickerBottomSheet(
mediaItems = mediaItems,
selectedItems = selectedItems,
onCameraClick = {
hideKeyboard()
animatedClose()
onOpenCamera()
},
@@ -1222,11 +1233,11 @@ private fun MediaGridItem(
contentAlignment = Alignment.Center
) {
if (isSelected) {
Text(
text = "$selectionIndex",
color = Color.White,
fontSize = 12.sp,
fontWeight = FontWeight.Bold
Icon(
imageVector = TablerIcons.Check,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(16.dp)
)
}
}

View File

@@ -8,6 +8,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import compose.icons.TablerIcons
import compose.icons.tablericons.*
@@ -16,9 +17,11 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
@@ -30,6 +33,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.rosette.android.ui.keyboard.AnimatedKeyboardTransition
import app.rosette.android.ui.keyboard.KeyboardTransitionCoordinator
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.rosetta.messenger.network.AttachmentType
import com.rosetta.messenger.ui.components.AppleEmojiTextField
import com.rosetta.messenger.ui.components.OptimizedEmojiPicker
@@ -48,6 +53,7 @@ import kotlinx.coroutines.launch
* Telegram UX rules:
* 1. Input always linked to keyboard (imePadding)
* 2. Last message always visible
* 3. No layout jumps
* 4. After sending: input clears, keyboard stays open
* 5. Input grows upward for multi-line (up to 6 lines)