//! Search input handlers //! //! Handles keyboard input for search functionality, including: //! - Chat list search mode //! - Message search mode //! - Search query input use crate::app::App; use crate::app::methods::{navigation::NavigationMethods, search::SearchMethods}; use crate::tdlib::TdClientTrait; use crate::types::{ChatId, MessageId}; use crate::utils::with_timeout; use crossterm::event::{KeyCode, KeyEvent}; use std::time::Duration; use super::chat_list::open_chat_and_load_data; use super::scroll_to_message; /// Обработка режима поиска по чатам /// /// Обрабатывает: /// - Редактирование поискового запроса (Backspace, Char) /// - Навигацию по отфильтрованному списку (Up/Down) /// - Открытие выбранного чата (Enter) /// - Отмену поиска (Esc) pub async fn handle_chat_search_mode(app: &mut App, key: KeyEvent, command: Option) { match command { Some(crate::config::Command::Cancel) => { app.cancel_search(); } Some(crate::config::Command::SubmitMessage) => { app.select_filtered_chat(); if let Some(chat_id) = app.get_selected_chat_id() { open_chat_and_load_data(app, chat_id).await; } } Some(crate::config::Command::MoveDown) => { app.next_filtered_chat(); } Some(crate::config::Command::MoveUp) => { app.previous_filtered_chat(); } _ => { match key.code { KeyCode::Backspace => { app.search_query.pop(); app.chat_list_state.select(Some(0)); } KeyCode::Char(c) => { app.search_query.push(c); app.chat_list_state.select(Some(0)); } _ => {} } } } } /// Обработка режима поиска по сообщениям в открытом чате /// /// Обрабатывает: /// - Навигацию по результатам поиска (Up/Down/N/n) /// - Переход к выбранному сообщению (Enter) /// - Редактирование поискового запроса (Backspace, Char) /// - Выход из режима поиска (Esc) pub async fn handle_message_search_mode(app: &mut App, key: KeyEvent, command: Option) { match command { Some(crate::config::Command::Cancel) => { app.exit_message_search_mode(); } Some(crate::config::Command::MoveUp) => { app.select_previous_search_result(); } Some(crate::config::Command::MoveDown) => { app.select_next_search_result(); } Some(crate::config::Command::SubmitMessage) => { if let Some(msg_id) = app.get_selected_search_result_id() { scroll_to_message(app, MessageId::new(msg_id)); app.exit_message_search_mode(); } } _ => { match key.code { KeyCode::Char('N') => { app.select_previous_search_result(); } KeyCode::Char('n') => { app.select_next_search_result(); } KeyCode::Backspace => { let Some(mut query) = app.get_search_query().map(|s| s.to_string()) else { return; }; query.pop(); app.update_search_query(query.clone()); perform_message_search(app, &query).await; } KeyCode::Char(c) => { let Some(mut query) = app.get_search_query().map(|s| s.to_string()) else { return; }; query.push(c); app.update_search_query(query.clone()); perform_message_search(app, &query).await; } _ => {} } } } } /// Выполняет поиск по сообщениям с обновлением результатов pub async fn perform_message_search(app: &mut App, query: &str) { let Some(chat_id) = app.get_selected_chat_id() else { return; }; if query.is_empty() { app.set_search_results(Vec::new()); return; } if let Ok(results) = with_timeout( Duration::from_secs(3), app.td_client.search_messages(ChatId::new(chat_id), query), ) .await { app.set_search_results(results); } }