This commit is contained in:
Mikhail Kilin
2026-01-30 17:26:21 +03:00
parent a4cf6bac72
commit 433233d766
11 changed files with 603 additions and 315 deletions

View File

@@ -322,7 +322,7 @@ fn adjust_entities_for_substring(
pub fn render(f: &mut Frame, area: Rect, app: &App) {
// Режим профиля
if app.is_profile_mode() {
if let Some(profile) = &app.profile_info {
if let Some(profile) = app.get_profile_info() {
crate::ui::profile::render(f, area, app, profile);
}
return;
@@ -964,18 +964,31 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
}
// Модалка выбора реакции
if app.is_reaction_picker_mode() {
render_reaction_picker_modal(
f,
area,
&app.available_reactions,
app.selected_reaction_index,
);
if let crate::app::ChatState::ReactionPicker {
available_reactions,
selected_index,
..
} = &app.chat_state
{
render_reaction_picker_modal(f, area, available_reactions, *selected_index);
}
}
/// Рендерит режим поиска по сообщениям
fn render_search_mode(f: &mut Frame, area: Rect, app: &App) {
// Извлекаем данные из ChatState
let (query, results, selected_index) =
if let crate::app::ChatState::SearchInChat {
query,
results,
selected_index,
} = &app.chat_state
{
(query.as_str(), results.as_slice(), *selected_index)
} else {
return; // Некорректное состояние, не рендерим
};
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
@@ -986,14 +999,14 @@ fn render_search_mode(f: &mut Frame, area: Rect, app: &App) {
.split(area);
// Search input
let total = app.message_search_results.len();
let total = results.len();
let current = if total > 0 {
app.selected_search_result_index + 1
selected_index + 1
} else {
0
};
let input_line = if app.message_search_query.is_empty() {
let input_line = if query.is_empty() {
Line::from(vec![
Span::styled("🔍 ", Style::default().fg(Color::Yellow)),
Span::styled("", Style::default().fg(Color::Yellow)),
@@ -1002,7 +1015,7 @@ fn render_search_mode(f: &mut Frame, area: Rect, app: &App) {
} else {
Line::from(vec![
Span::styled("🔍 ", Style::default().fg(Color::Yellow)),
Span::styled(&app.message_search_query, Style::default().fg(Color::White)),
Span::styled(query, Style::default().fg(Color::White)),
Span::styled("", Style::default().fg(Color::Yellow)),
Span::styled(format!(" ({}/{})", current, total), Style::default().fg(Color::Gray)),
])
@@ -1025,16 +1038,16 @@ fn render_search_mode(f: &mut Frame, area: Rect, app: &App) {
let content_width = chunks[1].width.saturating_sub(2) as usize;
let mut lines: Vec<Line> = Vec::new();
if app.message_search_results.is_empty() {
if !app.message_search_query.is_empty() {
if results.is_empty() {
if !query.is_empty() {
lines.push(Line::from(Span::styled(
"Ничего не найдено",
Style::default().fg(Color::Gray),
)));
}
} else {
for (idx, msg) in app.message_search_results.iter().enumerate() {
let is_selected = idx == app.selected_search_result_index;
for (idx, msg) in results.iter().enumerate() {
let is_selected = idx == selected_index;
// Пустая строка между результатами
if idx > 0 {
@@ -1101,7 +1114,7 @@ fn render_search_mode(f: &mut Frame, area: Rect, app: &App) {
// Скролл к выбранному результату
let visible_height = chunks[1].height.saturating_sub(2) as usize;
let lines_per_result = 4;
let selected_line = app.selected_search_result_index * lines_per_result;
let selected_line = selected_index * lines_per_result;
let scroll_offset = if selected_line > visible_height / 2 {
(selected_line - visible_height / 2) as u16
} else {
@@ -1158,6 +1171,17 @@ fn render_search_mode(f: &mut Frame, area: Rect, app: &App) {
/// Рендерит режим просмотра закреплённых сообщений
fn render_pinned_mode(f: &mut Frame, area: Rect, app: &App) {
// Извлекаем данные из ChatState
let (messages, selected_index) = if let crate::app::ChatState::PinnedMessages {
messages,
selected_index,
} = &app.chat_state
{
(messages.as_slice(), *selected_index)
} else {
return; // Некорректное состояние
};
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
@@ -1168,8 +1192,8 @@ fn render_pinned_mode(f: &mut Frame, area: Rect, app: &App) {
.split(area);
// Header
let total = app.pinned_messages.len();
let current = app.selected_pinned_index + 1;
let total = messages.len();
let current = selected_index + 1;
let header_text = format!("📌 ЗАКРЕПЛЁННЫЕ ({}/{})", current, total);
let header = Paragraph::new(header_text)
.block(
@@ -1188,8 +1212,8 @@ fn render_pinned_mode(f: &mut Frame, area: Rect, app: &App) {
let content_width = chunks[1].width.saturating_sub(2) as usize;
let mut lines: Vec<Line> = Vec::new();
for (idx, msg) in app.pinned_messages.iter().enumerate() {
let is_selected = idx == app.selected_pinned_index;
for (idx, msg) in messages.iter().enumerate() {
let is_selected = idx == selected_index;
// Пустая строка между сообщениями
if idx > 0 {
@@ -1263,7 +1287,7 @@ fn render_pinned_mode(f: &mut Frame, area: Rect, app: &App) {
// Скролл к выбранному сообщению
let visible_height = chunks[1].height.saturating_sub(2) as usize;
let lines_per_msg = 5; // Примерно строк на сообщение
let selected_line = app.selected_pinned_index * lines_per_msg;
let selected_line = selected_index * lines_per_msg;
let scroll_offset = if selected_line > visible_height / 2 {
(selected_line - visible_height / 2) as u16
} else {