Some checks failed
ci/woodpecker/pr/check Pipeline was successful
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
- Add #[allow(unused_imports)] on pub re-exports used only by lib/tests - Add #[allow(dead_code)] on public API items unused in binary target - Fix collapsible_if, redundant_closure, unnecessary_map_or in main.rs - Prefix unused test variables with underscore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
166 lines
4.8 KiB
Rust
166 lines
4.8 KiB
Rust
//! Search methods for App
|
|
//!
|
|
//! Handles chat list search and message search within chat
|
|
|
|
use crate::app::{App, ChatFilter, ChatFilterCriteria, ChatState};
|
|
use crate::tdlib::{ChatInfo, MessageInfo, TdClientTrait};
|
|
|
|
/// Search methods for chats and messages
|
|
pub trait SearchMethods<T: TdClientTrait> {
|
|
// === Chat Search ===
|
|
|
|
/// Start search mode in chat list
|
|
fn start_search(&mut self);
|
|
|
|
/// Cancel search mode and reset query
|
|
fn cancel_search(&mut self);
|
|
|
|
/// Get filtered chats based on search query and selected folder
|
|
fn get_filtered_chats(&self) -> Vec<&ChatInfo>;
|
|
|
|
// === Message Search ===
|
|
|
|
/// Check if message search mode is active
|
|
fn is_message_search_mode(&self) -> bool;
|
|
|
|
/// Enter message search mode within chat
|
|
fn enter_message_search_mode(&mut self);
|
|
|
|
/// Exit message search mode
|
|
fn exit_message_search_mode(&mut self);
|
|
|
|
/// Set search results
|
|
fn set_search_results(&mut self, results: Vec<MessageInfo>);
|
|
|
|
/// Select previous search result (up)
|
|
fn select_previous_search_result(&mut self);
|
|
|
|
/// Select next search result (down)
|
|
fn select_next_search_result(&mut self);
|
|
|
|
/// Get currently selected search result
|
|
fn get_selected_search_result(&self) -> Option<&MessageInfo>;
|
|
|
|
/// Get ID of selected search result for navigation
|
|
fn get_selected_search_result_id(&self) -> Option<i64>;
|
|
|
|
/// Get current search query
|
|
fn get_search_query(&self) -> Option<&str>;
|
|
|
|
/// Update search query
|
|
fn update_search_query(&mut self, new_query: String);
|
|
|
|
/// Get index of selected search result
|
|
#[allow(dead_code)]
|
|
fn get_search_selected_index(&self) -> Option<usize>;
|
|
|
|
/// Get all search results
|
|
#[allow(dead_code)]
|
|
fn get_search_results(&self) -> Option<&[MessageInfo]>;
|
|
}
|
|
|
|
impl<T: TdClientTrait> SearchMethods<T> for App<T> {
|
|
fn start_search(&mut self) {
|
|
self.is_searching = true;
|
|
self.search_query.clear();
|
|
}
|
|
|
|
fn cancel_search(&mut self) {
|
|
self.is_searching = false;
|
|
self.search_query.clear();
|
|
self.chat_list_state.select(Some(0));
|
|
}
|
|
|
|
fn get_filtered_chats(&self) -> Vec<&ChatInfo> {
|
|
// Используем ChatFilter для централизованной фильтрации
|
|
let mut criteria = ChatFilterCriteria::new().with_folder(self.selected_folder_id);
|
|
|
|
if !self.search_query.is_empty() {
|
|
criteria = criteria.with_search(self.search_query.clone());
|
|
}
|
|
|
|
ChatFilter::filter(&self.chats, &criteria)
|
|
}
|
|
|
|
fn is_message_search_mode(&self) -> bool {
|
|
self.chat_state.is_search_in_chat()
|
|
}
|
|
|
|
fn enter_message_search_mode(&mut self) {
|
|
self.chat_state = ChatState::SearchInChat {
|
|
query: String::new(),
|
|
results: Vec::new(),
|
|
selected_index: 0,
|
|
};
|
|
}
|
|
|
|
fn exit_message_search_mode(&mut self) {
|
|
self.chat_state = ChatState::Normal;
|
|
}
|
|
|
|
fn set_search_results(&mut self, results: Vec<MessageInfo>) {
|
|
if let ChatState::SearchInChat { results: r, selected_index, .. } = &mut self.chat_state {
|
|
*r = results;
|
|
*selected_index = 0;
|
|
}
|
|
}
|
|
|
|
fn select_previous_search_result(&mut self) {
|
|
if let ChatState::SearchInChat { selected_index, .. } = &mut self.chat_state {
|
|
if *selected_index > 0 {
|
|
*selected_index -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn select_next_search_result(&mut self) {
|
|
if let ChatState::SearchInChat { selected_index, results, .. } = &mut self.chat_state {
|
|
if *selected_index + 1 < results.len() {
|
|
*selected_index += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_selected_search_result(&self) -> Option<&MessageInfo> {
|
|
if let ChatState::SearchInChat { results, selected_index, .. } = &self.chat_state {
|
|
results.get(*selected_index)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn get_selected_search_result_id(&self) -> Option<i64> {
|
|
self.get_selected_search_result().map(|m| m.id().as_i64())
|
|
}
|
|
|
|
fn get_search_query(&self) -> Option<&str> {
|
|
if let ChatState::SearchInChat { query, .. } = &self.chat_state {
|
|
Some(query.as_str())
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn update_search_query(&mut self, new_query: String) {
|
|
if let ChatState::SearchInChat { query, .. } = &mut self.chat_state {
|
|
*query = new_query;
|
|
}
|
|
}
|
|
|
|
fn get_search_selected_index(&self) -> Option<usize> {
|
|
if let ChatState::SearchInChat { selected_index, .. } = &self.chat_state {
|
|
Some(*selected_index)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn get_search_results(&self) -> Option<&[MessageInfo]> {
|
|
if let ChatState::SearchInChat { results, .. } = &self.chat_state {
|
|
Some(results.as_slice())
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|