style: auto-format entire codebase with cargo fmt (stable rustfmt.toml)
Some checks failed
ci/woodpecker/pr/check Pipeline failed
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
Some checks failed
ci/woodpecker/pr/check Pipeline failed
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
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
/// - По статусу (archived, muted, и т.д.)
|
||||
///
|
||||
/// Используется как в App, так и в UI слое для консистентной фильтрации.
|
||||
|
||||
use crate::tdlib::ChatInfo;
|
||||
|
||||
/// Критерии фильтрации чатов
|
||||
@@ -42,18 +41,12 @@ impl ChatFilterCriteria {
|
||||
|
||||
/// Фильтр только по папке
|
||||
pub fn by_folder(folder_id: Option<i32>) -> Self {
|
||||
Self {
|
||||
folder_id,
|
||||
..Default::default()
|
||||
}
|
||||
Self { folder_id, ..Default::default() }
|
||||
}
|
||||
|
||||
/// Фильтр только по поисковому запросу
|
||||
pub fn by_search(query: String) -> Self {
|
||||
Self {
|
||||
search_query: Some(query),
|
||||
..Default::default()
|
||||
}
|
||||
Self { search_query: Some(query), ..Default::default() }
|
||||
}
|
||||
|
||||
/// Builder: установить папку
|
||||
@@ -176,10 +169,7 @@ impl ChatFilter {
|
||||
///
|
||||
/// let filtered = ChatFilter::filter(&all_chats, &criteria);
|
||||
/// ```
|
||||
pub fn filter<'a>(
|
||||
chats: &'a [ChatInfo],
|
||||
criteria: &ChatFilterCriteria,
|
||||
) -> Vec<&'a ChatInfo> {
|
||||
pub fn filter<'a>(chats: &'a [ChatInfo], criteria: &ChatFilterCriteria) -> Vec<&'a ChatInfo> {
|
||||
chats.iter().filter(|chat| criteria.matches(chat)).collect()
|
||||
}
|
||||
|
||||
@@ -309,8 +299,7 @@ mod tests {
|
||||
let filtered = ChatFilter::filter(&chats, &criteria);
|
||||
assert_eq!(filtered.len(), 2); // Chat 1 and Chat 3 have unread
|
||||
|
||||
let criteria = ChatFilterCriteria::new()
|
||||
.pinned_only(true);
|
||||
let criteria = ChatFilterCriteria::new().pinned_only(true);
|
||||
|
||||
let filtered = ChatFilter::filter(&chats, &criteria);
|
||||
assert_eq!(filtered.len(), 1); // Only Chat 1 is pinned
|
||||
@@ -330,5 +319,4 @@ mod tests {
|
||||
assert_eq!(ChatFilter::count_unread(&chats, &criteria), 15); // 5 + 10
|
||||
assert_eq!(ChatFilter::count_unread_mentions(&chats, &criteria), 3); // 1 + 2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
//!
|
||||
//! Handles reply, forward, and draft functionality
|
||||
|
||||
use crate::app::{App, ChatState};
|
||||
use crate::app::methods::messages::MessageMethods;
|
||||
use crate::app::{App, ChatState};
|
||||
use crate::tdlib::{MessageInfo, TdClientTrait};
|
||||
|
||||
/// Compose methods for reply/forward/draft
|
||||
@@ -44,9 +44,7 @@ pub trait ComposeMethods<T: TdClientTrait> {
|
||||
impl<T: TdClientTrait> ComposeMethods<T> for App<T> {
|
||||
fn start_reply_to_selected(&mut self) -> bool {
|
||||
if let Some(msg) = self.get_selected_message() {
|
||||
self.chat_state = ChatState::Reply {
|
||||
message_id: msg.id(),
|
||||
};
|
||||
self.chat_state = ChatState::Reply { message_id: msg.id() };
|
||||
return true;
|
||||
}
|
||||
false
|
||||
@@ -72,9 +70,7 @@ impl<T: TdClientTrait> ComposeMethods<T> for App<T> {
|
||||
|
||||
fn start_forward_selected(&mut self) -> bool {
|
||||
if let Some(msg) = self.get_selected_message() {
|
||||
self.chat_state = ChatState::Forward {
|
||||
message_id: msg.id(),
|
||||
};
|
||||
self.chat_state = ChatState::Forward { message_id: msg.id() };
|
||||
// Сбрасываем выбор чата на первый
|
||||
self.chat_list_state.select(Some(0));
|
||||
return true;
|
||||
|
||||
@@ -61,8 +61,7 @@ impl<T: TdClientTrait> MessageMethods<T> for App<T> {
|
||||
// Перескакиваем через все сообщения текущего альбома назад
|
||||
let mut new_index = *selected_index - 1;
|
||||
if current_album_id != 0 {
|
||||
while new_index > 0
|
||||
&& messages[new_index].media_album_id() == current_album_id
|
||||
while new_index > 0 && messages[new_index].media_album_id() == current_album_id
|
||||
{
|
||||
new_index -= 1;
|
||||
}
|
||||
@@ -125,9 +124,9 @@ impl<T: TdClientTrait> MessageMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn get_selected_message(&self) -> Option<MessageInfo> {
|
||||
self.chat_state.selected_message_index().and_then(|idx| {
|
||||
self.td_client.current_chat_messages().get(idx).cloned()
|
||||
})
|
||||
self.chat_state
|
||||
.selected_message_index()
|
||||
.and_then(|idx| self.td_client.current_chat_messages().get(idx).cloned())
|
||||
}
|
||||
|
||||
fn start_editing_selected(&mut self) -> bool {
|
||||
@@ -158,10 +157,7 @@ impl<T: TdClientTrait> MessageMethods<T> for App<T> {
|
||||
if let Some((id, content, idx)) = msg_data {
|
||||
self.cursor_position = content.chars().count();
|
||||
self.message_input = content;
|
||||
self.chat_state = ChatState::Editing {
|
||||
message_id: id,
|
||||
selected_index: idx,
|
||||
};
|
||||
self.chat_state = ChatState::Editing { message_id: id, selected_index: idx };
|
||||
return true;
|
||||
}
|
||||
false
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
//! - search: Search in chats and messages
|
||||
//! - modal: Modal dialogs (Profile, Pinned, Reactions, Delete)
|
||||
|
||||
pub mod navigation;
|
||||
pub mod messages;
|
||||
pub mod compose;
|
||||
pub mod search;
|
||||
pub mod messages;
|
||||
pub mod modal;
|
||||
pub mod navigation;
|
||||
pub mod search;
|
||||
|
||||
pub use navigation::NavigationMethods;
|
||||
pub use messages::MessageMethods;
|
||||
pub use compose::ComposeMethods;
|
||||
pub use search::SearchMethods;
|
||||
pub use messages::MessageMethods;
|
||||
pub use modal::ModalMethods;
|
||||
pub use navigation::NavigationMethods;
|
||||
pub use search::SearchMethods;
|
||||
|
||||
@@ -106,10 +106,7 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
|
||||
fn enter_pinned_mode(&mut self, messages: Vec<MessageInfo>) {
|
||||
if !messages.is_empty() {
|
||||
self.chat_state = ChatState::PinnedMessages {
|
||||
messages,
|
||||
selected_index: 0,
|
||||
};
|
||||
self.chat_state = ChatState::PinnedMessages { messages, selected_index: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,11 +115,7 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn select_previous_pinned(&mut self) {
|
||||
if let ChatState::PinnedMessages {
|
||||
selected_index,
|
||||
messages,
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::PinnedMessages { selected_index, messages } = &mut self.chat_state {
|
||||
if *selected_index + 1 < messages.len() {
|
||||
*selected_index += 1;
|
||||
}
|
||||
@@ -138,11 +131,7 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn get_selected_pinned(&self) -> Option<&MessageInfo> {
|
||||
if let ChatState::PinnedMessages {
|
||||
messages,
|
||||
selected_index,
|
||||
} = &self.chat_state
|
||||
{
|
||||
if let ChatState::PinnedMessages { messages, selected_index } = &self.chat_state {
|
||||
messages.get(*selected_index)
|
||||
} else {
|
||||
None
|
||||
@@ -170,10 +159,7 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn select_previous_profile_action(&mut self) {
|
||||
if let ChatState::Profile {
|
||||
selected_action, ..
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { selected_action, .. } = &mut self.chat_state {
|
||||
if *selected_action > 0 {
|
||||
*selected_action -= 1;
|
||||
}
|
||||
@@ -181,10 +167,7 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn select_next_profile_action(&mut self, max_actions: usize) {
|
||||
if let ChatState::Profile {
|
||||
selected_action, ..
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { selected_action, .. } = &mut self.chat_state {
|
||||
if *selected_action < max_actions.saturating_sub(1) {
|
||||
*selected_action += 1;
|
||||
}
|
||||
@@ -192,41 +175,25 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn show_leave_group_confirmation(&mut self) {
|
||||
if let ChatState::Profile {
|
||||
leave_group_confirmation_step,
|
||||
..
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { leave_group_confirmation_step, .. } = &mut self.chat_state {
|
||||
*leave_group_confirmation_step = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn show_leave_group_final_confirmation(&mut self) {
|
||||
if let ChatState::Profile {
|
||||
leave_group_confirmation_step,
|
||||
..
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { leave_group_confirmation_step, .. } = &mut self.chat_state {
|
||||
*leave_group_confirmation_step = 2;
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel_leave_group(&mut self) {
|
||||
if let ChatState::Profile {
|
||||
leave_group_confirmation_step,
|
||||
..
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { leave_group_confirmation_step, .. } = &mut self.chat_state {
|
||||
*leave_group_confirmation_step = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_leave_group_confirmation_step(&self) -> u8 {
|
||||
if let ChatState::Profile {
|
||||
leave_group_confirmation_step,
|
||||
..
|
||||
} = &self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { leave_group_confirmation_step, .. } = &self.chat_state {
|
||||
*leave_group_confirmation_step
|
||||
} else {
|
||||
0
|
||||
@@ -242,10 +209,7 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn get_selected_profile_action(&self) -> Option<usize> {
|
||||
if let ChatState::Profile {
|
||||
selected_action, ..
|
||||
} = &self.chat_state
|
||||
{
|
||||
if let ChatState::Profile { selected_action, .. } = &self.chat_state {
|
||||
Some(*selected_action)
|
||||
} else {
|
||||
None
|
||||
@@ -277,11 +241,8 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn select_next_reaction(&mut self) {
|
||||
if let ChatState::ReactionPicker {
|
||||
selected_index,
|
||||
available_reactions,
|
||||
..
|
||||
} = &mut self.chat_state
|
||||
if let ChatState::ReactionPicker { selected_index, available_reactions, .. } =
|
||||
&mut self.chat_state
|
||||
{
|
||||
if *selected_index + 1 < available_reactions.len() {
|
||||
*selected_index += 1;
|
||||
@@ -290,11 +251,8 @@ impl<T: TdClientTrait> ModalMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn get_selected_reaction(&self) -> Option<&String> {
|
||||
if let ChatState::ReactionPicker {
|
||||
available_reactions,
|
||||
selected_index,
|
||||
..
|
||||
} = &self.chat_state
|
||||
if let ChatState::ReactionPicker { available_reactions, selected_index, .. } =
|
||||
&self.chat_state
|
||||
{
|
||||
available_reactions.get(*selected_index)
|
||||
} else {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
//!
|
||||
//! Handles chat list navigation and selection
|
||||
|
||||
use crate::app::{App, ChatState, InputMode};
|
||||
use crate::app::methods::search::SearchMethods;
|
||||
use crate::app::{App, ChatState, InputMode};
|
||||
use crate::tdlib::TdClientTrait;
|
||||
|
||||
/// Navigation methods for chat list
|
||||
|
||||
@@ -71,8 +71,7 @@ impl<T: TdClientTrait> SearchMethods<T> for App<T> {
|
||||
|
||||
fn get_filtered_chats(&self) -> Vec<&ChatInfo> {
|
||||
// Используем ChatFilter для централизованной фильтрации
|
||||
let mut criteria = ChatFilterCriteria::new()
|
||||
.with_folder(self.selected_folder_id);
|
||||
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());
|
||||
@@ -113,12 +112,7 @@ impl<T: TdClientTrait> SearchMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn select_next_search_result(&mut self) {
|
||||
if let ChatState::SearchInChat {
|
||||
selected_index,
|
||||
results,
|
||||
..
|
||||
} = &mut self.chat_state
|
||||
{
|
||||
if let ChatState::SearchInChat { selected_index, results, .. } = &mut self.chat_state {
|
||||
if *selected_index + 1 < results.len() {
|
||||
*selected_index += 1;
|
||||
}
|
||||
@@ -126,12 +120,7 @@ impl<T: TdClientTrait> SearchMethods<T> for App<T> {
|
||||
}
|
||||
|
||||
fn get_selected_search_result(&self) -> Option<&MessageInfo> {
|
||||
if let ChatState::SearchInChat {
|
||||
results,
|
||||
selected_index,
|
||||
..
|
||||
} = &self.chat_state
|
||||
{
|
||||
if let ChatState::SearchInChat { results, selected_index, .. } = &self.chat_state {
|
||||
results.get(*selected_index)
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
mod chat_filter;
|
||||
mod chat_state;
|
||||
mod state;
|
||||
pub mod methods;
|
||||
mod state;
|
||||
|
||||
pub use chat_filter::{ChatFilter, ChatFilterCriteria};
|
||||
pub use chat_state::{ChatState, InputMode};
|
||||
pub use state::AppScreen;
|
||||
pub use methods::*;
|
||||
pub use state::AppScreen;
|
||||
|
||||
use crate::accounts::AccountProfile;
|
||||
use crate::tdlib::{ChatInfo, TdClient, TdClientTrait};
|
||||
@@ -165,9 +165,7 @@ impl<T: TdClientTrait> App<T> {
|
||||
let audio_cache_size_mb = config.audio.cache_size_mb;
|
||||
|
||||
#[cfg(feature = "images")]
|
||||
let image_cache = Some(crate::media::cache::ImageCache::new(
|
||||
config.images.cache_size_mb,
|
||||
));
|
||||
let image_cache = Some(crate::media::cache::ImageCache::new(config.images.cache_size_mb));
|
||||
#[cfg(feature = "images")]
|
||||
let inline_image_renderer = crate::media::image_renderer::ImageRenderer::new_fast();
|
||||
#[cfg(feature = "images")]
|
||||
@@ -275,11 +273,8 @@ impl<T: TdClientTrait> App<T> {
|
||||
|
||||
/// Navigate to next item in account switcher list.
|
||||
pub fn account_switcher_select_next(&mut self) {
|
||||
if let Some(AccountSwitcherState::SelectAccount {
|
||||
accounts,
|
||||
selected_index,
|
||||
..
|
||||
}) = &mut self.account_switcher
|
||||
if let Some(AccountSwitcherState::SelectAccount { accounts, selected_index, .. }) =
|
||||
&mut self.account_switcher
|
||||
{
|
||||
// +1 for the "Add account" item at the end
|
||||
let max_index = accounts.len();
|
||||
@@ -372,20 +367,6 @@ impl<T: TdClientTrait> App<T> {
|
||||
.and_then(|id| self.chats.iter().find(|c| c.id == id))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ========== Getter/Setter методы для инкапсуляции ==========
|
||||
|
||||
// Config
|
||||
|
||||
Reference in New Issue
Block a user