diff --git a/src/tdlib/client.rs b/src/tdlib/client.rs index 4c43433..b321c09 100644 --- a/src/tdlib/client.rs +++ b/src/tdlib/client.rs @@ -6,7 +6,7 @@ use tdlib_rs::enums::{ MessageSender, Update, UserStatus, Chat as TdChat }; -use tdlib_rs::types::{Message as TdMessage}; +use tdlib_rs::types::{Message as TdMessage, UpdateNewMessage, UpdateChatAction}; use tdlib_rs::functions; use crate::constants::{MAX_CHAT_USER_IDS, MAX_CHATS}; @@ -549,46 +549,7 @@ impl TdClient { } } Update::NewMessage(new_msg) => { - // Добавляем новое сообщение если это текущий открытый чат - let chat_id = ChatId::new(new_msg.message.chat_id); - if Some(chat_id) == self.current_chat_id() { - let msg_info = self.convert_message(&new_msg.message, chat_id); - let msg_id = msg_info.id(); - let is_incoming = !msg_info.is_outgoing(); - - // Проверяем, есть ли уже сообщение с таким id - let existing_idx = self - .current_chat_messages() - .iter() - .position(|m| m.id() == msg_info.id()); - - match existing_idx { - Some(idx) => { - // Сообщение уже есть - обновляем - if is_incoming { - self.current_chat_messages_mut()[idx] = msg_info; - } else { - // Для исходящих: обновляем can_be_edited и другие поля, - // но сохраняем reply_to (добавленный при отправке) - let existing = &mut self.current_chat_messages_mut()[idx]; - existing.state.can_be_edited = msg_info.state.can_be_edited; - existing.state.can_be_deleted_only_for_self = - msg_info.state.can_be_deleted_only_for_self; - existing.state.can_be_deleted_for_all_users = - msg_info.state.can_be_deleted_for_all_users; - existing.state.is_read = msg_info.state.is_read; - } - } - None => { - // Нового сообщения нет - добавляем - self.push_message(msg_info.clone()); - // Если это входящее сообщение — добавляем в очередь для отметки как прочитанное - if is_incoming { - self.pending_view_messages_mut().push((chat_id, vec![msg_id])); - } - } - } - } + self.handle_new_message_update(new_msg); } Update::User(update) => { // Сохраняем имя и username пользователя @@ -662,51 +623,7 @@ impl TdClient { }; } Update::ChatAction(update) => { - // Обрабатываем только для текущего открытого чата - if Some(ChatId::new(update.chat_id)) == self.current_chat_id() { - // Извлекаем user_id из sender_id - let user_id = match update.sender_id { - MessageSender::User(user) => Some(UserId::new(user.user_id)), - MessageSender::Chat(_) => None, // Игнорируем действия от имени чата - }; - - if let Some(user_id) = user_id { - // Определяем текст действия - let action_text = match update.action { - ChatAction::Typing => Some("печатает...".to_string()), - ChatAction::RecordingVideo => Some("записывает видео...".to_string()), - ChatAction::UploadingVideo(_) => { - Some("отправляет видео...".to_string()) - } - ChatAction::RecordingVoiceNote => { - Some("записывает голосовое...".to_string()) - } - ChatAction::UploadingVoiceNote(_) => { - Some("отправляет голосовое...".to_string()) - } - ChatAction::UploadingPhoto(_) => Some("отправляет фото...".to_string()), - ChatAction::UploadingDocument(_) => { - Some("отправляет файл...".to_string()) - } - ChatAction::ChoosingSticker => Some("выбирает стикер...".to_string()), - ChatAction::RecordingVideoNote => { - Some("записывает видеосообщение...".to_string()) - } - ChatAction::UploadingVideoNote(_) => { - Some("отправляет видеосообщение...".to_string()) - } - ChatAction::Cancel => None, // Отмена — сбрасываем статус - _ => None, - }; - - if let Some(text) = action_text { - self.set_typing_status(Some((user_id, text, Instant::now()))); - } else { - // Cancel или неизвестное действие — сбрасываем - self.set_typing_status(None); - } - } - } + self.handle_chat_action_update(update); } Update::ChatDraftMessage(update) => { // Обновляем черновик в списке чатов @@ -796,6 +713,100 @@ impl TdClient { } } + + /// Обрабатывает Update::NewMessage - добавление нового сообщения + fn handle_new_message_update(&mut self, new_msg: UpdateNewMessage) { + // Добавляем новое сообщение если это текущий открытый чат + let chat_id = ChatId::new(new_msg.message.chat_id); + if Some(chat_id) == self.current_chat_id() { + let msg_info = self.convert_message(&new_msg.message, chat_id); + let msg_id = msg_info.id(); + let is_incoming = !msg_info.is_outgoing(); + + // Проверяем, есть ли уже сообщение с таким id + let existing_idx = self + .current_chat_messages() + .iter() + .position(|m| m.id() == msg_info.id()); + + match existing_idx { + Some(idx) => { + // Сообщение уже есть - обновляем + if is_incoming { + self.current_chat_messages_mut()[idx] = msg_info; + } else { + // Для исходящих: обновляем can_be_edited и другие поля, + // но сохраняем reply_to (добавленный при отправке) + let existing = &mut self.current_chat_messages_mut()[idx]; + existing.state.can_be_edited = msg_info.state.can_be_edited; + existing.state.can_be_deleted_only_for_self = + msg_info.state.can_be_deleted_only_for_self; + existing.state.can_be_deleted_for_all_users = + msg_info.state.can_be_deleted_for_all_users; + existing.state.is_read = msg_info.state.is_read; + } + } + None => { + // Нового сообщения нет - добавляем + self.push_message(msg_info.clone()); + // Если это входящее сообщение — добавляем в очередь для отметки как прочитанное + if is_incoming { + self.pending_view_messages_mut().push((chat_id, vec![msg_id])); + } + } + } + } + } + + /// Обрабатывает Update::ChatAction - статус набора текста/отправки файлов + fn handle_chat_action_update(&mut self, update: UpdateChatAction) { + // Обрабатываем только для текущего открытого чата + if Some(ChatId::new(update.chat_id)) == self.current_chat_id() { + // Извлекаем user_id из sender_id + let user_id = match update.sender_id { + MessageSender::User(user) => Some(UserId::new(user.user_id)), + MessageSender::Chat(_) => None, // Игнорируем действия от имени чата + }; + + if let Some(user_id) = user_id { + // Определяем текст действия + let action_text = match update.action { + ChatAction::Typing => Some("печатает...".to_string()), + ChatAction::RecordingVideo => Some("записывает видео...".to_string()), + ChatAction::UploadingVideo(_) => { + Some("отправляет видео...".to_string()) + } + ChatAction::RecordingVoiceNote => { + Some("записывает голосовое...".to_string()) + } + ChatAction::UploadingVoiceNote(_) => { + Some("отправляет голосовое...".to_string()) + } + ChatAction::UploadingPhoto(_) => Some("отправляет фото...".to_string()), + ChatAction::UploadingDocument(_) => { + Some("отправляет файл...".to_string()) + } + ChatAction::ChoosingSticker => Some("выбирает стикер...".to_string()), + ChatAction::RecordingVideoNote => { + Some("записывает видеосообщение...".to_string()) + } + ChatAction::UploadingVideoNote(_) => { + Some("отправляет видеосообщение...".to_string()) + } + ChatAction::Cancel => None, // Отмена — сбрасываем статус + _ => None, + }; + + if let Some(text) = action_text { + self.set_typing_status(Some((user_id, text, Instant::now()))); + } else { + // Cancel или неизвестное действие — сбрасываем + self.set_typing_status(None); + } + } + } + } + fn handle_auth_state(&mut self, state: AuthorizationState) { self.auth.state = match state { AuthorizationState::WaitTdlibParameters => AuthState::WaitTdlibParameters,