Split core and TUI crates
This commit is contained in:
136
crates/tele-core/src/tdlib/chat_helpers.rs
Normal file
136
crates/tele-core/src/tdlib/chat_helpers.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
//! 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();
|
||||
}
|
||||
Reference in New Issue
Block a user