feat: enhance chat and requests screens with avatar handling, pinning, and user blocking functionalities
This commit is contained in:
@@ -7,18 +7,18 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/**
|
||||
* 📨 Менеджер для пересылки сообщений (Forward)
|
||||
*
|
||||
*
|
||||
* Логика как в десктопе:
|
||||
* 1. Пользователь выбирает сообщения в чате
|
||||
* 2. Нажимает Forward
|
||||
* 3. Открывается список чатов
|
||||
* 4. Выбирает чат куда переслать
|
||||
* 5. Переходит в выбранный чат с сообщениями в Reply панели (как Forward)
|
||||
*
|
||||
* 3. Открывается список чатов (мультивыбор)
|
||||
* 4. Выбирает один или несколько чатов
|
||||
* 5. Первый чат — навигация с reply панелью, остальные — прямая отправка
|
||||
*
|
||||
* Singleton для передачи данных между экранами
|
||||
*/
|
||||
object ForwardManager {
|
||||
|
||||
|
||||
/**
|
||||
* Сообщение для пересылки
|
||||
*/
|
||||
@@ -29,25 +29,31 @@ object ForwardManager {
|
||||
val isOutgoing: Boolean,
|
||||
val senderPublicKey: String, // publicKey отправителя сообщения
|
||||
val originalChatPublicKey: String, // publicKey чата откуда пересылается
|
||||
val senderName: String = "", // Имя отправителя для атрибуции
|
||||
val attachments: List<MessageAttachment> = emptyList()
|
||||
)
|
||||
|
||||
|
||||
// Сообщения для пересылки
|
||||
private val _forwardMessages = MutableStateFlow<List<ForwardMessage>>(emptyList())
|
||||
val forwardMessages: StateFlow<List<ForwardMessage>> = _forwardMessages.asStateFlow()
|
||||
|
||||
|
||||
// Флаг показа выбора чата
|
||||
private val _showChatPicker = MutableStateFlow(false)
|
||||
val showChatPicker: StateFlow<Boolean> = _showChatPicker.asStateFlow()
|
||||
|
||||
// Выбранный чат (publicKey собеседника)
|
||||
private val _selectedChatPublicKey = MutableStateFlow<String?>(null)
|
||||
val selectedChatPublicKey: StateFlow<String?> = _selectedChatPublicKey.asStateFlow()
|
||||
|
||||
|
||||
// Выбранные чаты (publicKeys собеседников) — поддержка мультивыбора
|
||||
private val _selectedChatPublicKeys = MutableStateFlow<List<String>>(emptyList())
|
||||
val selectedChatPublicKeys: StateFlow<List<String>> = _selectedChatPublicKeys.asStateFlow()
|
||||
|
||||
// Обратная совместимость: первый выбранный чат
|
||||
val selectedChatPublicKey: StateFlow<String?> get() = MutableStateFlow(
|
||||
_selectedChatPublicKeys.value.firstOrNull()
|
||||
)
|
||||
|
||||
// 🔥 Счётчик для триггера перезагрузки диалога при forward
|
||||
private val _forwardTrigger = MutableStateFlow(0)
|
||||
val forwardTrigger: StateFlow<Int> = _forwardTrigger.asStateFlow()
|
||||
|
||||
|
||||
/**
|
||||
* Установить сообщения для пересылки и показать выбор чата
|
||||
*/
|
||||
@@ -60,24 +66,31 @@ object ForwardManager {
|
||||
_showChatPicker.value = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Выбрать чат для пересылки
|
||||
* Выбрать один чат для пересылки (обратная совместимость)
|
||||
*/
|
||||
fun selectChat(publicKey: String) {
|
||||
_selectedChatPublicKey.value = publicKey
|
||||
selectChats(listOf(publicKey))
|
||||
}
|
||||
|
||||
/**
|
||||
* Выбрать несколько чатов для пересылки
|
||||
*/
|
||||
fun selectChats(publicKeys: List<String>) {
|
||||
_selectedChatPublicKeys.value = publicKeys
|
||||
_showChatPicker.value = false
|
||||
// 🔥 Увеличиваем триггер чтобы ChatDetailScreen перезагрузил диалог
|
||||
_forwardTrigger.value++
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Скрыть выбор чата (отмена)
|
||||
*/
|
||||
fun hideChatPicker() {
|
||||
_showChatPicker.value = false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получить сообщения и очистить состояние
|
||||
* Вызывается при открытии выбранного чата
|
||||
@@ -86,57 +99,64 @@ object ForwardManager {
|
||||
val messages = _forwardMessages.value
|
||||
return messages
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Очистить все данные (после применения или отмены)
|
||||
*/
|
||||
fun clear() {
|
||||
_forwardMessages.value = emptyList()
|
||||
_showChatPicker.value = false
|
||||
_selectedChatPublicKey.value = null
|
||||
_selectedChatPublicKeys.value = emptyList()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Проверить есть ли сообщения для пересылки
|
||||
*/
|
||||
fun hasForwardMessages(): Boolean = _forwardMessages.value.isNotEmpty()
|
||||
|
||||
|
||||
/**
|
||||
* Проверить есть ли сообщения для конкретного чата
|
||||
*/
|
||||
fun hasForwardMessagesForChat(publicKey: String): Boolean {
|
||||
val selectedKey = _selectedChatPublicKey.value
|
||||
val selectedKeys = _selectedChatPublicKeys.value
|
||||
val hasMessages = _forwardMessages.value.isNotEmpty()
|
||||
return selectedKey == publicKey && hasMessages
|
||||
return publicKey in selectedKeys && hasMessages
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Установить выбранный чат и вернуть сообщения для него
|
||||
* Комбинированный метод для атомарного получения данных
|
||||
*/
|
||||
fun getForwardMessagesForChat(publicKey: String): List<ForwardMessage> {
|
||||
val selectedKey = _selectedChatPublicKey.value
|
||||
return if (selectedKey == publicKey && _forwardMessages.value.isNotEmpty()) {
|
||||
val selectedKeys = _selectedChatPublicKeys.value
|
||||
return if (publicKey in selectedKeys && _forwardMessages.value.isNotEmpty()) {
|
||||
_forwardMessages.value
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список дополнительных чатов (кроме основного, куда навигируемся)
|
||||
*/
|
||||
fun getAdditionalChatKeys(primaryKey: String): List<String> {
|
||||
return _selectedChatPublicKeys.value.filter { it != primaryKey }
|
||||
}
|
||||
|
||||
/**
|
||||
* Атомарно получить forward-сообщения для конкретного чата и очистить pending state.
|
||||
* Это повторяет desktop-подход "consume once" после перехода в целевой диалог.
|
||||
*/
|
||||
@Synchronized
|
||||
fun consumeForwardMessagesForChat(publicKey: String): List<ForwardMessage> {
|
||||
val selectedKey = _selectedChatPublicKey.value
|
||||
val selectedKeys = _selectedChatPublicKeys.value
|
||||
val pending = _forwardMessages.value
|
||||
if (selectedKey != publicKey || pending.isEmpty()) {
|
||||
if (publicKey !in selectedKeys || pending.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
_forwardMessages.value = emptyList()
|
||||
_selectedChatPublicKey.value = null
|
||||
_selectedChatPublicKeys.value = emptyList()
|
||||
_showChatPicker.value = false
|
||||
return pending
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user