refactor(handler): add Action enum

This commit is contained in:
Kristofers Solo 2024-01-31 16:57:09 +02:00
parent 0171e8e135
commit 8b6a290b3e
5 changed files with 73 additions and 30 deletions

17
src/app/action.rs Normal file
View File

@ -0,0 +1,17 @@
#[derive(Debug, Clone, PartialEq)]
pub enum Action {
Quit,
NextTab,
PrevTab,
NextTorrent,
PrevTorrent,
SwitchTab(u8),
TogglePopup,
ToggleTorrent,
ToggleAll,
PauseAll,
StartAll,
Move,
Delete(bool),
Rename,
}

View File

@ -1,6 +1,5 @@
use std::path::Path; use std::path::Path;
use anyhow::Result;
use transmission_rpc::types::{Id, Torrent, TorrentAction, TorrentStatus}; use transmission_rpc::types::{Id, Torrent, TorrentAction, TorrentStatus};
use super::Torrents; use super::Torrents;

View File

@ -4,6 +4,7 @@ pub mod utils;
use ratatui::widgets::TableState; use ratatui::widgets::TableState;
use transmission_rpc::types::Torrent; use transmission_rpc::types::Torrent;
pub mod action;
mod command; mod command;
pub use self::{tab::Tab, torrent::Torrents}; pub use self::{tab::Tab, torrent::Torrents};
@ -124,6 +125,15 @@ impl<'a> App<'a> {
self.close_popup(); self.close_popup();
} }
pub async fn delete(&mut self, delete_local_data: bool) -> transmission_rpc::types::Result<()> {
let torrent = self.selected().expect("Torrent not found");
self.torrents
.delete(&torrent.clone(), delete_local_data)
.await?;
self.close_popup();
Ok(())
}
fn selected(&self) -> Option<&Torrent> { fn selected(&self) -> Option<&Torrent> {
let idx = self.state.selected()?; let idx = self.state.selected()?;
let torrent = self.torrents.torrents.get(idx)?; let torrent = self.torrents.torrents.get(idx)?;

View File

@ -1,37 +1,49 @@
use crate::app::App; use crate::app::{action::Action, App};
use anyhow::Result;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
/// Handles the key events and updates the state of [`App`]. /// Handles the key events of [`App`].
pub async fn handle_key_events(key_event: KeyEvent, app: &mut App<'_>) -> Result<()> { pub fn get_action(key_event: KeyEvent) -> Option<Action> {
match key_event.code { match key_event.code {
// Exit application on `ESC` or `q` // Exit application on `ESC` or `q`
KeyCode::Esc | KeyCode::Char('q') => app.quit(), KeyCode::Esc | KeyCode::Char('q') => Some(Action::Quit),
// Exit application on `Ctrl-C` // Exit application on `Ctrl-C`
KeyCode::Char('c') | KeyCode::Char('C') => { KeyCode::Char('c') | KeyCode::Char('C') => match key_event.modifiers {
if key_event.modifiers == KeyModifiers::CONTROL { KeyModifiers::CONTROL => Some(Action::Quit),
app.quit(); _ => None,
} },
} KeyCode::Char('l') | KeyCode::Right => Some(Action::NextTab),
KeyCode::Char('l') | KeyCode::Right => app.next_tab(), KeyCode::Char('h') | KeyCode::Left => Some(Action::PrevTab),
KeyCode::Char('h') | KeyCode::Left => app.prev_tab(), KeyCode::Char('j') | KeyCode::Down => Some(Action::NextTorrent),
KeyCode::Char('j') | KeyCode::Down => app.next(), KeyCode::Char('k') | KeyCode::Up => Some(Action::PrevTorrent),
KeyCode::Char('k') | KeyCode::Up => app.previous(), KeyCode::Char('1') => Some(Action::SwitchTab(0)),
KeyCode::Char('1') => app.switch_tab(0), KeyCode::Char('2') => Some(Action::SwitchTab(1)),
KeyCode::Char('2') => app.switch_tab(1), KeyCode::Char('3') => Some(Action::SwitchTab(2)),
KeyCode::Char('3') => app.switch_tab(2), KeyCode::Char('4') => Some(Action::SwitchTab(3)),
KeyCode::Char('4') => app.switch_tab(3), KeyCode::Char('t') | KeyCode::Enter | KeyCode::Menu => Some(Action::ToggleTorrent),
KeyCode::Char('t') | KeyCode::Enter | KeyCode::Menu => { KeyCode::Char('a') => Some(Action::ToggleAll),
app.toggle_popup();
app.toggle_torrent().await;
}
KeyCode::Char('a') => {
app.toggle_popup();
app.torrents.toggle_all().await;
}
// Other handlers you could add here. // Other handlers you could add here.
_ => (), _ => None,
}
}
/// Handles the updates of [`App`].
pub async fn update(app: &mut App<'_>, action: Action) -> transmission_rpc::types::Result<()> {
match action {
Action::Quit => app.quit(),
Action::NextTab => app.next_tab(),
Action::PrevTab => app.prev_tab(),
Action::NextTorrent => app.next(),
Action::PrevTorrent => app.previous(),
Action::SwitchTab(x) => app.switch_tab(x as usize),
Action::TogglePopup => app.toggle_popup(),
Action::ToggleTorrent => app.toggle_torrent().await,
Action::ToggleAll => app.torrents.toggle_all().await,
Action::PauseAll => app.torrents.stop_all().await,
Action::StartAll => app.torrents.start_all().await,
Action::Move => unimplemented!(),
Action::Delete(x) => app.delete(x).await?,
Action::Rename => unimplemented!(),
} }
Ok(()) Ok(())
} }

View File

@ -4,7 +4,7 @@ use ratatui::Terminal;
use std::io; use std::io;
use traxor::app::App; use traxor::app::App;
use traxor::event::{Event, EventHandler}; use traxor::event::{Event, EventHandler};
use traxor::handler::handle_key_events; use traxor::handler::{get_action, update};
use traxor::tui::Tui; use traxor::tui::Tui;
#[tokio::main] #[tokio::main]
@ -26,7 +26,12 @@ async fn main() -> Result<()> {
// Handle events. // Handle events.
match tui.events.next()? { match tui.events.next()? {
Event::Tick => app.tick().await, Event::Tick => app.tick().await,
Event::Key(key_event) => handle_key_events(key_event, &mut app).await?, // Event::Key(key_event) => handle_key_events(key_event, &mut app).await?,
Event::Key(key_event) => {
if let Some(action) = get_action(key_event) {
update(&mut app, action).await.unwrap();
}
}
Event::Mouse(_) => {} Event::Mouse(_) => {}
Event::Resize(_, _) => {} Event::Resize(_, _) => {}
} }