This commit is contained in:
Mikhail Kilin
2026-01-20 14:54:30 +03:00
parent 699f50a59c
commit 9912ac11bd
8 changed files with 232 additions and 48 deletions

View File

@@ -1,5 +1,6 @@
use std::env;
use tdlib_rs::enums::{AuthorizationState, ChatList, MessageContent, Update, User};
use std::collections::HashMap;
use tdlib_rs::enums::{AuthorizationState, ChatList, ChatType, MessageContent, Update, User};
use tdlib_rs::functions;
use tdlib_rs::types::{Chat as TdChat, Message as TdMessage};
@@ -20,6 +21,7 @@ pub enum AuthState {
pub struct ChatInfo {
pub id: i64,
pub title: String,
pub username: Option<String>,
pub last_message: String,
pub last_message_date: i32,
pub unread_count: i32,
@@ -44,6 +46,10 @@ pub struct TdClient {
client_id: i32,
pub chats: Vec<ChatInfo>,
pub current_chat_messages: Vec<MessageInfo>,
/// Кэш usernames: user_id -> username
user_usernames: HashMap<i64, String>,
/// Связь chat_id -> user_id для приватных чатов
chat_user_ids: HashMap<i64, i64>,
}
#[allow(dead_code)]
@@ -64,6 +70,8 @@ impl TdClient {
client_id,
chats: Vec::new(),
current_chat_messages: Vec::new(),
user_usernames: HashMap::new(),
chat_user_ids: HashMap::new(),
}
}
@@ -166,6 +174,23 @@ impl TdClient {
Update::NewMessage(_new_msg) => {
// Новые сообщения обрабатываются при обновлении UI
}
Update::User(update) => {
// Сохраняем username пользователя
let user = update.user;
if let Some(usernames) = user.usernames {
if let Some(username) = usernames.active_usernames.first() {
self.user_usernames.insert(user.id, username.clone());
// Обновляем username в чатах, связанных с этим пользователем
for (&chat_id, &user_id) in &self.chat_user_ids.clone() {
if user_id == user.id {
if let Some(chat) = self.chats.iter_mut().find(|c| c.id == chat_id) {
chat.username = Some(format!("@{}", username));
}
}
}
}
}
}
_ => {}
}
}
@@ -183,23 +208,15 @@ impl TdClient {
}
fn add_or_update_chat(&mut self, td_chat: &TdChat) {
// Проверяем, есть ли у чата позиция в ChatList::Main
// Если нет - не добавляем (это архивные чаты или связанные группы)
// Ищем позицию в Main списке (если есть)
let main_position = td_chat.positions.iter().find(|pos| {
matches!(pos.list, ChatList::Main)
});
// Если чат не в Main списке - удаляем его если был, и выходим
let Some(position) = main_position else {
self.chats.retain(|c| c.id != td_chat.id);
return;
};
// Если order == 0, чат не должен отображаться
if position.order == 0 {
self.chats.retain(|c| c.id != td_chat.id);
return;
}
// Получаем 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
@@ -207,14 +224,25 @@ impl TdClient {
.map(|m| (extract_message_text_static(m), m.date))
.unwrap_or_default();
// Извлекаем user_id для приватных чатов и сохраняем связь
let username = match &td_chat.r#type {
ChatType::Private(private) => {
self.chat_user_ids.insert(td_chat.id, private.user_id);
// Проверяем, есть ли уже username в кэше
self.user_usernames.get(&private.user_id).map(|u| format!("@{}", u))
}
_ => None,
};
let chat_info = ChatInfo {
id: td_chat.id,
title: td_chat.title.clone(),
username,
last_message,
last_message_date,
unread_count: td_chat.unread_count,
is_pinned: position.is_pinned,
order: position.order,
is_pinned,
order,
};
if let Some(existing) = self.chats.iter_mut().find(|c| c.id == td_chat.id) {
@@ -222,8 +250,15 @@ 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.is_pinned = chat_info.is_pinned;
existing.order = chat_info.order;
// Обновляем username если он появился
if chat_info.username.is_some() {
existing.username = chat_info.username;
}
// Обновляем позицию только если она пришла
if main_position.is_some() {
existing.is_pinned = chat_info.is_pinned;
existing.order = chat_info.order;
}
} else {
self.chats.push(chat_info);
}