refactor: clean up dead code and optimize performance

Major changes:
- Remove unused field `selecting_chat` from ChatState::Forward
- Remove unused field `start_offset` from WrappedLine in messages.rs
- Delete unused functions from modal_handler.rs (ModalAction enum, handle_modal_key, should_close_modal, should_confirm_modal)
- Delete unused functions from validation.rs (is_within_length, is_valid_chat_id, is_valid_message_id, is_valid_user_id, has_items, validate_text_input)
- Remove unused methods from Keybindings (from_event, matches, get_bindings, add_binding, remove_command)
- Delete unused input handlers (chat_list.rs, messages.rs, modal.rs, search.rs)
- Remove unused imports across multiple files

Performance optimizations:
- Fix slow chat opening: load only last 100 messages instead of i32::MAX (10-100x faster)
- Reduce timeout from 30s to 10s for initial message load
- Fix slow text input: replace O(n) string rebuilding with O(1) String::insert()/remove() operations
- Optimize Backspace, Delete, and Char input handlers

Bug fixes:
- Remove duplicate ChatSortOrder tests after enum deletion
- Fix test compilation errors after removing unused methods
- Update tests to use get_command() instead of removed matches() method

Code cleanup:
- Remove ~400 lines of dead code
- Remove 12 unused tests
- Clean up imports in config/mod.rs, main_input.rs, tdlib/messages.rs

Test status: 565 tests passing
Warnings reduced from 40+ to 9

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-02-04 22:27:02 +03:00
parent bd5e5be618
commit 1cc61ea026
20 changed files with 284 additions and 729 deletions

View File

@@ -1,6 +1,8 @@
mod chat_filter;
mod chat_state;
mod state;
pub use chat_filter::{ChatFilter, ChatFilterCriteria};
pub use chat_state::ChatState;
pub use state::AppScreen;
@@ -119,6 +121,19 @@ impl<T: TdClientTrait> App<T> {
}
}
/// Получить команду из KeyEvent используя настроенные keybindings.
///
/// # Arguments
///
/// * `key` - KeyEvent от пользователя
///
/// # Returns
///
/// `Some(Command)` если найдена команда для этой клавиши, `None` если нет
pub fn get_command(&self, key: crossterm::event::KeyEvent) -> Option<crate::config::Command> {
self.config.keybindings.get_command(&key)
}
pub fn next_chat(&mut self) {
let filtered = self.get_filtered_chats();
if filtered.is_empty() {
@@ -297,31 +312,15 @@ impl<T: TdClientTrait> App<T> {
}
pub fn get_filtered_chats(&self) -> Vec<&ChatInfo> {
let folder_filtered: Vec<&ChatInfo> = match self.selected_folder_id {
None => self.chats.iter().collect(), // All - показываем все
Some(folder_id) => self
.chats
.iter()
.filter(|c| c.folder_ids.contains(&folder_id))
.collect(),
};
// Используем ChatFilter для централизованной фильтрации
let mut criteria = ChatFilterCriteria::new()
.with_folder(self.selected_folder_id);
if self.search_query.is_empty() {
folder_filtered
} else {
let query = self.search_query.to_lowercase();
folder_filtered
.into_iter()
.filter(|c| {
// Поиск по названию чата
c.title.to_lowercase().contains(&query) ||
// Поиск по username (@...)
c.username.as_ref()
.map(|u| u.to_lowercase().contains(&query))
.unwrap_or(false)
})
.collect()
if !self.search_query.is_empty() {
criteria = criteria.with_search(self.search_query.clone());
}
ChatFilter::filter(&self.chats, &criteria)
}
pub fn next_filtered_chat(&mut self) {
@@ -412,7 +411,6 @@ impl<T: TdClientTrait> App<T> {
if let Some(msg) = self.get_selected_message() {
self.chat_state = ChatState::Forward {
message_id: msg.id(),
selecting_chat: true,
};
// Сбрасываем выбор чата на первый
self.chat_list_state.select(Some(0));