use ratatui::{ layout::{Alignment, Rect}, style::{Color, Modifier, Style}, text::{Line, Span}, widgets::{Block, Borders, Clear, Paragraph}, Frame, }; /// Рендерит модалку выбора реакций (emoji picker) /// /// # Параметры /// - `f`: Frame для рендеринга /// - `area`: Область экрана /// - `available_reactions`: Список доступных эмодзи /// - `selected_index`: Индекс выбранного эмодзи pub fn render_emoji_picker( f: &mut Frame, area: Rect, available_reactions: &[String], selected_index: usize, ) { // Размеры модалки (зависят от количества реакций) let emojis_per_row = 8; let rows = available_reactions.len().div_ceil(emojis_per_row); let modal_width = 50u16; let modal_height = (rows + 4) as u16; // +4 для заголовка, отступов и подсказки // Центрируем модалку let x = area.x + (area.width.saturating_sub(modal_width)) / 2; let y = area.y + (area.height.saturating_sub(modal_height)) / 2; let modal_area = Rect::new(x, y, modal_width.min(area.width), modal_height.min(area.height)); // Очищаем область под модалкой f.render_widget(Clear, modal_area); // Формируем содержимое - сетка эмодзи let mut text_lines = vec![Line::from("")]; // Пустая строка сверху for row in 0..rows { let mut row_spans = vec![Span::raw(" ")]; // Отступ слева for col in 0..emojis_per_row { let idx = row * emojis_per_row + col; if idx >= available_reactions.len() { break; } let emoji = &available_reactions[idx]; let is_selected = idx == selected_index; let style = if is_selected { Style::default() .fg(Color::Yellow) .add_modifier(Modifier::BOLD) .add_modifier(Modifier::REVERSED) } else { Style::default().fg(Color::White) }; row_spans.push(Span::styled(format!(" {} ", emoji), style)); row_spans.push(Span::raw(" ")); // Пробел между эмодзи } text_lines.push(Line::from(row_spans)); } // Добавляем пустую строку и подсказку text_lines.push(Line::from("")); text_lines.push(Line::from(vec![ Span::styled( " [←/→/↑/↓] ", Style::default() .fg(Color::Cyan) .add_modifier(Modifier::BOLD), ), Span::raw("Выбор "), Span::styled( " [Enter] ", Style::default() .fg(Color::Green) .add_modifier(Modifier::BOLD), ), Span::raw("Добавить "), Span::styled(" [Esc] ", Style::default().fg(Color::Red).add_modifier(Modifier::BOLD)), Span::raw("Отмена"), ])); let modal = Paragraph::new(text_lines) .block( Block::default() .borders(Borders::ALL) .border_style(Style::default().fg(Color::Yellow)) .title(" Выбери реакцию ") .title_style( Style::default() .fg(Color::Yellow) .add_modifier(Modifier::BOLD), ), ) .alignment(Alignment::Center); f.render_widget(modal, modal_area); }