This commit is contained in:
Mikhail Kilin
2026-01-21 02:27:08 +03:00
parent 9912ac11bd
commit 32ab1df1fa
8 changed files with 291 additions and 79 deletions

View File

@@ -6,7 +6,7 @@ use ratatui::{
Frame,
};
use crate::app::App;
use crate::utils::format_timestamp;
use crate::utils::{format_timestamp, format_date, get_day};
pub fn render(f: &mut Frame, area: Rect, app: &App) {
if let Some(chat) = app.get_selected_chat() {
@@ -20,7 +20,11 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
.split(area);
// Chat header
let header = Paragraph::new(format!("👤 {}", chat.title))
let header_text = match &chat.username {
Some(username) => format!("👤 {} {}", chat.title, username),
None => format!("👤 {}", chat.title),
};
let header = Paragraph::new(header_text)
.block(Block::default().borders(Borders::ALL))
.style(
Style::default()
@@ -29,42 +33,82 @@ pub fn render(f: &mut Frame, area: Rect, app: &App) {
);
f.render_widget(header, message_chunks[0]);
// Messages
// Messages с группировкой по дате и отправителю
let mut lines: Vec<Line> = Vec::new();
let mut last_day: Option<i64> = None;
let mut last_sender: Option<(bool, String)> = None; // (is_outgoing, sender_name)
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 msg_day = get_day(msg.date);
if last_day != Some(msg_day) {
if last_day.is_some() {
lines.push(Line::from("")); // Пустая строка перед разделителем
}
// Добавляем разделитель даты
let date_str = format_date(msg.date);
lines.push(Line::from(vec![
Span::styled(
format!("──────── {} ────────", date_str),
Style::default().fg(Color::DarkGray),
),
]));
lines.push(Line::from(""));
last_day = Some(msg_day);
last_sender = None; // Сбрасываем отправителя при смене дня
}
let sender_name = if msg.is_outgoing {
"You".to_string()
"Вы".to_string()
} else {
msg.sender_name.clone()
};
let current_sender = (msg.is_outgoing, sender_name.clone());
// Проверяем, нужно ли показать заголовок отправителя
let show_sender_header = last_sender.as_ref() != Some(&current_sender);
if show_sender_header {
// Пустая строка между группами сообщений (кроме первой)
if last_sender.is_some() {
lines.push(Line::from(""));
}
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)
};
// Заголовок отправителя
lines.push(Line::from(vec![
Span::styled(format!("{} ", sender_name), sender_style),
Span::styled("────────────────", Style::default().fg(Color::DarkGray)),
]));
last_sender = Some(current_sender);
}
// Форматируем время (HH:MM)
let time = format_timestamp(msg.date);
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)),
Span::styled(format!(" [{}]", time), Style::default().fg(Color::DarkGray)),
Span::raw(format!(" {}", msg.content)),
Span::styled(read_mark.to_string(), Style::default().fg(Color::DarkGray)),
]));
lines.push(Line::from(msg.content.clone()));
lines.push(Line::from(""));
}
if lines.is_empty() {