Files
telegram-tui/crates/tele-core/src/tdlib/chat_helpers.rs
2026-05-20 00:31:18 +03:00

137 lines
5.3 KiB
Rust

//! Chat management helper functions.
//!
//! This module contains utility functions for managing chats,
//! including finding, updating, and adding/removing chats.
use crate::constants::{MAX_CHATS, MAX_CHAT_USER_IDS};
use crate::types::{ChatId, MessageId, UserId};
use tdlib_rs::enums::{Chat as TdChat, ChatList, ChatType};
use super::client::TdClient;
use super::types::ChatInfo;
/// Обновляет поле чата, если чат найден.
pub fn update_chat<F>(client: &mut TdClient, chat_id: ChatId, updater: F)
where
F: FnOnce(&mut ChatInfo),
{
client.update_chat(chat_id, updater);
}
/// Добавляет новый чат или обновляет существующий
pub fn add_or_update_chat(client: &mut TdClient, td_chat_enum: &TdChat) {
// Pattern match to get inner Chat struct
let TdChat::Chat(td_chat) = td_chat_enum;
// Пропускаем удалённые аккаунты
if td_chat.title == "Deleted Account" || td_chat.title.is_empty() {
// Удаляем из списка если уже был добавлен
client.remove_chat(ChatId::new(td_chat.id));
return;
}
// Ищем позицию в Main списке (если есть)
let main_position = td_chat
.positions
.iter()
.find(|pos| matches!(pos.list, ChatList::Main));
// Получаем order и is_pinned из позиции, или используем значения по умолчанию
let (order, is_pinned) = main_position
.map(|p| (p.order, p.is_pinned))
.unwrap_or((1, false)); // order=1 чтобы чат отображался
let (last_message, last_message_date) = td_chat
.last_message
.as_ref()
.map(|m| (TdClient::extract_message_text_static(m).0, m.date))
.unwrap_or_default();
// Извлекаем user_id для приватных чатов и сохраняем связь
let username = match &td_chat.r#type {
ChatType::Private(private) => {
// Ограничиваем размер chat_user_ids
let chat_id = ChatId::new(td_chat.id);
let user_id = UserId::new(private.user_id);
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,
};
// Извлекаем ID папок из позиций
let folder_ids: Vec<i32> = td_chat
.positions
.iter()
.filter_map(|pos| match &pos.list {
ChatList::Folder(folder) => Some(folder.chat_folder_id),
_ => None,
})
.collect();
// Проверяем mute статус
let is_muted = td_chat.notification_settings.mute_for > 0;
let chat_info = ChatInfo {
id: ChatId::new(td_chat.id),
title: td_chat.title.clone(),
username,
last_message,
last_message_date,
unread_count: td_chat.unread_count,
unread_mention_count: td_chat.unread_mention_count,
is_pinned,
order,
last_read_outbox_message_id: MessageId::new(td_chat.last_read_outbox_message_id),
folder_ids,
is_muted,
draft_text: None,
};
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_for_update.username {
existing.username = Some(username);
}
// Обновляем позицию только если она пришла
if main_position.is_some() {
existing.is_pinned = chat_info_for_update.is_pinned;
existing.order = chat_info_for_update.order;
}
});
if !updated_existing {
client.push_chat(chat_info);
// Ограничиваем количество чатов
client.trim_chats_to_max_by_order(MAX_CHATS);
}
// Сортируем чаты по order (TDLib order учитывает pinned и время)
client.sort_chats_by_order();
}