//! 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(f: &mut Frame, area: Rect, app: &App) { // Извлекаем данные из 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 = 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]); }