Files
telegram-tui/src/ui/messages.rs
Mikhail Kilin b6d9291864 fixes
2026-01-20 01:00:12 +03:00

117 lines
3.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, Paragraph},
Frame,
};
use crate::app::App;
use crate::utils::format_timestamp;
pub fn render(f: &mut Frame, area: Rect, app: &App) {
if let Some(chat) = app.get_selected_chat() {
let message_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(3), // Chat header
Constraint::Min(0), // Messages
Constraint::Length(3), // Input box
])
.split(area);
// Chat header
let header = Paragraph::new(format!("👤 {}", chat.title))
.block(Block::default().borders(Borders::ALL))
.style(
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
);
f.render_widget(header, message_chunks[0]);
// Messages
let mut lines: Vec<Line> = Vec::new();
for msg in &app.current_messages {
let sender_style = if msg.is_outgoing {
Style::default()
.fg(Color::Green)
.add_modifier(Modifier::BOLD)
} else {
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD)
};
let sender_name = if msg.is_outgoing {
"You".to_string()
} else {
msg.sender_name.clone()
};
let read_mark = if msg.is_outgoing {
if msg.is_read { " ✓✓" } else { "" }
} else {
""
};
// Форматируем время
let time = format_timestamp(msg.date);
lines.push(Line::from(vec![
Span::styled(format!("{} ", sender_name), sender_style),
Span::raw("── "),
Span::styled(format!("{}{}", time, read_mark), Style::default().fg(Color::DarkGray)),
]));
lines.push(Line::from(msg.content.clone()));
lines.push(Line::from(""));
}
if lines.is_empty() {
lines.push(Line::from(Span::styled(
"Нет сообщений",
Style::default().fg(Color::DarkGray),
)));
}
// Вычисляем скролл с учётом пользовательского offset
let visible_height = message_chunks[1].height.saturating_sub(2) as usize;
let total_lines = lines.len();
let base_scroll = if total_lines > visible_height {
total_lines - visible_height
} else {
0
};
let scroll_offset = base_scroll.saturating_sub(app.message_scroll_offset) as u16;
let messages_widget = Paragraph::new(lines)
.block(Block::default().borders(Borders::ALL))
.scroll((scroll_offset, 0));
f.render_widget(messages_widget, message_chunks[1]);
// Input box
let input_text = if app.message_input.is_empty() {
"> Введите сообщение...".to_string()
} else {
format!("> {}", app.message_input)
};
let input_style = if app.message_input.is_empty() {
Style::default().fg(Color::DarkGray)
} else {
Style::default().fg(Color::Yellow)
};
let input = Paragraph::new(input_text)
.block(Block::default().borders(Borders::ALL))
.style(input_style);
f.render_widget(input, message_chunks[2]);
} else {
let empty = Paragraph::new("Выберите чат")
.block(Block::default().borders(Borders::ALL))
.style(Style::default().fg(Color::DarkGray))
.alignment(Alignment::Center);
f.render_widget(empty, area);
}
}