fix: исправлены баги с сообщениями, редактированием и reply
- Изменён порядок хранения сообщений (теперь от старых к новым) - Исправлена логика выбора сообщений для редактирования - Исправлена отправка reply (структура условий) - Добавлено сохранение reply_info при отправке - Удалены отладочные логи Fixes: сообщения теперь отображаются корректно в UI Fixes: редактирование работает без ошибки 'Message not found' Fixes: reply показывает превью исходного сообщения
This commit is contained in:
@@ -498,7 +498,7 @@ impl TdClient {
|
||||
}
|
||||
None => {
|
||||
// Нового сообщения нет - добавляем
|
||||
self.push_message(msg_info);
|
||||
self.push_message(msg_info.clone());
|
||||
// Если это входящее сообщение — добавляем в очередь для отметки как прочитанное
|
||||
if is_incoming {
|
||||
self.pending_view_messages_mut().push((chat_id, vec![msg_id]));
|
||||
|
||||
@@ -29,11 +29,11 @@ impl MessageManager {
|
||||
|
||||
/// Добавить сообщение в список текущего чата
|
||||
pub fn push_message(&mut self, msg: MessageInfo) {
|
||||
self.current_chat_messages.insert(0, msg);
|
||||
self.current_chat_messages.push(msg); // Добавляем в конец
|
||||
|
||||
// Ограничиваем размер списка
|
||||
// Ограничиваем размер списка (удаляем старые с начала)
|
||||
if self.current_chat_messages.len() > MAX_MESSAGES_IN_CHAT {
|
||||
self.current_chat_messages.truncate(MAX_MESSAGES_IN_CHAT);
|
||||
self.current_chat_messages.drain(0..(self.current_chat_messages.len() - MAX_MESSAGES_IN_CHAT));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,34 +43,63 @@ impl MessageManager {
|
||||
chat_id: ChatId,
|
||||
limit: i32,
|
||||
) -> Result<Vec<MessageInfo>, String> {
|
||||
// Устанавливаем текущий чат для получения новых сообщений
|
||||
self.current_chat_id = Some(chat_id);
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
let result = functions::get_chat_history(
|
||||
chat_id.as_i64(),
|
||||
0, // from_message_id
|
||||
0, // offset
|
||||
limit,
|
||||
false,
|
||||
self.client_id,
|
||||
)
|
||||
.await;
|
||||
// ВАЖНО: Сначала открываем чат в TDLib
|
||||
// Это сообщает TDLib что пользователь открыл чат и нужно загрузить историю
|
||||
let _ = functions::open_chat(chat_id.as_i64(), self.client_id).await;
|
||||
|
||||
match result {
|
||||
Ok(tdlib_rs::enums::Messages::Messages(messages_obj)) => {
|
||||
let mut messages = Vec::new();
|
||||
for msg_opt in messages_obj.messages.iter().rev() {
|
||||
if let Some(msg) = msg_opt {
|
||||
if let Some(info) = self.convert_message(msg).await {
|
||||
messages.push(info);
|
||||
// Даём TDLib время на синхронизацию (загрузку истории с сервера)
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
|
||||
// НЕ устанавливаем current_chat_id здесь!
|
||||
// Он будет установлен снаружи ПОСЛЕ сохранения истории
|
||||
// Это предотвращает race condition с Update::NewMessage
|
||||
|
||||
// Пробуем загрузить несколько раз, TDLib может подгружать с сервера
|
||||
let mut all_messages = Vec::new();
|
||||
let max_attempts = 3;
|
||||
|
||||
for attempt in 1..=max_attempts {
|
||||
let result = functions::get_chat_history(
|
||||
chat_id.as_i64(),
|
||||
0, // from_message_id (0 = from latest)
|
||||
0, // offset
|
||||
limit,
|
||||
false, // only_local - false means can fetch from server
|
||||
self.client_id,
|
||||
)
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(tdlib_rs::enums::Messages::Messages(messages_obj)) => {
|
||||
if !messages_obj.messages.is_empty() {
|
||||
all_messages.clear(); // Очищаем предыдущие результаты
|
||||
for msg_opt in messages_obj.messages.iter().rev() {
|
||||
if let Some(msg) = msg_opt {
|
||||
if let Some(info) = self.convert_message(msg).await {
|
||||
all_messages.push(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Если получили достаточно сообщений, прекращаем попытки
|
||||
if all_messages.len() >= 2 || attempt == max_attempts {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Если сообщений мало, ждём перед следующей попыткой
|
||||
if attempt < max_attempts {
|
||||
sleep(Duration::from_millis(200)).await;
|
||||
}
|
||||
}
|
||||
Ok(messages)
|
||||
Ok(_) => return Err("Неожиданный тип сообщений".to_string()),
|
||||
Err(e) => return Err(format!("Ошибка загрузки истории: {:?}", e)),
|
||||
}
|
||||
Ok(_) => Err("Неожиданный тип сообщений".to_string()),
|
||||
Err(e) => Err(format!("Ошибка загрузки истории: {:?}", e)),
|
||||
}
|
||||
|
||||
Ok(all_messages)
|
||||
}
|
||||
|
||||
/// Загрузить более старые сообщения
|
||||
@@ -194,7 +223,7 @@ impl MessageManager {
|
||||
chat_id: ChatId,
|
||||
text: String,
|
||||
reply_to_message_id: Option<MessageId>,
|
||||
_reply_info: Option<ReplyInfo>,
|
||||
reply_info: Option<ReplyInfo>,
|
||||
) -> Result<MessageInfo, String> {
|
||||
// Парсим markdown в тексте
|
||||
let formatted_text = match functions::parse_text_entities(
|
||||
@@ -241,10 +270,19 @@ impl MessageManager {
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(tdlib_rs::enums::Message::Message(msg)) => self
|
||||
.convert_message(&msg)
|
||||
.await
|
||||
.ok_or_else(|| "Не удалось конвертировать сообщение".to_string()),
|
||||
Ok(tdlib_rs::enums::Message::Message(msg)) => {
|
||||
let mut msg_info = self
|
||||
.convert_message(&msg)
|
||||
.await
|
||||
.ok_or_else(|| "Не удалось конвертировать сообщение".to_string())?;
|
||||
|
||||
// Добавляем reply_info если был передан
|
||||
if let Some(reply) = reply_info {
|
||||
msg_info.interactions.reply_to = Some(reply);
|
||||
}
|
||||
|
||||
Ok(msg_info)
|
||||
}
|
||||
Ok(_) => Err("Неожиданный тип сообщения".to_string()),
|
||||
Err(e) => Err(format!("Ошибка отправки сообщения: {:?}", e)),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user