From c199325d5055284e7d68130829be650ab0163ddf Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Tue, 30 Jan 2024 18:12:04 +0200 Subject: [PATCH] feat(torrent): add torrent toggle Switch between Stopped and Running torrent states --- Cargo.lock | 13 +++++++++++++ Cargo.toml | 3 ++- src/app/mod.rs | 22 ++++++++++++++++++++++ src/app/torrent.rs | 2 +- src/handler.rs | 9 ++++++--- src/main.rs | 2 +- src/ui/mod.rs | 1 - 7 files changed, 45 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccee69e..0c71d99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -911,9 +911,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + [[package]] name = "tracing-core" version = "0.1.31" @@ -944,6 +956,7 @@ dependencies = [ "crossterm", "ratatui", "tokio", + "tracing", "transmission-rpc", "url", ] diff --git a/Cargo.toml b/Cargo.toml index f7509db..581fb68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "traxor" version = "0.1.0" authors = ["Kristofers Solo "] -license = "GPL3" +license = "GPLv3" edition = "2021" @@ -14,3 +14,4 @@ transmission-rpc = "0.4" url = "2.4" anyhow = "1.0" tokio = { version = "1", features = ["full"] } +tracing = "0.1" diff --git a/src/app/mod.rs b/src/app/mod.rs index 06b7a88..f86265f 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -3,6 +3,7 @@ mod torrent; pub mod utils; use ratatui::widgets::TableState; +use transmission_rpc::types::{Result, Torrent, TorrentAction, TorrentStatus}; pub use self::{tab::Tab, torrent::Torrents}; @@ -115,4 +116,25 @@ impl<'a> App<'a> { pub fn open_popup(&mut self) { self.show_popup = true; } + + pub async fn toggle_torrent(&mut self) -> Result<()> { + let torrent = self.selected().ok_or_else(|| "Torrent not found")?; + let id = torrent.id().ok_or_else(|| "ID not found")?; + let action = match torrent.status.ok_or_else(|| "Torrent status not found")? { + TorrentStatus::Stopped => TorrentAction::StartNow, + _ => TorrentAction::Stop, + }; + self.torrents + .client + .torrent_action(action, vec![id]) + .await?; + self.close_popup(); + Ok(()) + } + + fn selected(&self) -> Option<&Torrent> { + let idx = self.state.selected()?; + let torrent = self.torrents.torrents().get(idx)?; + Some(torrent) + } } diff --git a/src/app/torrent.rs b/src/app/torrent.rs index 86cca45..0ec0c4c 100644 --- a/src/app/torrent.rs +++ b/src/app/torrent.rs @@ -11,7 +11,7 @@ use url::Url; /// List of torrents. pub struct Torrents { /// Constructs a new instance of [`Torrents`]. - client: TransClient, + pub client: TransClient, torrents: Vec, ids: Option>, fields: Option>, diff --git a/src/handler.rs b/src/handler.rs index f5c2b20..366a209 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -3,7 +3,7 @@ use anyhow::Result; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; /// Handles the key events and updates the state of [`App`]. -pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> Result<()> { +pub async fn handle_key_events(key_event: KeyEvent, app: &mut App<'_>) -> Result<()> { match key_event.code { // Exit application on `ESC` or `q` KeyCode::Esc | KeyCode::Char('q') => { @@ -28,9 +28,12 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> Result<()> { KeyCode::Char('2') => app.switch_tab(1), KeyCode::Char('3') => app.switch_tab(2), KeyCode::Char('4') => app.switch_tab(3), - KeyCode::Char('t') => app.toggle_popup(), + KeyCode::Char('t') | KeyCode::Enter | KeyCode::Menu => { + app.toggle_popup(); + app.toggle_torrent().await.unwrap(); + } // Other handlers you could add here. - _ => {} + _ => (), } Ok(()) } diff --git a/src/main.rs b/src/main.rs index 449d9ac..8c3de76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,7 @@ async fn main() -> Result<()> { // Handle events. match tui.events.next()? { Event::Tick => app.tick().await, - Event::Key(key_event) => handle_key_events(key_event, &mut app)?, + Event::Key(key_event) => handle_key_events(key_event, &mut app).await?, Event::Mouse(_) => {} Event::Resize(_, _) => {} } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 33787f1..11cb6aa 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -26,7 +26,6 @@ pub fn render(app: &mut App, frame: &mut Frame) { .constraints([Constraint::Length(3), Constraint::Min(0)].as_ref()) .split(size); - // let titles = app.tabs.iter().map(Line::from).collect(); let titles = app .tabs() .iter()