This commit is contained in:
Mikhail Kilin
2026-01-22 15:26:15 +03:00
parent 1ef341d907
commit c18f43664e
10 changed files with 436 additions and 87 deletions

View File

@@ -1,6 +1,9 @@
use std::env;
use std::collections::HashMap;
use tdlib_rs::enums::{AuthorizationState, ChatList, ChatType, MessageContent, Update, User, UserStatus};
use tdlib_rs::enums::{AuthorizationState, ChatList, ChatType, ConnectionState, MessageContent, Update, User, UserStatus};
/// Максимальный размер кэшей пользователей
const MAX_USER_CACHE_SIZE: usize = 500;
use tdlib_rs::functions;
use tdlib_rs::types::{Chat as TdChat, Message as TdMessage};
@@ -25,12 +28,16 @@ pub struct ChatInfo {
pub last_message: String,
pub last_message_date: i32,
pub unread_count: i32,
/// Количество непрочитанных упоминаний (@)
pub unread_mention_count: i32,
pub is_pinned: bool,
pub order: i64,
/// ID последнего прочитанного исходящего сообщения (для галочек)
pub last_read_outbox_message_id: i64,
/// ID папок, в которых находится чат
pub folder_ids: Vec<i32>,
/// Чат замьючен (уведомления отключены)
pub is_muted: bool,
}
#[derive(Debug, Clone)]
@@ -49,6 +56,21 @@ pub struct FolderInfo {
pub name: String,
}
/// Состояние сетевого соединения
#[derive(Debug, Clone, PartialEq)]
pub enum NetworkState {
/// Ожидание подключения к сети
WaitingForNetwork,
/// Подключение к прокси
ConnectingToProxy,
/// Подключение к серверам Telegram
Connecting,
/// Обновление данных
Updating,
/// Подключено
Ready,
}
/// Онлайн-статус пользователя
#[derive(Debug, Clone, PartialEq)]
pub enum UserOnlineStatus {
@@ -91,6 +113,8 @@ pub struct TdClient {
pub main_chat_list_position: i32,
/// Онлайн-статусы пользователей: user_id -> status
user_statuses: HashMap<i64, UserOnlineStatus>,
/// Состояние сетевого соединения
pub network_state: NetworkState,
}
#[allow(dead_code)]
@@ -120,6 +144,7 @@ impl TdClient {
folders: Vec::new(),
main_chat_list_position: 0,
user_statuses: HashMap::new(),
network_state: NetworkState::Connecting,
}
}
@@ -131,6 +156,18 @@ impl TdClient {
self.client_id
}
/// Очистка кэшей если они превышают лимит
fn trim_caches(&mut self) {
if self.user_names.len() > MAX_USER_CACHE_SIZE {
// Оставляем только пользователей из текущих чатов
let active_user_ids: std::collections::HashSet<i64> =
self.chat_user_ids.values().copied().collect();
self.user_names.retain(|id, _| active_user_ids.contains(id));
self.user_usernames.retain(|id, _| active_user_ids.contains(id));
self.user_statuses.retain(|id, _| active_user_ids.contains(id));
}
}
/// Получение онлайн-статуса пользователя по chat_id (для приватных чатов)
pub fn get_user_status_by_chat_id(&self, chat_id: i64) -> Option<&UserOnlineStatus> {
self.chat_user_ids
@@ -205,6 +242,17 @@ impl TdClient {
chat.unread_count = update.unread_count;
}
}
Update::ChatUnreadMentionCount(update) => {
if let Some(chat) = self.chats.iter_mut().find(|c| c.id == update.chat_id) {
chat.unread_mention_count = update.unread_mention_count;
}
}
Update::ChatNotificationSettings(update) => {
if let Some(chat) = self.chats.iter_mut().find(|c| c.id == update.chat_id) {
// mute_for > 0 означает что чат замьючен
chat.is_muted = update.notification_settings.mute_for > 0;
}
}
Update::ChatReadOutbox(update) => {
// Обновляем last_read_outbox_message_id когда собеседник прочитал сообщения
if let Some(chat) = self.chats.iter_mut().find(|c| c.id == update.chat_id) {
@@ -306,6 +354,9 @@ impl TdClient {
}
}
}
// Периодически очищаем кэши
self.trim_caches();
}
Update::ChatFolders(update) => {
// Обновляем список папок
@@ -331,6 +382,16 @@ impl TdClient {
};
self.user_statuses.insert(update.user_id, status);
}
Update::ConnectionState(update) => {
// Обновляем состояние сетевого соединения
self.network_state = match update.state {
ConnectionState::WaitingForNetwork => NetworkState::WaitingForNetwork,
ConnectionState::ConnectingToProxy => NetworkState::ConnectingToProxy,
ConnectionState::Connecting => NetworkState::Connecting,
ConnectionState::Updating => NetworkState::Updating,
ConnectionState::Ready => NetworkState::Ready,
};
}
_ => {}
}
}
@@ -394,6 +455,9 @@ impl TdClient {
})
.collect();
// Проверяем mute статус
let is_muted = td_chat.notification_settings.mute_for > 0;
let chat_info = ChatInfo {
id: td_chat.id,
title: td_chat.title.clone(),
@@ -401,10 +465,12 @@ impl TdClient {
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: td_chat.last_read_outbox_message_id,
folder_ids,
is_muted,
};
if let Some(existing) = self.chats.iter_mut().find(|c| c.id == td_chat.id) {
@@ -412,8 +478,10 @@ impl TdClient {
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;
// Обновляем username если он появился
if chat_info.username.is_some() {
existing.username = chat_info.username;