Refactor code structure for improved readability and maintainability
This commit is contained in:
1
app/src/main/assets/lottie/saved.json
Normal file
1
app/src/main/assets/lottie/saved.json
Normal file
File diff suppressed because one or more lines are too long
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
1
app/src/main/res/raw/saved.json
Normal file
1
app/src/main/res/raw/saved.json
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user