97 lines
3.0 KiB
Rust
97 lines
3.0 KiB
Rust
//! Pinned messages viewer modal
|
|
|
|
use crate::app::App;
|
|
use crate::tdlib::TdClientTrait;
|
|
use crate::ui::components::{calculate_scroll_offset, render_help_bar, render_message_item};
|
|
use ratatui::{
|
|
layout::{Constraint, Direction, Layout, Rect},
|
|
style::{Color, Modifier, Style},
|
|
text::{Line, Span},
|
|
widgets::{Block, Borders, Paragraph},
|
|
Frame,
|
|
};
|
|
|
|
/// Renders pinned messages mode
|
|
pub fn render<T: TdClientTrait>(f: &mut Frame, area: Rect, app: &App<T>) {
|
|
// Извлекаем данные из ChatState
|
|
let (messages, selected_index) =
|
|
if let crate::app::ChatState::PinnedMessages { messages, selected_index } = &app.chat_state
|
|
{
|
|
(messages.as_slice(), *selected_index)
|
|
} else {
|
|
return; // Некорректное состояние
|
|
};
|
|
|
|
let chunks = Layout::default()
|
|
.direction(Direction::Vertical)
|
|
.constraints([
|
|
Constraint::Length(3), // Header
|
|
Constraint::Min(0), // Pinned messages list
|
|
Constraint::Length(3), // Help bar
|
|
])
|
|
.split(area);
|
|
|
|
// Header
|
|
let total = messages.len();
|
|
let current = selected_index + 1;
|
|
let header_text = format!("📌 ЗАКРЕПЛЁННЫЕ ({}/{})", current, total);
|
|
let header = Paragraph::new(header_text)
|
|
.block(
|
|
Block::default()
|
|
.borders(Borders::ALL)
|
|
.border_style(Style::default().fg(Color::Magenta)),
|
|
)
|
|
.style(
|
|
Style::default()
|
|
.fg(Color::Magenta)
|
|
.add_modifier(Modifier::BOLD),
|
|
);
|
|
f.render_widget(header, chunks[0]);
|
|
|
|
// Pinned messages list
|
|
let content_width = chunks[1].width.saturating_sub(2) as usize;
|
|
let mut lines: Vec<Line> = Vec::new();
|
|
|
|
for (idx, msg) in messages.iter().enumerate() {
|
|
if idx > 0 {
|
|
lines.push(Line::from(""));
|
|
}
|
|
lines.extend(render_message_item(
|
|
msg,
|
|
idx == selected_index,
|
|
content_width,
|
|
3,
|
|
));
|
|
}
|
|
|
|
if lines.is_empty() {
|
|
lines.push(Line::from(Span::styled(
|
|
"Нет закреплённых сообщений",
|
|
Style::default().fg(Color::Gray),
|
|
)));
|
|
}
|
|
|
|
// Скролл к выбранному сообщению
|
|
let scroll_offset = calculate_scroll_offset(selected_index, 5, chunks[1].height);
|
|
|
|
let messages_widget = Paragraph::new(lines)
|
|
.block(
|
|
Block::default()
|
|
.borders(Borders::ALL)
|
|
.border_style(Style::default().fg(Color::Magenta)),
|
|
)
|
|
.scroll((scroll_offset, 0));
|
|
f.render_widget(messages_widget, chunks[1]);
|
|
|
|
// Help bar
|
|
let help = render_help_bar(
|
|
&[
|
|
("↑↓", "навигация", Color::Yellow),
|
|
("Enter", "перейти", Color::Green),
|
|
("Esc", "выход", Color::Red),
|
|
],
|
|
Color::Magenta,
|
|
);
|
|
f.render_widget(help, chunks[2]);
|
|
}
|