Encapsulate TDLib state mutations
This commit is contained in:
@@ -104,11 +104,11 @@ rg -n "current_chat_messages_mut|chats_mut|folders_mut|pending_user_ids_mut|user
|
||||
|
||||
Steps:
|
||||
|
||||
- [ ] Add focused methods on `TdClient` for common mutations: update chat, update message by id, queue pending user, update user cache, update folders.
|
||||
- [ ] Replace raw `*_mut()` usage in helper/update modules with those methods.
|
||||
- [ ] Keep raw mutable access private to `TdClient` implementation where it is still needed.
|
||||
- [ ] Add or update tests around message updates, user-cache updates, and chat-list updates.
|
||||
- [ ] Run `cargo test --all-features`.
|
||||
- [x] Add focused methods on `TdClient` for common mutations: update chat, update message by id, queue pending user, update user cache, update folders.
|
||||
- [x] Replace raw `*_mut()` usage in helper/update modules with those methods.
|
||||
- [x] Keep raw mutable access private to `TdClient` implementation where it is still needed.
|
||||
- [x] Add or update tests around message updates, user-cache updates, and chat-list updates.
|
||||
- [x] Run `cargo test --all-features`.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
|
||||
@@ -10,19 +10,12 @@ use tdlib_rs::enums::{Chat as TdChat, ChatList, ChatType};
|
||||
use super::client::TdClient;
|
||||
use super::types::ChatInfo;
|
||||
|
||||
/// Находит мутабельную ссылку на чат по ID.
|
||||
pub fn find_chat_mut(client: &mut TdClient, chat_id: ChatId) -> Option<&mut ChatInfo> {
|
||||
client.chats_mut().iter_mut().find(|c| c.id == chat_id)
|
||||
}
|
||||
|
||||
/// Обновляет поле чата, если чат найден.
|
||||
pub fn update_chat<F>(client: &mut TdClient, chat_id: ChatId, updater: F)
|
||||
where
|
||||
F: FnOnce(&mut ChatInfo),
|
||||
{
|
||||
if let Some(chat) = find_chat_mut(client, chat_id) {
|
||||
updater(chat);
|
||||
}
|
||||
client.update_chat(chat_id, updater);
|
||||
}
|
||||
|
||||
/// Добавляет новый чат или обновляет существующий
|
||||
@@ -33,9 +26,7 @@ pub fn add_or_update_chat(client: &mut TdClient, td_chat_enum: &TdChat) {
|
||||
// Пропускаем удалённые аккаунты
|
||||
if td_chat.title == "Deleted Account" || td_chat.title.is_empty() {
|
||||
// Удаляем из списка если уже был добавлен
|
||||
client
|
||||
.chats_mut()
|
||||
.retain(|c| c.id != ChatId::new(td_chat.id));
|
||||
client.remove_chat(ChatId::new(td_chat.id));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -61,22 +52,23 @@ pub fn add_or_update_chat(client: &mut TdClient, td_chat_enum: &TdChat) {
|
||||
ChatType::Private(private) => {
|
||||
// Ограничиваем размер chat_user_ids
|
||||
let chat_id = ChatId::new(td_chat.id);
|
||||
if client.user_cache.chat_user_ids.len() >= MAX_CHAT_USER_IDS
|
||||
&& !client.user_cache.chat_user_ids.contains_key(&chat_id)
|
||||
{
|
||||
// Удаляем случайную запись (первую найденную)
|
||||
if let Some(&key) = client.user_cache.chat_user_ids.keys().next() {
|
||||
client.user_cache.chat_user_ids.remove(&key);
|
||||
}
|
||||
}
|
||||
let user_id = UserId::new(private.user_id);
|
||||
client.user_cache.chat_user_ids.insert(chat_id, user_id);
|
||||
// Проверяем, есть ли уже username в кэше (peek не обновляет LRU)
|
||||
client
|
||||
.user_cache
|
||||
.user_usernames
|
||||
.peek(&user_id)
|
||||
.map(|u| format!("@{}", u))
|
||||
client.update_user_cache(|cache| {
|
||||
if cache.chat_user_ids.len() >= MAX_CHAT_USER_IDS
|
||||
&& !cache.chat_user_ids.contains_key(&chat_id)
|
||||
{
|
||||
// Удаляем случайную запись (первую найденную)
|
||||
if let Some(&key) = cache.chat_user_ids.keys().next() {
|
||||
cache.chat_user_ids.remove(&key);
|
||||
}
|
||||
}
|
||||
cache.chat_user_ids.insert(chat_id, user_id);
|
||||
// Проверяем, есть ли уже username в кэше (peek не обновляет LRU)
|
||||
cache
|
||||
.user_usernames
|
||||
.peek(&user_id)
|
||||
.map(|u| format!("@{}", u))
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@@ -110,44 +102,35 @@ pub fn add_or_update_chat(client: &mut TdClient, td_chat_enum: &TdChat) {
|
||||
draft_text: None,
|
||||
};
|
||||
|
||||
if let Some(existing) = find_chat_mut(client, ChatId::new(td_chat.id)) {
|
||||
existing.title = chat_info.title;
|
||||
existing.last_message = chat_info.last_message;
|
||||
existing.last_message_date = chat_info.last_message_date;
|
||||
existing.unread_count = chat_info.unread_count;
|
||||
existing.unread_mention_count = chat_info.unread_mention_count;
|
||||
existing.last_read_outbox_message_id = chat_info.last_read_outbox_message_id;
|
||||
existing.folder_ids = chat_info.folder_ids;
|
||||
existing.is_muted = chat_info.is_muted;
|
||||
let chat_info_for_update = chat_info.clone();
|
||||
let updated_existing = client.update_chat(ChatId::new(td_chat.id), |existing| {
|
||||
existing.title = chat_info_for_update.title;
|
||||
existing.last_message = chat_info_for_update.last_message;
|
||||
existing.last_message_date = chat_info_for_update.last_message_date;
|
||||
existing.unread_count = chat_info_for_update.unread_count;
|
||||
existing.unread_mention_count = chat_info_for_update.unread_mention_count;
|
||||
existing.last_read_outbox_message_id = chat_info_for_update.last_read_outbox_message_id;
|
||||
existing.folder_ids = chat_info_for_update.folder_ids;
|
||||
existing.is_muted = chat_info_for_update.is_muted;
|
||||
|
||||
// Обновляем username если он появился
|
||||
if let Some(username) = chat_info.username {
|
||||
if let Some(username) = chat_info_for_update.username {
|
||||
existing.username = Some(username);
|
||||
}
|
||||
|
||||
// Обновляем позицию только если она пришла
|
||||
if main_position.is_some() {
|
||||
existing.is_pinned = chat_info.is_pinned;
|
||||
existing.order = chat_info.order;
|
||||
existing.is_pinned = chat_info_for_update.is_pinned;
|
||||
existing.order = chat_info_for_update.order;
|
||||
}
|
||||
} else {
|
||||
client.chats_mut().push(chat_info);
|
||||
});
|
||||
|
||||
if !updated_existing {
|
||||
client.push_chat(chat_info);
|
||||
// Ограничиваем количество чатов
|
||||
if client.chats_mut().len() > MAX_CHATS {
|
||||
// Удаляем чат с наименьшим order (наименее активный)
|
||||
let Some(min_idx) = client
|
||||
.chats()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.min_by_key(|(_, c)| c.order)
|
||||
.map(|(i, _)| i)
|
||||
else {
|
||||
return; // Нет чатов для удаления (не должно произойти)
|
||||
};
|
||||
client.chats_mut().remove(min_idx);
|
||||
}
|
||||
client.trim_chats_to_max_by_order(MAX_CHATS);
|
||||
}
|
||||
|
||||
// Сортируем чаты по order (TDLib order учитывает pinned и время)
|
||||
client.chats_mut().sort_by(|a, b| b.order.cmp(&a.order));
|
||||
client.sort_chats_by_order();
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ impl TdClient {
|
||||
self.notification_manager.set_enabled(config.enabled);
|
||||
self.notification_manager
|
||||
.set_only_mentions(config.only_mentions);
|
||||
self.notification_manager.set_show_preview(config.show_preview);
|
||||
self.notification_manager
|
||||
.set_show_preview(config.show_preview);
|
||||
self.notification_manager.set_timeout(config.timeout_ms);
|
||||
self.notification_manager
|
||||
.set_urgency(config.urgency.clone());
|
||||
@@ -433,24 +434,117 @@ impl TdClient {
|
||||
&self.chat_manager.chats
|
||||
}
|
||||
|
||||
pub fn chats_mut(&mut self) -> &mut Vec<ChatInfo> {
|
||||
&mut self.chat_manager.chats
|
||||
pub fn update_chats<F, R>(&mut self, updater: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Vec<ChatInfo>) -> R,
|
||||
{
|
||||
updater(&mut self.chat_manager.chats)
|
||||
}
|
||||
|
||||
pub fn update_chat<F>(&mut self, chat_id: ChatId, updater: F) -> bool
|
||||
where
|
||||
F: FnOnce(&mut ChatInfo),
|
||||
{
|
||||
let Some(chat) = self.chat_manager.chats.iter_mut().find(|c| c.id == chat_id) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
updater(chat);
|
||||
true
|
||||
}
|
||||
|
||||
pub fn remove_chat(&mut self, chat_id: ChatId) {
|
||||
self.chat_manager.chats.retain(|c| c.id != chat_id);
|
||||
}
|
||||
|
||||
pub fn push_chat(&mut self, chat: ChatInfo) {
|
||||
self.chat_manager.chats.push(chat);
|
||||
}
|
||||
|
||||
pub fn trim_chats_to_max_by_order(&mut self, max_chats: usize) {
|
||||
if self.chat_manager.chats.len() <= max_chats {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(min_idx) = self
|
||||
.chat_manager
|
||||
.chats
|
||||
.iter()
|
||||
.enumerate()
|
||||
.min_by_key(|(_, chat)| chat.order)
|
||||
.map(|(idx, _)| idx)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.chat_manager.chats.remove(min_idx);
|
||||
}
|
||||
|
||||
pub fn sort_chats_by_order(&mut self) {
|
||||
self.chat_manager
|
||||
.chats
|
||||
.sort_by(|a, b| b.order.cmp(&a.order));
|
||||
}
|
||||
|
||||
pub fn folders(&self) -> &[FolderInfo] {
|
||||
&self.chat_manager.folders
|
||||
}
|
||||
|
||||
pub fn folders_mut(&mut self) -> &mut Vec<FolderInfo> {
|
||||
&mut self.chat_manager.folders
|
||||
pub fn update_folders<F, R>(&mut self, updater: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Vec<FolderInfo>) -> R,
|
||||
{
|
||||
updater(&mut self.chat_manager.folders)
|
||||
}
|
||||
|
||||
pub fn set_folders(&mut self, folders: Vec<FolderInfo>) {
|
||||
self.chat_manager.folders = folders;
|
||||
}
|
||||
|
||||
pub fn current_chat_messages(&self) -> &[MessageInfo] {
|
||||
&self.message_manager.current_chat_messages
|
||||
}
|
||||
|
||||
pub fn current_chat_messages_mut(&mut self) -> &mut Vec<MessageInfo> {
|
||||
&mut self.message_manager.current_chat_messages
|
||||
pub fn clear_current_chat_messages(&mut self) {
|
||||
self.message_manager.current_chat_messages.clear();
|
||||
}
|
||||
|
||||
pub fn set_current_chat_messages(&mut self, messages: Vec<MessageInfo>) {
|
||||
self.message_manager.current_chat_messages = messages;
|
||||
}
|
||||
|
||||
pub fn update_current_chat_messages<F, R>(&mut self, updater: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Vec<MessageInfo>) -> R,
|
||||
{
|
||||
updater(&mut self.message_manager.current_chat_messages)
|
||||
}
|
||||
|
||||
pub fn update_current_chat_message<F>(&mut self, message_id: MessageId, updater: F) -> bool
|
||||
where
|
||||
F: FnOnce(&mut MessageInfo),
|
||||
{
|
||||
let Some(message) = self
|
||||
.message_manager
|
||||
.current_chat_messages
|
||||
.iter_mut()
|
||||
.find(|message| message.id() == message_id)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
updater(message);
|
||||
true
|
||||
}
|
||||
|
||||
pub fn replace_current_chat_message(
|
||||
&mut self,
|
||||
message_id: MessageId,
|
||||
new_message: MessageInfo,
|
||||
) -> bool {
|
||||
self.update_current_chat_message(message_id, |message| {
|
||||
*message = new_message;
|
||||
})
|
||||
}
|
||||
|
||||
pub fn current_chat_id(&self) -> Option<ChatId> {
|
||||
@@ -498,8 +592,10 @@ impl TdClient {
|
||||
&self.user_cache.pending_user_ids
|
||||
}
|
||||
|
||||
pub fn pending_user_ids_mut(&mut self) -> &mut Vec<crate::types::UserId> {
|
||||
&mut self.user_cache.pending_user_ids
|
||||
pub fn queue_pending_user_id(&mut self, user_id: crate::types::UserId) {
|
||||
if !self.user_cache.pending_user_ids.contains(&user_id) {
|
||||
self.user_cache.pending_user_ids.push(user_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_chat_list_position(&self) -> i32 {
|
||||
@@ -515,8 +611,11 @@ impl TdClient {
|
||||
&self.user_cache
|
||||
}
|
||||
|
||||
pub fn user_cache_mut(&mut self) -> &mut UserCache {
|
||||
&mut self.user_cache
|
||||
pub fn update_user_cache<F, R>(&mut self, updater: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut UserCache) -> R,
|
||||
{
|
||||
updater(&mut self.user_cache)
|
||||
}
|
||||
|
||||
// ==================== Helper методы для упрощения обработки updates ====================
|
||||
@@ -558,7 +657,7 @@ impl TdClient {
|
||||
}
|
||||
|
||||
// Пересортируем по order
|
||||
self.chats_mut().sort_by(|a, b| b.order.cmp(&a.order));
|
||||
self.sort_chats_by_order();
|
||||
}
|
||||
Update::ChatReadInbox(update) => {
|
||||
crate::tdlib::chat_helpers::update_chat(
|
||||
@@ -600,11 +699,13 @@ impl TdClient {
|
||||
);
|
||||
// Если это текущий открытый чат — обновляем is_read у сообщений
|
||||
if Some(ChatId::new(update.chat_id)) == self.current_chat_id() {
|
||||
for msg in self.current_chat_messages_mut().iter_mut() {
|
||||
if msg.is_outgoing() && msg.id() <= last_read_msg_id {
|
||||
msg.state.is_read = true;
|
||||
self.update_current_chat_messages(|messages| {
|
||||
for msg in messages {
|
||||
if msg.is_outgoing() && msg.id() <= last_read_msg_id {
|
||||
msg.state.is_read = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Update::ChatPosition(update) => {
|
||||
@@ -618,11 +719,13 @@ impl TdClient {
|
||||
}
|
||||
Update::ChatFolders(update) => {
|
||||
// Обновляем список папок
|
||||
*self.folders_mut() = update
|
||||
.chat_folders
|
||||
.into_iter()
|
||||
.map(|f| FolderInfo { id: f.id, name: f.title })
|
||||
.collect();
|
||||
self.set_folders(
|
||||
update
|
||||
.chat_folders
|
||||
.into_iter()
|
||||
.map(|f| FolderInfo { id: f.id, name: f.title })
|
||||
.collect(),
|
||||
);
|
||||
self.set_main_chat_list_position(update.main_chat_list_position);
|
||||
}
|
||||
Update::UserStatus(update) => {
|
||||
@@ -635,9 +738,11 @@ impl TdClient {
|
||||
UserStatus::LastMonth(_) => UserOnlineStatus::LastMonth,
|
||||
UserStatus::Empty => UserOnlineStatus::LongTimeAgo,
|
||||
};
|
||||
self.user_cache
|
||||
.user_statuses
|
||||
.insert(UserId::new(update.user_id), status);
|
||||
self.update_user_cache(|cache| {
|
||||
cache
|
||||
.user_statuses
|
||||
.insert(UserId::new(update.user_id), status);
|
||||
});
|
||||
}
|
||||
Update::ConnectionState(update) => {
|
||||
// Обновляем состояние сетевого соединения
|
||||
|
||||
@@ -70,14 +70,14 @@ impl ChatClient for TdClient {
|
||||
where
|
||||
F: FnOnce(&mut Vec<ChatInfo>),
|
||||
{
|
||||
updater(self.chats_mut());
|
||||
TdClient::update_chats(self, updater);
|
||||
}
|
||||
|
||||
fn update_folders<F>(&mut self, updater: F)
|
||||
where
|
||||
F: FnOnce(&mut Vec<FolderInfo>),
|
||||
{
|
||||
updater(self.folders_mut());
|
||||
TdClient::update_folders(self, updater);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,18 +204,18 @@ impl MessageClient for TdClient {
|
||||
}
|
||||
|
||||
fn clear_current_chat_messages(&mut self) {
|
||||
self.current_chat_messages_mut().clear()
|
||||
TdClient::clear_current_chat_messages(self)
|
||||
}
|
||||
|
||||
fn set_current_chat_messages(&mut self, messages: Vec<MessageInfo>) {
|
||||
*self.current_chat_messages_mut() = messages;
|
||||
TdClient::set_current_chat_messages(self, messages);
|
||||
}
|
||||
|
||||
fn update_current_chat_messages<F>(&mut self, updater: F)
|
||||
where
|
||||
F: FnOnce(&mut Vec<MessageInfo>),
|
||||
{
|
||||
updater(self.current_chat_messages_mut());
|
||||
TdClient::update_current_chat_messages(self, updater);
|
||||
}
|
||||
|
||||
fn set_current_chat_id(&mut self, chat_id: Option<ChatId>) {
|
||||
@@ -253,7 +253,7 @@ impl UserClient for TdClient {
|
||||
where
|
||||
F: FnOnce(&mut UserCache),
|
||||
{
|
||||
updater(self.user_cache_mut());
|
||||
TdClient::update_user_cache(self, updater);
|
||||
}
|
||||
|
||||
async fn process_pending_user_ids(&mut self) {
|
||||
|
||||
@@ -23,9 +23,7 @@ pub fn convert_message(client: &mut TdClient, message: &TdMessage, chat_id: Chat
|
||||
.cloned()
|
||||
.unwrap_or_else(|| {
|
||||
// Добавляем в очередь для загрузки
|
||||
if !client.pending_user_ids().contains(&user_id) {
|
||||
client.pending_user_ids_mut().push(user_id);
|
||||
}
|
||||
client.queue_pending_user_id(user_id);
|
||||
format!("User_{}", user_id.as_i64())
|
||||
})
|
||||
}
|
||||
@@ -210,25 +208,27 @@ pub fn update_reply_info_from_loaded_messages(client: &mut TdClient) {
|
||||
.collect();
|
||||
|
||||
// Обновляем reply_to для сообщений с неполными данными
|
||||
for msg in client.current_chat_messages_mut().iter_mut() {
|
||||
let Some(ref mut reply) = msg.interactions.reply_to else {
|
||||
continue;
|
||||
};
|
||||
client.update_current_chat_messages(|messages| {
|
||||
for msg in messages {
|
||||
let Some(ref mut reply) = msg.interactions.reply_to else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Если sender_name = "..." или text пустой — пробуем заполнить
|
||||
if reply.sender_name != "..." && !reply.text.is_empty() {
|
||||
continue;
|
||||
}
|
||||
// Если sender_name = "..." или text пустой — пробуем заполнить
|
||||
if reply.sender_name != "..." && !reply.text.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some((sender, content)) = msg_data.get(&reply.message_id.as_i64()) else {
|
||||
continue;
|
||||
};
|
||||
let Some((sender, content)) = msg_data.get(&reply.message_id.as_i64()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if reply.sender_name == "..." {
|
||||
reply.sender_name = sender.clone();
|
||||
if reply.sender_name == "..." {
|
||||
reply.sender_name = sender.clone();
|
||||
}
|
||||
if reply.text.is_empty() {
|
||||
reply.text = content.clone();
|
||||
}
|
||||
}
|
||||
if reply.text.is_empty() {
|
||||
reply.text = content.clone();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -54,17 +54,19 @@ pub fn handle_new_message_update(client: &mut TdClient, new_msg: UpdateNewMessag
|
||||
Some(idx) => {
|
||||
// Сообщение уже есть - обновляем
|
||||
if is_incoming {
|
||||
client.current_chat_messages_mut()[idx] = msg_info;
|
||||
client.replace_current_chat_message(msg_id, msg_info);
|
||||
} else {
|
||||
// Для исходящих: обновляем can_be_edited и другие поля,
|
||||
// но сохраняем reply_to (добавленный при отправке)
|
||||
let existing = &mut client.current_chat_messages_mut()[idx];
|
||||
existing.state.can_be_edited = msg_info.state.can_be_edited;
|
||||
existing.state.can_be_deleted_only_for_self =
|
||||
msg_info.state.can_be_deleted_only_for_self;
|
||||
existing.state.can_be_deleted_for_all_users =
|
||||
msg_info.state.can_be_deleted_for_all_users;
|
||||
existing.state.is_read = msg_info.state.is_read;
|
||||
client.update_current_chat_messages(|messages| {
|
||||
let existing = &mut messages[idx];
|
||||
existing.state.can_be_edited = msg_info.state.can_be_edited;
|
||||
existing.state.can_be_deleted_only_for_self =
|
||||
msg_info.state.can_be_deleted_only_for_self;
|
||||
existing.state.can_be_deleted_for_all_users =
|
||||
msg_info.state.can_be_deleted_for_all_users;
|
||||
existing.state.is_read = msg_info.state.is_read;
|
||||
});
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@@ -122,7 +124,7 @@ pub fn handle_chat_position_update(client: &mut TdClient, update: UpdateChatPosi
|
||||
ChatList::Main => {
|
||||
if update.position.order == 0 {
|
||||
// Чат больше не в Main (перемещён в архив и т.д.)
|
||||
client.chats_mut().retain(|c| c.id != chat_id);
|
||||
client.remove_chat(chat_id);
|
||||
} else {
|
||||
// Обновляем позицию существующего чата
|
||||
crate::tdlib::chat_helpers::update_chat(client, chat_id, |chat| {
|
||||
@@ -131,7 +133,7 @@ pub fn handle_chat_position_update(client: &mut TdClient, update: UpdateChatPosi
|
||||
});
|
||||
}
|
||||
// Пересортируем по order
|
||||
client.chats_mut().sort_by(|a, b| b.order.cmp(&a.order));
|
||||
client.sort_chats_by_order();
|
||||
}
|
||||
ChatList::Folder(folder) => {
|
||||
// Обновляем folder_ids для чата
|
||||
@@ -166,10 +168,10 @@ pub fn handle_user_update(client: &mut TdClient, update: UpdateUser) {
|
||||
// Удаляем чаты с этим пользователем из списка
|
||||
let user_id = user.id;
|
||||
// Clone chat_user_ids to avoid borrow conflict
|
||||
let chat_user_ids = client.user_cache.chat_user_ids.clone();
|
||||
client
|
||||
.chats_mut()
|
||||
.retain(|c| chat_user_ids.get(&c.id) != Some(&UserId::new(user_id)));
|
||||
let chat_user_ids = client.user_cache().chat_user_ids.clone();
|
||||
client.update_chats(|chats| {
|
||||
chats.retain(|c| chat_user_ids.get(&c.id) != Some(&UserId::new(user_id)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -179,10 +181,9 @@ pub fn handle_user_update(client: &mut TdClient, update: UpdateUser) {
|
||||
} else {
|
||||
format!("{} {}", user.first_name, user.last_name)
|
||||
};
|
||||
client
|
||||
.user_cache
|
||||
.user_names
|
||||
.insert(UserId::new(user.id), display_name);
|
||||
client.update_user_cache(|cache| {
|
||||
cache.user_names.insert(UserId::new(user.id), display_name);
|
||||
});
|
||||
|
||||
// Сохраняем username если есть (с упрощённым извлечением через and_then)
|
||||
if let Some(username) = user
|
||||
@@ -190,17 +191,23 @@ pub fn handle_user_update(client: &mut TdClient, update: UpdateUser) {
|
||||
.as_ref()
|
||||
.and_then(|u| u.active_usernames.first())
|
||||
{
|
||||
client
|
||||
.user_cache
|
||||
.user_usernames
|
||||
.insert(UserId::new(user.id), username.to_string());
|
||||
let affected_chat_ids = client.update_user_cache(|cache| {
|
||||
cache
|
||||
.user_usernames
|
||||
.insert(UserId::new(user.id), username.to_string());
|
||||
cache
|
||||
.chat_user_ids
|
||||
.iter()
|
||||
.filter_map(|(&chat_id, &user_id)| {
|
||||
(user_id == UserId::new(user.id)).then_some(chat_id)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
// Обновляем username в чатах, связанных с этим пользователем
|
||||
for (&chat_id, &user_id) in &client.user_cache.chat_user_ids.clone() {
|
||||
if user_id == UserId::new(user.id) {
|
||||
crate::tdlib::chat_helpers::update_chat(client, chat_id, |chat| {
|
||||
chat.username = Some(format!("@{}", username));
|
||||
});
|
||||
}
|
||||
for chat_id in affected_chat_ids {
|
||||
crate::tdlib::chat_helpers::update_chat(client, chat_id, |chat| {
|
||||
chat.username = Some(format!("@{}", username));
|
||||
});
|
||||
}
|
||||
}
|
||||
// LRU-кэш автоматически удаляет старые записи при вставке
|
||||
@@ -218,16 +225,8 @@ pub fn handle_message_interaction_info_update(
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(msg) = client
|
||||
.current_chat_messages_mut()
|
||||
.iter_mut()
|
||||
.find(|m| m.id() == MessageId::new(update.message_id))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Извлекаем реакции из interaction_info
|
||||
msg.interactions.reactions = update
|
||||
let reactions = update
|
||||
.interaction_info
|
||||
.as_ref()
|
||||
.and_then(|info| info.reactions.as_ref())
|
||||
@@ -250,6 +249,9 @@ pub fn handle_message_interaction_info_update(
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
client.update_current_chat_message(MessageId::new(update.message_id), |msg| {
|
||||
msg.interactions.reactions = reactions;
|
||||
});
|
||||
}
|
||||
|
||||
/// Обрабатывает Update::MessageSendSucceeded - успешная отправка сообщения.
|
||||
@@ -291,7 +293,7 @@ pub fn handle_message_send_succeeded_update(
|
||||
}
|
||||
|
||||
// Заменяем старое сообщение на новое
|
||||
client.current_chat_messages_mut()[idx] = new_msg;
|
||||
client.replace_current_chat_message(old_id, new_msg);
|
||||
}
|
||||
|
||||
/// Обрабатывает Update::ChatDraftMessage - обновление черновика сообщения в чате.
|
||||
|
||||
Reference in New Issue
Block a user