fixes
This commit is contained in:
@@ -144,7 +144,7 @@ fn styles_equal(a: &CharStyle, b: &CharStyle) -> bool {
|
||||
}
|
||||
|
||||
/// Рендерит текст инпута с блочным курсором
|
||||
fn render_input_with_cursor<'a>(prefix: &'a str, text: &str, cursor_pos: usize, color: Color) -> Line<'a> {
|
||||
fn render_input_with_cursor(prefix: &str, text: &str, cursor_pos: usize, color: Color) -> Line<'static> {
|
||||
let chars: Vec<char> = text.chars().collect();
|
||||
let mut spans: Vec<Span> = vec![Span::raw(prefix.to_string())];
|
||||
|
||||
@@ -435,6 +435,48 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
let selection_marker = if is_selected { "▶ " } else { "" };
|
||||
let marker_len = selection_marker.chars().count();
|
||||
|
||||
// Отображаем forward если есть
|
||||
if let Some(forward) = &msg.forward_from {
|
||||
let forward_line = format!("↪ Переслано от {}", forward.sender_name);
|
||||
let forward_len = forward_line.chars().count();
|
||||
|
||||
if msg.is_outgoing {
|
||||
// Forward справа для исходящих
|
||||
let padding = content_width.saturating_sub(forward_len + 1);
|
||||
lines.push(Line::from(vec![
|
||||
Span::raw(" ".repeat(padding)),
|
||||
Span::styled(forward_line, Style::default().fg(Color::Magenta)),
|
||||
]));
|
||||
} else {
|
||||
// Forward слева для входящих
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(forward_line, Style::default().fg(Color::Magenta)),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
// Отображаем reply если есть
|
||||
if let Some(reply) = &msg.reply_to {
|
||||
let reply_text: String = reply.text.chars().take(40).collect();
|
||||
let ellipsis = if reply.text.chars().count() > 40 { "..." } else { "" };
|
||||
let reply_line = format!("┌ {}: {}{}", reply.sender_name, reply_text, ellipsis);
|
||||
let reply_len = reply_line.chars().count();
|
||||
|
||||
if msg.is_outgoing {
|
||||
// Reply справа для исходящих
|
||||
let padding = content_width.saturating_sub(reply_len + 1);
|
||||
lines.push(Line::from(vec![
|
||||
Span::raw(" ".repeat(padding)),
|
||||
Span::styled(reply_line, Style::default().fg(Color::Cyan)),
|
||||
]));
|
||||
} else {
|
||||
// Reply слева для входящих
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(reply_line, Style::default().fg(Color::Cyan)),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
if msg.is_outgoing {
|
||||
// Исходящие: справа, формат "текст (HH:MM ✎ ✓✓)"
|
||||
let read_mark = if msg.is_read { "✓✓" } else { "✓" };
|
||||
@@ -562,17 +604,29 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
f.render_widget(messages_widget, message_chunks[1]);
|
||||
|
||||
// Input box с wrap для длинного текста и блочным курсором
|
||||
let (input_line, input_title) = if app.is_selecting_message() {
|
||||
let (input_line, input_title) = if app.is_forwarding() {
|
||||
// Режим пересылки - показываем превью сообщения
|
||||
let forward_preview = app.get_forwarding_message()
|
||||
.map(|m| {
|
||||
let text_preview: String = m.content.chars().take(40).collect();
|
||||
let ellipsis = if m.content.chars().count() > 40 { "..." } else { "" };
|
||||
format!("↪ {}{}", text_preview, ellipsis)
|
||||
})
|
||||
.unwrap_or_else(|| "↪ ...".to_string());
|
||||
|
||||
let line = Line::from(Span::styled(forward_preview, Style::default().fg(Color::Cyan)));
|
||||
(line, " Выберите чат ← ")
|
||||
} else if app.is_selecting_message() {
|
||||
// Режим выбора сообщения - подсказка зависит от возможностей
|
||||
let selected_msg = app.get_selected_message();
|
||||
let can_edit = selected_msg.map(|m| m.can_be_edited && m.is_outgoing).unwrap_or(false);
|
||||
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 редакт. · d удалить · Esc отмена",
|
||||
(true, false) => "↑↓ выбрать · Enter редакт. · Esc отмена",
|
||||
(false, true) => "↑↓ выбрать · d удалить · Esc отмена",
|
||||
(false, false) => "↑↓ выбрать · Esc отмена",
|
||||
(true, true) => "↑↓ · Enter ред. · r ответ · f перслть · d удал. · Esc",
|
||||
(true, false) => "↑↓ · Enter ред. · r ответ · f переслть · Esc",
|
||||
(false, true) => "↑↓ · r ответ · f переслать · d удалить · Esc",
|
||||
(false, false) => "↑↓ · r ответить · f переслать · Esc",
|
||||
};
|
||||
(Line::from(Span::styled(hint, Style::default().fg(Color::Cyan))), " Выбор сообщения ")
|
||||
} else if app.is_editing() {
|
||||
@@ -590,6 +644,31 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
let line = render_input_with_cursor("✏ ", &app.message_input, app.cursor_position, Color::Magenta);
|
||||
(line, " Редактирование (Esc отмена) ")
|
||||
}
|
||||
} else if app.is_replying() {
|
||||
// Режим ответа на сообщение
|
||||
let reply_preview = app.get_replying_to_message()
|
||||
.map(|m| {
|
||||
let sender = if m.is_outgoing { "Вы" } else { &m.sender_name };
|
||||
let text_preview: String = m.content.chars().take(30).collect();
|
||||
let ellipsis = if m.content.chars().count() > 30 { "..." } else { "" };
|
||||
format!("{}: {}{}", sender, text_preview, ellipsis)
|
||||
})
|
||||
.unwrap_or_else(|| "...".to_string());
|
||||
|
||||
if app.message_input.is_empty() {
|
||||
let line = Line::from(vec![
|
||||
Span::styled("↪ ", Style::default().fg(Color::Cyan)),
|
||||
Span::styled(reply_preview, Style::default().fg(Color::Gray)),
|
||||
Span::raw(" "),
|
||||
Span::styled("█", Style::default().fg(Color::Yellow)),
|
||||
]);
|
||||
(line, " Ответ (Esc отмена) ")
|
||||
} else {
|
||||
let short_preview: String = reply_preview.chars().take(15).collect();
|
||||
let prefix = format!("↪ {} > ", short_preview);
|
||||
let line = render_input_with_cursor(&prefix, &app.message_input, app.cursor_position, Color::Yellow);
|
||||
(line, " Ответ (Esc отмена) ")
|
||||
}
|
||||
} else {
|
||||
// Обычный режим
|
||||
if app.message_input.is_empty() {
|
||||
@@ -610,10 +689,15 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
|
||||
let input_block = if input_title.is_empty() {
|
||||
Block::default().borders(Borders::ALL)
|
||||
} else {
|
||||
let title_color = if app.is_replying() || app.is_forwarding() {
|
||||
Color::Cyan
|
||||
} else {
|
||||
Color::Magenta
|
||||
};
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.title(input_title)
|
||||
.title_style(Style::default().fg(Color::Magenta).add_modifier(Modifier::BOLD))
|
||||
.title_style(Style::default().fg(title_color).add_modifier(Modifier::BOLD))
|
||||
};
|
||||
|
||||
let input = Paragraph::new(input_line)
|
||||
|
||||
Reference in New Issue
Block a user