mirror of
https://github.com/kristoferssolo/traxor.git
synced 2025-10-21 20:10:35 +00:00
feat(help): add help popup
This commit is contained in:
parent
cad0ac00e2
commit
98ad8efd3a
@ -6,7 +6,7 @@ pub enum Action {
|
||||
NextTorrent,
|
||||
PrevTorrent,
|
||||
SwitchTab(u8),
|
||||
TogglePopup,
|
||||
ToggleHelp, // Add this line
|
||||
ToggleTorrent,
|
||||
ToggleAll,
|
||||
PauseAll,
|
||||
|
||||
@ -17,7 +17,7 @@ pub struct App<'a> {
|
||||
tabs: &'a [Tab],
|
||||
pub state: TableState,
|
||||
pub torrents: Torrents,
|
||||
pub show_popup: bool,
|
||||
pub show_help: bool,
|
||||
}
|
||||
|
||||
impl<'a> App<'a> {
|
||||
@ -30,7 +30,7 @@ impl<'a> App<'a> {
|
||||
index: 0,
|
||||
state: TableState::default(),
|
||||
torrents: Torrents::new()?, // Handle the Result here
|
||||
show_popup: false,
|
||||
show_help: false,
|
||||
})
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ impl<'a> App<'a> {
|
||||
}
|
||||
None => 0,
|
||||
};
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
self.state.select(Some(i));
|
||||
}
|
||||
|
||||
@ -71,19 +71,19 @@ impl<'a> App<'a> {
|
||||
}
|
||||
None => 0,
|
||||
};
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
self.state.select(Some(i));
|
||||
}
|
||||
|
||||
/// Switches to the next tab.
|
||||
pub fn next_tab(&mut self) {
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
self.index = (self.index + 1) % self.tabs.len();
|
||||
}
|
||||
|
||||
/// Switches to the previous tab.
|
||||
pub fn prev_tab(&mut self) {
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
if self.index > 0 {
|
||||
self.index -= 1;
|
||||
} else {
|
||||
@ -93,7 +93,7 @@ impl<'a> App<'a> {
|
||||
|
||||
/// Switches to the tab whose index is `idx`.
|
||||
pub fn switch_tab(&mut self, idx: usize) {
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
self.index = idx
|
||||
}
|
||||
|
||||
@ -107,29 +107,29 @@ impl<'a> App<'a> {
|
||||
self.tabs
|
||||
}
|
||||
|
||||
pub fn toggle_popup(&mut self) {
|
||||
self.show_popup = !self.show_popup;
|
||||
pub fn toggle_help(&mut self) {
|
||||
self.show_help = !self.show_help;
|
||||
}
|
||||
|
||||
pub fn close_popup(&mut self) {
|
||||
self.show_popup = false;
|
||||
pub fn close_help(&mut self) {
|
||||
self.show_help = false;
|
||||
}
|
||||
|
||||
pub fn open_popup(&mut self) {
|
||||
self.show_popup = true;
|
||||
pub fn open_help(&mut self) {
|
||||
self.show_help = true;
|
||||
}
|
||||
|
||||
pub async fn toggle_torrents(&mut self) -> anyhow::Result<()> {
|
||||
let ids = self.selected(false);
|
||||
self.torrents.toggle(ids).await?;
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete(&mut self, delete_local_data: bool) -> anyhow::Result<()> {
|
||||
let ids = self.selected(false);
|
||||
self.torrents.delete(ids, delete_local_data).await?;
|
||||
self.close_popup();
|
||||
self.close_help();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ pub fn get_action(key_event: KeyEvent) -> Option<Action> {
|
||||
KeyCode::Char('d') => Some(Action::Delete(false)),
|
||||
KeyCode::Char('D') => Some(Action::Delete(true)),
|
||||
KeyCode::Char(' ') => Some(Action::Select),
|
||||
// Other handlers you could add here.
|
||||
KeyCode::Char('?') => Some(Action::ToggleHelp),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,7 @@ pub async fn update(app: &mut App<'_>, action: Action) -> anyhow::Result<()> {
|
||||
Action::NextTorrent => app.next(),
|
||||
Action::PrevTorrent => app.previous(),
|
||||
Action::SwitchTab(x) => app.switch_tab(x as usize),
|
||||
Action::TogglePopup => app.toggle_popup(),
|
||||
Action::ToggleHelp => app.toggle_help(),
|
||||
Action::ToggleTorrent => app.toggle_torrents().await?,
|
||||
Action::ToggleAll => app.torrents.toggle_all().await?,
|
||||
Action::PauseAll => app.torrents.stop_all().await?,
|
||||
|
||||
@ -12,7 +12,3 @@ pub mod tui;
|
||||
|
||||
/// Event handler.
|
||||
pub mod handler;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
51
src/ui/help.rs
Normal file
51
src/ui/help.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use ratatui::{prelude::*, widgets::*};
|
||||
|
||||
pub fn render_help(frame: &mut Frame) {
|
||||
let block = Block::default()
|
||||
.title("Help")
|
||||
.title_alignment(Alignment::Center)
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded);
|
||||
|
||||
let rows = vec![
|
||||
Row::new(vec![Cell::from("?"), Cell::from("Show help")]),
|
||||
Row::new(vec![Cell::from("q"), Cell::from("Quit")]),
|
||||
Row::new(vec![Cell::from("h"), Cell::from("Left")]),
|
||||
Row::new(vec![Cell::from("l"), Cell::from("Right")]),
|
||||
Row::new(vec![Cell::from("j"), Cell::from("Down")]),
|
||||
Row::new(vec![Cell::from("k"), Cell::from("Up")]),
|
||||
Row::new(vec![Cell::from("1"), Cell::from("Switch to All tab")]),
|
||||
Row::new(vec![Cell::from("2"), Cell::from("Switch to Active tab")]),
|
||||
Row::new(vec![
|
||||
Cell::from("3"),
|
||||
Cell::from("Switch to Downloading tab"),
|
||||
]),
|
||||
Row::new(vec![Cell::from("t"), Cell::from("Toggle torrent")]),
|
||||
Row::new(vec![Cell::from("a"), Cell::from("Toggle all torrents")]),
|
||||
Row::new(vec![Cell::from("d"), Cell::from("Delete torrent")]),
|
||||
Row::new(vec![Cell::from("D"), Cell::from("Delete torrent and data")]),
|
||||
Row::new(vec![Cell::from(" "), Cell::from("Select torrent")]),
|
||||
];
|
||||
|
||||
let table = Table::new(
|
||||
rows,
|
||||
&[Constraint::Percentage(20), Constraint::Percentage(80)],
|
||||
)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::Green));
|
||||
|
||||
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,
|
||||
);
|
||||
|
||||
frame.render_widget(Clear, popup_area);
|
||||
frame.render_widget(table, popup_area);
|
||||
}
|
||||
|
||||
@ -1,16 +1,9 @@
|
||||
mod popup;
|
||||
mod help;
|
||||
mod table;
|
||||
|
||||
use crate::app::{App, Tab};
|
||||
use popup::render_popup;
|
||||
use ratatui::{
|
||||
layout::Alignment,
|
||||
prelude::{Constraint, Direction, Layout},
|
||||
style::{Color, Style},
|
||||
text::Line,
|
||||
widgets::{Block, BorderType, Borders, Clear, Tabs},
|
||||
Frame,
|
||||
};
|
||||
use help::render_help;
|
||||
use ratatui::{prelude::*, widgets::*};
|
||||
use table::render_table;
|
||||
|
||||
/// Renders the user interface widgets.
|
||||
@ -57,10 +50,7 @@ pub fn render(app: &mut App, frame: &mut Frame) {
|
||||
};
|
||||
frame.render_stateful_widget(table, chunks[1], &mut app.state); // renders table
|
||||
|
||||
if app.show_popup {
|
||||
let block = Block::default().borders(Borders::ALL);
|
||||
let size = render_popup(size);
|
||||
frame.render_widget(Clear, size);
|
||||
frame.render_widget(block, size);
|
||||
if app.show_help {
|
||||
render_help(frame);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
use ratatui::layout::Rect;
|
||||
|
||||
pub fn render_popup(r: Rect) -> Rect {
|
||||
let vertical_margin = r.height / 5;
|
||||
let horizontal_margin = r.width / 5;
|
||||
|
||||
Rect::new(
|
||||
r.x + horizontal_margin,
|
||||
r.y + vertical_margin,
|
||||
r.width - (2 * horizontal_margin),
|
||||
r.height - (2 * vertical_margin),
|
||||
)
|
||||
}
|
||||
@ -1,11 +1,10 @@
|
||||
use crate::app::{utils::Wrapper, App, Tab};
|
||||
use ratatui::{
|
||||
layout::Constraint,
|
||||
style::{Color, Style, Styled},
|
||||
widgets::{Block, BorderType, Borders, Row, Table},
|
||||
};
|
||||
|
||||
use crate::app::{utils::Wrapper, App, Tab};
|
||||
|
||||
pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> {
|
||||
let fields = tab.fields();
|
||||
let selected = &app.torrents.selected.clone();
|
||||
|
||||
20
tests/app.rs
20
tests/app.rs
@ -48,19 +48,19 @@ fn test_app_switch_tab() {
|
||||
#[test]
|
||||
fn test_app_toggle_popup() {
|
||||
let mut app = App::new().unwrap();
|
||||
assert!(!app.show_popup);
|
||||
app.toggle_popup();
|
||||
assert!(app.show_popup);
|
||||
app.toggle_popup();
|
||||
assert!(!app.show_popup);
|
||||
assert!(!app.show_help);
|
||||
app.toggle_help();
|
||||
assert!(app.show_help);
|
||||
app.toggle_help();
|
||||
assert!(!app.show_help);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_app_open_close_popup() {
|
||||
let mut app = App::new().unwrap();
|
||||
assert!(!app.show_popup);
|
||||
app.open_popup();
|
||||
assert!(app.show_popup);
|
||||
app.close_popup();
|
||||
assert!(!app.show_popup);
|
||||
assert!(!app.show_help);
|
||||
app.open_help();
|
||||
assert!(app.show_help);
|
||||
app.close_help();
|
||||
assert!(!app.show_help);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user