fixes
This commit is contained in:
@@ -668,6 +668,58 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Отображаем реакции под сообщением
|
||||
if !msg.reactions.is_empty() {
|
||||
let mut reaction_spans = vec![];
|
||||
|
||||
for reaction in &msg.reactions {
|
||||
if !reaction_spans.is_empty() {
|
||||
reaction_spans.push(Span::raw(" "));
|
||||
}
|
||||
|
||||
// Свои реакции в рамках [emoji], чужие просто emoji
|
||||
let reaction_text = if reaction.is_chosen {
|
||||
if reaction.count > 1 {
|
||||
format!("[{}] {}", reaction.emoji, reaction.count)
|
||||
} else {
|
||||
format!("[{}]", reaction.emoji)
|
||||
}
|
||||
} else {
|
||||
if reaction.count > 1 {
|
||||
format!("{} {}", reaction.emoji, reaction.count)
|
||||
} else {
|
||||
reaction.emoji.clone()
|
||||
}
|
||||
};
|
||||
|
||||
let style = if reaction.is_chosen {
|
||||
Style::default().fg(Color::Yellow)
|
||||
} else {
|
||||
Style::default().fg(Color::Gray)
|
||||
};
|
||||
|
||||
reaction_spans.push(Span::styled(reaction_text, style));
|
||||
}
|
||||
|
||||
// Выравниваем реакции в зависимости от типа сообщения
|
||||
if msg.is_outgoing {
|
||||
// Реакции справа для исходящих
|
||||
let reactions_text: String = reaction_spans
|
||||
.iter()
|
||||
.map(|s| s.content.as_ref())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
let reactions_len = reactions_text.chars().count();
|
||||
let padding = content_width.saturating_sub(reactions_len + 1);
|
||||
let mut line_spans = vec![Span::raw(" ".repeat(padding))];
|
||||
line_spans.extend(reaction_spans);
|
||||
lines.push(Line::from(line_spans));
|
||||
} else {
|
||||
// Реакции слева для входящих
|
||||
lines.push(Line::from(reaction_spans));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if lines.is_empty() {
|
||||
@@ -734,10 +786,10 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
let can_delete = selected_msg.map(|m| m.can_be_deleted_only_for_self || m.can_be_deleted_for_all_users).unwrap_or(false);
|
||||
|
||||
let hint = match (can_edit, can_delete) {
|
||||
(true, true) => "↑↓ · Enter ред. · r ответ · f перслть · d удал. · Esc",
|
||||
(true, false) => "↑↓ · Enter ред. · r ответ · f переслть · Esc",
|
||||
(false, true) => "↑↓ · r ответ · f переслать · d удалить · Esc",
|
||||
(false, false) => "↑↓ · r ответить · f переслать · Esc",
|
||||
(true, true) => "↑↓ · Enter ред. · r ответ · f перслть · y копир. · d удал. · Esc",
|
||||
(true, false) => "↑↓ · Enter ред. · r ответ · f переслть · y копир. · Esc",
|
||||
(false, true) => "↑↓ · r ответ · f переслать · y копир. · d удалить · Esc",
|
||||
(false, false) => "↑↓ · r ответить · f переслать · y копировать · Esc",
|
||||
};
|
||||
(Line::from(Span::styled(hint, Style::default().fg(Color::Cyan))), " Выбор сообщения ")
|
||||
} else if app.is_editing() {
|
||||
@@ -827,6 +879,11 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
if app.is_confirm_delete_shown() {
|
||||
render_delete_confirm_modal(f, area);
|
||||
}
|
||||
|
||||
// Модалка выбора реакции
|
||||
if app.is_reaction_picker_mode() {
|
||||
render_reaction_picker_modal(f, area, &app.available_reactions, app.selected_reaction_index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Рендерит режим поиска по сообщениям
|
||||
@@ -1136,3 +1193,78 @@ fn render_delete_confirm_modal(f: &mut Frame, area: Rect) {
|
||||
|
||||
f.render_widget(modal, modal_area);
|
||||
}
|
||||
|
||||
|
||||
/// Рендерит модалку выбора реакции
|
||||
fn render_reaction_picker_modal(f: &mut Frame, area: Rect, available_reactions: &[String], selected_index: usize) {
|
||||
use ratatui::widgets::Clear;
|
||||
|
||||
// Размеры модалки (зависят от количества реакций)
|
||||
let emojis_per_row = 8;
|
||||
let rows = (available_reactions.len() + emojis_per_row - 1) / emojis_per_row;
|
||||
let modal_width = 50u16;
|
||||
let modal_height = (rows + 4) as u16; // +4 для заголовка, отступов и подсказки
|
||||
|
||||
// Центрируем модалку
|
||||
let x = area.x + (area.width.saturating_sub(modal_width)) / 2;
|
||||
let y = area.y + (area.height.saturating_sub(modal_height)) / 2;
|
||||
|
||||
let modal_area = Rect::new(x, y, modal_width.min(area.width), modal_height.min(area.height));
|
||||
|
||||
// Очищаем область под модалкой
|
||||
f.render_widget(Clear, modal_area);
|
||||
|
||||
// Формируем содержимое - сетка эмодзи
|
||||
let mut text_lines = vec![Line::from("")]; // Пустая строка сверху
|
||||
|
||||
for row in 0..rows {
|
||||
let mut row_spans = vec![Span::raw(" ")]; // Отступ слева
|
||||
|
||||
for col in 0..emojis_per_row {
|
||||
let idx = row * emojis_per_row + col;
|
||||
if idx >= available_reactions.len() {
|
||||
break;
|
||||
}
|
||||
|
||||
let emoji = &available_reactions[idx];
|
||||
let is_selected = idx == selected_index;
|
||||
|
||||
let style = if is_selected {
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::REVERSED)
|
||||
} else {
|
||||
Style::default().fg(Color::White)
|
||||
};
|
||||
|
||||
row_spans.push(Span::styled(format!(" {} ", emoji), style));
|
||||
row_spans.push(Span::raw(" ")); // Пробел между эмодзи
|
||||
}
|
||||
|
||||
text_lines.push(Line::from(row_spans));
|
||||
}
|
||||
|
||||
// Добавляем пустую строку и подсказку
|
||||
text_lines.push(Line::from(""));
|
||||
text_lines.push(Line::from(vec![
|
||||
Span::styled(" [←/→/↑/↓] ", Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)),
|
||||
Span::raw("Выбор "),
|
||||
Span::styled(" [Enter] ", Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)),
|
||||
Span::raw("Добавить "),
|
||||
Span::styled(" [Esc] ", Style::default().fg(Color::Red).add_modifier(Modifier::BOLD)),
|
||||
Span::raw("Отмена"),
|
||||
]));
|
||||
|
||||
let modal = Paragraph::new(text_lines)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_style(Style::default().fg(Color::Yellow))
|
||||
.title(" Выбери реакцию ")
|
||||
.title_style(Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)),
|
||||
)
|
||||
.alignment(Alignment::Left);
|
||||
|
||||
f.render_widget(modal, modal_area);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user