Refactor code structure for improved readability and maintainability

This commit is contained in:
k1ngsterr1
2026-01-17 01:50:10 +05:00
parent 97eac22879
commit 14ea9e6996
6 changed files with 139 additions and 78 deletions

File diff suppressed because one or more lines are too long

View File

@@ -151,8 +151,10 @@ class MessageRepository private constructor(private val context: Context) {
attachments: List<MessageAttachment> = emptyList(),
replyToMessageId: String? = null
): Message {
android.util.Log.d("MessageRepo", "📤 sendMessage START: to=${toPublicKey.take(16)}...")
val account = currentAccount ?: throw IllegalStateException("Not initialized")
val privateKey = currentPrivateKey ?: throw IllegalStateException("Not initialized")
android.util.Log.d("MessageRepo", "📤 sendMessage: account=${account.take(16)}...")
val messageId = UUID.randomUUID().toString().replace("-", "").take(32)
val timestamp = System.currentTimeMillis()
@@ -217,7 +219,8 @@ class MessageRepository private constructor(private val context: Context) {
updateDialog(toPublicKey, text.trim(), timestamp)
// 🔥 Отмечаем что я отправлял сообщения в этот диалог (перемещает из requests в chats)
dialogDao.markIHaveSent(account, toPublicKey)
val updatedRows = dialogDao.markIHaveSent(account, toPublicKey)
android.util.Log.d("MessageRepo", "📤 MARKED i_have_sent=1 for opponent=${toPublicKey.take(16)}..., updatedRows=$updatedRows")
// Отправляем пакет
val packet = PacketMessage().apply {
@@ -536,10 +539,15 @@ class MessageRepository private constructor(private val context: Context) {
suspend fun updateDialogUserInfo(publicKey: String, title: String, username: String, verified: Int) {
val account = currentAccount ?: return
android.util.Log.d("MessageRepo", "📋 updateDialogUserInfo: publicKey=${publicKey.take(16)}..., title=$title, username=$username")
// Проверяем существует ли диалог с этим пользователем
val existing = dialogDao.getDialog(account, publicKey)
if (existing != null) {
android.util.Log.d("MessageRepo", "📋 Updating existing dialog info for ${publicKey.take(16)}...")
dialogDao.updateOpponentInfo(account, publicKey, title, username, verified)
} else {
android.util.Log.d("MessageRepo", "📋 Dialog not found for ${publicKey.take(16)}..., skipping")
}
}

View File

@@ -361,9 +361,10 @@ interface DialogDao {
/**
* Отметить что я отправлял сообщения в этот диалог
* Возвращает количество обновлённых строк
*/
@Query("UPDATE dialogs SET i_have_sent = 1 WHERE account = :account AND opponent_key = :opponentKey")
suspend fun markIHaveSent(account: String, opponentKey: String)
suspend fun markIHaveSent(account: String, opponentKey: String): Int
/**
* Обновить онлайн статус
@@ -417,7 +418,8 @@ interface DialogDao {
* Логика:
* 1. Берем последнее сообщение (по timestamp DESC)
* 2. Считаем количество непрочитанных сообщений (from_me = 0 AND read = 0)
* 3. Обновляем диалог или создаем новый
* 3. Вычисляем i_have_sent = 1 если есть исходящие сообщения (from_me = 1) - как sended в Архиве
* 4. Обновляем диалог или создаем новый
*/
@Query("""
INSERT OR REPLACE INTO dialogs (
@@ -430,7 +432,8 @@ interface DialogDao {
unread_count,
is_online,
last_seen,
verified
verified,
i_have_sent
)
SELECT
:account AS account,
@@ -478,7 +481,19 @@ interface DialogDao {
COALESCE(
(SELECT verified FROM dialogs WHERE account = :account AND opponent_key = :opponentKey),
0
) AS verified
) AS verified,
CASE
WHEN (SELECT COUNT(*) FROM messages
WHERE account = :account
AND from_public_key = :account
AND to_public_key = :opponentKey
AND from_me = 1) > 0
THEN 1
ELSE COALESCE(
(SELECT i_have_sent FROM dialogs WHERE account = :account AND opponent_key = :opponentKey),
0
)
END AS i_have_sent
""")
suspend fun updateDialogFromMessages(account: String, opponentKey: String)
}

View File

@@ -810,6 +810,9 @@ fun ChatDetailScreen(
// Кнопка меню - открывает bottom sheet
IconButton(
onClick = {
// Закрываем клавиатуру перед открытием меню
keyboardController?.hide()
focusManager.clearFocus()
showMenu = true
},
modifier = Modifier
@@ -1087,11 +1090,15 @@ fun ChatDetailScreen(
verticalArrangement = Arrangement.Center
) {
if (isSavedMessages) {
Icon(
Icons.Default.Bookmark,
contentDescription = null,
tint = secondaryTextColor.copy(alpha = 0.5f),
modifier = Modifier.size(64.dp)
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.saved))
val progress by animateLottieCompositionAsState(
composition = composition,
iterations = LottieConstants.IterateForever
)
LottieAnimation(
composition = composition,
progress = { progress },
modifier = Modifier.size(120.dp)
)
} else {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.speech))

View File

@@ -704,7 +704,35 @@ fun ChatsListScreen(
val requestsCount by chatsViewModel.requestsCount.collectAsState()
val requests by chatsViewModel.requests.collectAsState()
if (showRequestsScreen) {
// 🎬 Animated content transition between main list and requests
AnimatedContent(
targetState = showRequestsScreen,
transitionSpec = {
if (targetState) {
// Переход на Requests: slide in from right + fade
(slideInHorizontally(
animationSpec = tween(300, easing = FastOutSlowInEasing),
initialOffsetX = { it }
) + fadeIn(tween(300))) togetherWith
(slideOutHorizontally(
animationSpec = tween(300, easing = FastOutSlowInEasing),
targetOffsetX = { -it / 3 }
) + fadeOut(tween(200)))
} else {
// Возврат из Requests: slide out to right
(slideInHorizontally(
animationSpec = tween(300, easing = FastOutSlowInEasing),
initialOffsetX = { -it / 3 }
) + fadeIn(tween(300))) togetherWith
(slideOutHorizontally(
animationSpec = tween(300, easing = FastOutSlowInEasing),
targetOffsetX = { it }
) + fadeOut(tween(200)))
}
},
label = "RequestsTransition"
) { isRequestsScreen ->
if (isRequestsScreen) {
// 📬 Show Requests Screen
RequestsScreen(
requests = requests,
@@ -782,6 +810,7 @@ fun ChatsListScreen(
}
}
}
} // Close AnimatedContent
// Console button removed
}

File diff suppressed because one or more lines are too long