From 9afd9c1d6741d50d0a47044b50dfb1d424c03618 Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Wed, 28 Jan 2026 02:26:35 +0500 Subject: [PATCH] feat: Integrate ChatsListViewModel for user block/unblock functionality in OtherProfileScreen --- .../messenger/database/BlacklistEntities.kt | 6 +++++ .../messenger/ui/chats/ChatDetailScreen.kt | 14 ++++-------- .../messenger/ui/chats/ChatsListViewModel.kt | 1 + .../ui/chats/input/ChatDetailInput.kt | 4 ++-- .../ui/settings/OtherProfileScreen.kt | 22 ++++++++++++++++++- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/rosetta/messenger/database/BlacklistEntities.kt b/app/src/main/java/com/rosetta/messenger/database/BlacklistEntities.kt index 88f0a65..75b58d9 100644 --- a/app/src/main/java/com/rosetta/messenger/database/BlacklistEntities.kt +++ b/app/src/main/java/com/rosetta/messenger/database/BlacklistEntities.kt @@ -47,6 +47,12 @@ interface BlacklistDao { @Query("SELECT COUNT(*) > 0 FROM blacklist WHERE public_key = :publicKey AND account = :account") suspend fun isUserBlocked(publicKey: String, account: String): Boolean + /** + * Наблюдать за статусом блокировки пользователя (Flow) + */ + @Query("SELECT COUNT(*) > 0 FROM blacklist WHERE public_key = :publicKey AND account = :account") + fun observeUserBlocked(publicKey: String, account: String): Flow + /** * Получить все заблокированные аккаунты для данного пользователя */ diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt index 3493110..6ae74c7 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt @@ -244,14 +244,10 @@ fun ChatDetailScreen( var showBlockConfirm by remember { mutableStateOf(false) } var showUnblockConfirm by remember { mutableStateOf(false) } - // Проверяем, заблокирован ли пользователь (отложенно, не блокирует UI) - var isBlocked by remember { mutableStateOf(false) } - LaunchedEffect(user.publicKey, currentUserPublicKey) { - // 🔥 ОПТИМИЗАЦИЯ: Отложенная проверка - не блокирует анимацию - kotlinx.coroutines.delay(100) // Даём анимации завершиться - isBlocked = - database.blacklistDao().isUserBlocked(user.publicKey, currentUserPublicKey) - } + // Наблюдаем за статусом блокировки в реальном времени через Flow + val isBlocked by database.blacklistDao() + .observeUserBlocked(user.publicKey, currentUserPublicKey) + .collectAsState(initial = false) // Подключаем к ViewModel val messages by viewModel.messages.collectAsState() @@ -1901,7 +1897,6 @@ fun ChatDetailScreen( currentUserPublicKey ) ) - isBlocked = true } catch (e: Exception) { // Error blocking user } @@ -1948,7 +1943,6 @@ fun ChatDetailScreen( account = currentUserPublicKey ) - isBlocked = false } catch (e: Exception) { // Error unblocking user } diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListViewModel.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListViewModel.kt index 4e8dc05..73e9bc1 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListViewModel.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatsListViewModel.kt @@ -7,6 +7,7 @@ import com.rosetta.messenger.crypto.CryptoManager import com.rosetta.messenger.data.MessageRepository import com.rosetta.messenger.database.DialogEntity import com.rosetta.messenger.database.RosettaDatabase +import com.rosetta.messenger.database.BlacklistEntity import com.rosetta.messenger.network.PacketOnlineSubscribe import com.rosetta.messenger.network.PacketSearch import com.rosetta.messenger.network.ProtocolManager diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt index 0a40446..41d2488 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt @@ -228,8 +228,8 @@ fun MessageInputBar( Row( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 8.dp) - .padding(bottom = 16.dp) + .padding(horizontal = 12.dp, vertical = 16.dp) + .padding(bottom = 20.dp) .navigationBarsPadding(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center diff --git a/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt index befaaa7..b04e177 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/settings/OtherProfileScreen.kt @@ -20,6 +20,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.rosetta.messenger.data.MessageRepository import com.rosetta.messenger.database.RosettaDatabase import com.rosetta.messenger.ui.chats.ChatViewModel +import com.rosetta.messenger.ui.chats.ChatsListViewModel import com.rosetta.messenger.ui.onboarding.PrimaryBlue import com.rosetta.messenger.ui.components.VerifiedBadge import androidx.compose.ui.Alignment @@ -78,6 +79,15 @@ fun OtherProfileScreen( // 🔥 Получаем тот же ChatViewModel что и в ChatDetailScreen для очистки истории val viewModel: ChatViewModel = viewModel(key = "chat_${user.publicKey}") + // 🔥 ChatsListViewModel для блокировки/разблокировки + val chatsListViewModel: ChatsListViewModel = viewModel() + val coroutineScope = rememberCoroutineScope() + + // 🔥 Загружаем статус блокировки при открытии экрана + LaunchedEffect(user.publicKey) { + isBlocked = chatsListViewModel.isUserBlocked(user.publicKey) + } + // 🎹 Для закрытия клавиатуры val keyboardController = LocalSoftwareKeyboardController.current val focusManager = LocalFocusManager.current @@ -201,7 +211,17 @@ fun OtherProfileScreen( showAvatarMenu = showAvatarMenu, onAvatarMenuChange = { showAvatarMenu = it }, isBlocked = isBlocked, - onBlockToggle = { isBlocked = !isBlocked }, + onBlockToggle = { + coroutineScope.launch { + if (isBlocked) { + chatsListViewModel.unblockUser(user.publicKey) + } else { + chatsListViewModel.blockUser(user.publicKey) + } + // Обновляем локальное состояние + isBlocked = !isBlocked + } + }, avatarRepository = avatarRepository, onClearChat = { viewModel.clearChatHistory()