commit
This commit is contained in:
@@ -5,6 +5,7 @@ use ratatui::{
|
||||
Frame,
|
||||
};
|
||||
use crate::app::App;
|
||||
use crate::tdlib::UserOnlineStatus;
|
||||
|
||||
pub fn render(f: &mut Frame, area: Rect, app: &mut App) {
|
||||
let chat_chunks = Layout::default()
|
||||
@@ -43,7 +44,14 @@ pub fn render(f: &mut Frame, area: Rect, app: &mut App) {
|
||||
.map(|chat| {
|
||||
let is_selected = app.selected_chat_id == Some(chat.id);
|
||||
let pin_icon = if chat.is_pinned { "📌 " } else { "" };
|
||||
let prefix = if is_selected { "▌ " } else { " " };
|
||||
|
||||
// Онлайн-статус (зелёная точка для онлайн)
|
||||
let status_icon = match app.td_client.get_user_status_by_chat_id(chat.id) {
|
||||
Some(UserOnlineStatus::Online) => "● ",
|
||||
_ => " ",
|
||||
};
|
||||
|
||||
let prefix = if is_selected { "▌" } else { " " };
|
||||
|
||||
let username_text = chat.username.as_ref()
|
||||
.map(|u| format!(" {}", u))
|
||||
@@ -55,8 +63,13 @@ pub fn render(f: &mut Frame, area: Rect, app: &mut App) {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let content = format!("{}{}{}{}{}", prefix, pin_icon, chat.title, username_text, unread_badge);
|
||||
let style = Style::default().fg(Color::White);
|
||||
let content = format!("{}{}{}{}{}{}", prefix, status_icon, pin_icon, chat.title, username_text, unread_badge);
|
||||
|
||||
// Цвет зависит от онлайн-статуса
|
||||
let style = match app.td_client.get_user_status_by_chat_id(chat.id) {
|
||||
Some(UserOnlineStatus::Online) => Style::default().fg(Color::Green),
|
||||
_ => Style::default().fg(Color::White),
|
||||
};
|
||||
|
||||
ListItem::new(content).style(style)
|
||||
})
|
||||
@@ -72,9 +85,75 @@ pub fn render(f: &mut Frame, area: Rect, app: &mut App) {
|
||||
|
||||
f.render_stateful_widget(chats_list, chat_chunks[1], &mut app.chat_list_state);
|
||||
|
||||
// User status
|
||||
let status = Paragraph::new("[User: Online]")
|
||||
// User status - показываем статус выбранного чата
|
||||
let (status_text, status_color) = if let Some(chat_id) = app.selected_chat_id {
|
||||
match app.td_client.get_user_status_by_chat_id(chat_id) {
|
||||
Some(UserOnlineStatus::Online) => ("● онлайн".to_string(), Color::Green),
|
||||
Some(UserOnlineStatus::Recently) => ("был(а) недавно".to_string(), Color::Yellow),
|
||||
Some(UserOnlineStatus::Offline(was_online)) => {
|
||||
let formatted = format_was_online(*was_online);
|
||||
(formatted, Color::Gray)
|
||||
}
|
||||
Some(UserOnlineStatus::LastWeek) => ("был(а) на этой неделе".to_string(), Color::DarkGray),
|
||||
Some(UserOnlineStatus::LastMonth) => ("был(а) в этом месяце".to_string(), Color::DarkGray),
|
||||
Some(UserOnlineStatus::LongTimeAgo) => ("был(а) давно".to_string(), Color::DarkGray),
|
||||
None => ("".to_string(), Color::DarkGray), // Для групп/каналов
|
||||
}
|
||||
} else {
|
||||
// Показываем статус выделенного в списке чата
|
||||
let filtered = app.get_filtered_chats();
|
||||
if let Some(i) = app.chat_list_state.selected() {
|
||||
if let Some(chat) = filtered.get(i) {
|
||||
match app.td_client.get_user_status_by_chat_id(chat.id) {
|
||||
Some(UserOnlineStatus::Online) => ("● онлайн".to_string(), Color::Green),
|
||||
Some(UserOnlineStatus::Recently) => ("был(а) недавно".to_string(), Color::Yellow),
|
||||
Some(UserOnlineStatus::Offline(was_online)) => {
|
||||
let formatted = format_was_online(*was_online);
|
||||
(formatted, Color::Gray)
|
||||
}
|
||||
Some(UserOnlineStatus::LastWeek) => ("был(а) на этой неделе".to_string(), Color::DarkGray),
|
||||
Some(UserOnlineStatus::LastMonth) => ("был(а) в этом месяце".to_string(), Color::DarkGray),
|
||||
Some(UserOnlineStatus::LongTimeAgo) => ("был(а) давно".to_string(), Color::DarkGray),
|
||||
None => ("".to_string(), Color::DarkGray),
|
||||
}
|
||||
} else {
|
||||
("".to_string(), Color::DarkGray)
|
||||
}
|
||||
} else {
|
||||
("".to_string(), Color::DarkGray)
|
||||
}
|
||||
};
|
||||
|
||||
let status = Paragraph::new(status_text)
|
||||
.block(Block::default().borders(Borders::ALL))
|
||||
.style(Style::default().fg(Color::Green));
|
||||
.style(Style::default().fg(status_color));
|
||||
f.render_widget(status, chat_chunks[2]);
|
||||
}
|
||||
|
||||
/// Форматирование времени "был(а) в ..."
|
||||
fn format_was_online(timestamp: i32) -> String {
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
let now = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as i32;
|
||||
|
||||
let diff = now - timestamp;
|
||||
|
||||
if diff < 60 {
|
||||
"был(а) только что".to_string()
|
||||
} else if diff < 3600 {
|
||||
let mins = diff / 60;
|
||||
format!("был(а) {} мин. назад", mins)
|
||||
} else if diff < 86400 {
|
||||
let hours = diff / 3600;
|
||||
format!("был(а) {} ч. назад", hours)
|
||||
} else {
|
||||
// Показываем дату
|
||||
let datetime = chrono::DateTime::from_timestamp(timestamp as i64, 0)
|
||||
.map(|dt| dt.format("%d.%m %H:%M").to_string())
|
||||
.unwrap_or_else(|| "давно".to_string());
|
||||
format!("был(а) {}", datetime)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,19 +36,29 @@ pub fn render(f: &mut Frame, app: &mut App) {
|
||||
fn render_folders(f: &mut Frame, area: Rect, app: &App) {
|
||||
let mut spans = vec![];
|
||||
|
||||
for (i, folder) in app.folders.iter().enumerate() {
|
||||
let style = if i == app.selected_folder {
|
||||
// "All" всегда первая (клавиша 1)
|
||||
let all_style = if app.selected_folder_id.is_none() {
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
} else {
|
||||
Style::default().fg(Color::White)
|
||||
};
|
||||
spans.push(Span::styled(" 1:All ", all_style));
|
||||
|
||||
// Папки из TDLib (клавиши 2, 3, 4...)
|
||||
for (i, folder) in app.td_client.folders.iter().enumerate() {
|
||||
spans.push(Span::raw("│"));
|
||||
|
||||
let style = if app.selected_folder_id == Some(folder.id) {
|
||||
Style::default()
|
||||
.fg(Color::Cyan)
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
} else {
|
||||
Style::default().fg(Color::White)
|
||||
};
|
||||
|
||||
spans.push(Span::styled(format!(" {}:{} ", i + 1, folder), style));
|
||||
if i < app.folders.len() - 1 {
|
||||
spans.push(Span::raw("│"));
|
||||
}
|
||||
spans.push(Span::styled(format!(" {}:{} ", i + 2, folder.name), style));
|
||||
}
|
||||
|
||||
let folders_line = Line::from(spans);
|
||||
|
||||
Reference in New Issue
Block a user