PicoBot/src/client/tui/components/command_menu.rs
2026-07-14 14:31:16 +08:00

54 lines
1.6 KiB
Rust

use crate::client::tui::app::App;
use ratatui::{
Frame,
layout::Rect,
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, List, ListItem, ListState},
};
pub fn render(f: &mut Frame, area: Rect, app: &App) {
let filtered = app.get_filtered_commands();
if filtered.is_empty() {
return;
}
let items: Vec<ListItem> = filtered
.iter()
.enumerate()
.map(|(i, cmd)| {
let is_selected = i == app.selected_command_idx;
let style = if is_selected {
Style::default()
.fg(Color::White)
.bg(Color::Blue)
.add_modifier(Modifier::BOLD)
} else {
Style::default().fg(Color::White)
};
// Show first alias as the command
let alias = cmd.aliases.first().map(|a| a.as_str()).unwrap_or(&cmd.name);
ListItem::new(Line::from(vec![
Span::styled(alias, style),
Span::styled(" - ", Style::default().fg(Color::Gray)),
Span::styled(&cmd.description, style),
]))
})
.collect();
let list = List::new(items)
.block(
Block::default()
.title("Commands")
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Cyan)),
)
.highlight_style(Style::default().add_modifier(Modifier::BOLD));
let mut state = ListState::default().with_selected(Some(app.selected_command_idx));
f.render_stateful_widget(list, area, &mut state);
}