From 59f86c31e5a8159b739c27dd32b9d5e7ac3129cf Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Thu, 1 Jan 2026 04:35:50 +0200 Subject: [PATCH] feat: improve help page layout and organization --- src/ui/help.rs | 123 ++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 63 deletions(-) diff --git a/src/ui/help.rs b/src/ui/help.rs index 63ce411..52cd8ea 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -4,79 +4,76 @@ use ratatui::{ widgets::{Block, BorderType, Borders, Cell, Clear, Row, Table}, }; -use super::to_color; - pub fn render_help(frame: &mut Frame, app: &App) { - let block = Block::default() - .title("Help") - .title_alignment(Alignment::Center) - .borders(Borders::ALL) - .border_type(BorderType::Rounded); - - let keybinds = app.config.keybinds.clone(); + let kb = &app.config.keybinds; + let key_style = Style::default().fg(Color::Yellow).bold(); + let select_key = display_key(&kb.select); let rows = vec![ - Row::new(vec![ - Cell::from(keybinds.toggle_help), - Cell::from("Show help"), - ]), - Row::new(vec![Cell::from(keybinds.quit), Cell::from("Quit")]), - Row::new(vec![Cell::from(keybinds.prev_tab), Cell::from("Left")]), - Row::new(vec![Cell::from(keybinds.next_tab), Cell::from("Right")]), - Row::new(vec![Cell::from(keybinds.next_torrent), Cell::from("Down")]), - Row::new(vec![Cell::from(keybinds.prev_torrent), Cell::from("Up")]), - Row::new(vec![ - Cell::from(keybinds.switch_tab_1), - Cell::from("Switch to All tab"), - ]), - Row::new(vec![ - Cell::from(keybinds.switch_tab_2), - Cell::from("Switch to Active tab"), - ]), - Row::new(vec![ - Cell::from(keybinds.switch_tab_3), - Cell::from("Switch to Downloading tab"), - ]), - Row::new(vec![ - Cell::from(keybinds.toggle_torrent), - Cell::from("Toggle torrent"), - ]), - Row::new(vec![ - Cell::from(keybinds.toggle_all), - Cell::from("Toggle all torrents"), - ]), - Row::new(vec![ - Cell::from(keybinds.delete), - Cell::from("Delete torrent"), - ]), - Row::new(vec![ - Cell::from(keybinds.delete_force), - Cell::from("Delete torrent and data"), - ]), - Row::new(vec![ - Cell::from(keybinds.select), - Cell::from("Select torrent"), - ]), + section_row("── Navigation ──"), + key_row(&kb.prev_torrent, "Move up", key_style), + key_row(&kb.next_torrent, "Move down", key_style), + key_row(&kb.prev_tab, "Previous tab", key_style), + key_row(&kb.next_tab, "Next tab", key_style), + key_row(&kb.switch_tab_1, "All torrents", key_style), + key_row(&kb.switch_tab_2, "Active torrents", key_style), + key_row(&kb.switch_tab_3, "Downloading", key_style), + Row::default(), + section_row("── Actions ──"), + key_row(&kb.toggle_torrent, "Start/stop torrent", key_style), + key_row(&kb.toggle_all, "Start/stop all", key_style), + key_row(&select_key, "Multi-select", key_style), + key_row(&kb.move_torrent, "Move torrent", key_style), + key_row(&kb.rename_torrent, "Rename torrent", key_style), + key_row(&kb.delete, "Remove torrent", key_style), + key_row(&kb.delete_force, "Delete with data", key_style), + Row::default(), + section_row("── General ──"), + key_row(&kb.toggle_help, "Toggle help", key_style), + key_row(&kb.quit, "Quit", key_style), ]; - let table = Table::new( - rows, - &[Constraint::Percentage(20), Constraint::Percentage(80)], - ) - .block(block) - .style(Style::default().fg(to_color(&app.config.colors.info_foreground))); + #[allow(clippy::cast_possible_truncation)] + let height = rows.len() as u16 + 4; + let width = 40; + + let block = Block::default() + .title(" Keybindings ") + .title_alignment(Alignment::Center) + .borders(Borders::ALL) + .border_type(BorderType::Rounded) + .border_style(Style::default().fg(Color::Cyan)); + + let table = Table::new(rows, [Constraint::Length(16), Constraint::Fill(1)]).block(block); let area = frame.area(); - let height = 15; // Desired height for the help menu - let width = area.width; // Full width of the screen - let popup_area = Rect::new( - area.x + (area.width - width) / 2, // Center horizontally - area.y + area.height - height, // Position at the very bottom - width, - height, + (area.width.saturating_sub(width)) / 2, + (area.height.saturating_sub(height)) / 2, + width.min(area.width), + height.min(area.height), ); frame.render_widget(Clear, popup_area); frame.render_widget(table, popup_area); } + +fn key_row<'a>(key: &'a str, desc: &'a str, key_style: Style) -> Row<'a> { + Row::new(vec![ + Cell::from(format!(" {key}")).style(key_style), + Cell::from(desc), + ]) +} + +fn section_row(title: &str) -> Row<'_> { + Row::new(vec![ + Cell::from(title).style(Style::default().fg(Color::DarkGray)), + ]) +} + +fn display_key(key: &str) -> String { + match key { + " " => "Space".to_string(), + k => k.to_string(), + } +}