feat(torrent): add torrent toggle

Switch between Stopped and Running torrent states
This commit is contained in:
Kristofers Solo 2024-01-30 18:12:04 +02:00
parent 917251d655
commit c199325d50
7 changed files with 45 additions and 7 deletions

13
Cargo.lock generated
View File

@ -911,9 +911,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"pin-project-lite", "pin-project-lite",
"tracing-attributes",
"tracing-core", "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]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.31" version = "0.1.31"
@ -944,6 +956,7 @@ dependencies = [
"crossterm", "crossterm",
"ratatui", "ratatui",
"tokio", "tokio",
"tracing",
"transmission-rpc", "transmission-rpc",
"url", "url",
] ]

View File

@ -2,7 +2,7 @@
name = "traxor" name = "traxor"
version = "0.1.0" version = "0.1.0"
authors = ["Kristofers Solo <dev@kristofers.xyz>"] authors = ["Kristofers Solo <dev@kristofers.xyz>"]
license = "GPL3" license = "GPLv3"
edition = "2021" edition = "2021"
@ -14,3 +14,4 @@ transmission-rpc = "0.4"
url = "2.4" url = "2.4"
anyhow = "1.0" anyhow = "1.0"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
tracing = "0.1"

View File

@ -3,6 +3,7 @@ mod torrent;
pub mod utils; pub mod utils;
use ratatui::widgets::TableState; use ratatui::widgets::TableState;
use transmission_rpc::types::{Result, Torrent, TorrentAction, TorrentStatus};
pub use self::{tab::Tab, torrent::Torrents}; pub use self::{tab::Tab, torrent::Torrents};
@ -115,4 +116,25 @@ impl<'a> App<'a> {
pub fn open_popup(&mut self) { pub fn open_popup(&mut self) {
self.show_popup = true; 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)
}
} }

View File

@ -11,7 +11,7 @@ use url::Url;
/// List of torrents. /// List of torrents.
pub struct Torrents { pub struct Torrents {
/// Constructs a new instance of [`Torrents`]. /// Constructs a new instance of [`Torrents`].
client: TransClient, pub client: TransClient,
torrents: Vec<Torrent>, torrents: Vec<Torrent>,
ids: Option<Vec<Id>>, ids: Option<Vec<Id>>,
fields: Option<Vec<TorrentGetField>>, fields: Option<Vec<TorrentGetField>>,

View File

@ -3,7 +3,7 @@ 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 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 { match key_event.code {
// Exit application on `ESC` or `q` // Exit application on `ESC` or `q`
KeyCode::Esc | KeyCode::Char('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('2') => app.switch_tab(1),
KeyCode::Char('3') => app.switch_tab(2), KeyCode::Char('3') => app.switch_tab(2),
KeyCode::Char('4') => app.switch_tab(3), 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. // Other handlers you could add here.
_ => {} _ => (),
} }
Ok(()) Ok(())
} }

View File

@ -26,7 +26,7 @@ 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)?, Event::Key(key_event) => handle_key_events(key_event, &mut app).await?,
Event::Mouse(_) => {} Event::Mouse(_) => {}
Event::Resize(_, _) => {} Event::Resize(_, _) => {}
} }

View File

@ -26,7 +26,6 @@ pub fn render(app: &mut App, frame: &mut Frame) {
.constraints([Constraint::Length(3), Constraint::Min(0)].as_ref()) .constraints([Constraint::Length(3), Constraint::Min(0)].as_ref())
.split(size); .split(size);
// let titles = app.tabs.iter().map(Line::from).collect();
let titles = app let titles = app
.tabs() .tabs()
.iter() .iter()