diff --git a/src/app/command.rs b/src/app/command.rs index 4022258..9d7c44d 100644 --- a/src/app/command.rs +++ b/src/app/command.rs @@ -1,20 +1,45 @@ use std::path::Path; +use tracing::debug; use transmission_rpc::types::{Id, Torrent, TorrentAction, TorrentStatus}; use super::Torrents; impl Torrents { - pub async fn toggle(&mut self, torrent: &Torrent) { - let id = torrent.id().expect("ID not found"); - let action = match torrent.status { - Some(TorrentStatus::Stopped) => TorrentAction::StartNow, - _ => TorrentAction::Stop, - }; - self.client - .torrent_action(action, vec![id]) - .await - .expect("Error toggling torrent"); + pub async fn toggle(&mut self, ids: &Vec) { + debug!("ID list - {:?}", ids); + + let api_ids: Vec<_> = self + .torrents + .iter() + .filter_map(|torrent| { + if let Some(id) = torrent.id { + if ids.contains(&id) { + return torrent.id(); + } + } + return None; + }) + .collect(); + + debug!("API ID list - {:?}", api_ids); + + for torrent in &self.torrents { + if let Some(id) = torrent.id { + if ids.contains(&id) { + let action = match torrent.status { + Some(TorrentStatus::Stopped) => TorrentAction::Start, + _ => TorrentAction::Stop, + }; + if !api_ids.is_empty() { + if let Err(err) = self.client.torrent_action(action, api_ids.clone()).await + { + eprintln!("Error toggling torrent: {}", err); + } + } + } + } + } } pub async fn toggle_all(&mut self) { @@ -65,16 +90,18 @@ impl Torrents { Ok(()) } - pub async fn delete( - &mut self, - torrent: &Torrent, - delete_local_data: bool, - ) -> transmission_rpc::types::Result<()> { - let id = torrent.id().expect("ID not found"); + pub async fn delete(&mut self, ids: &Vec, delete_local_data: bool) { + let api_ids = self + .torrents + .iter() + .filter(|torrent| ids.contains(&torrent.id.unwrap())) + .map(|torrent| torrent.id().unwrap()) + .collect(); + self.client - .torrent_remove(vec![id], delete_local_data) - .await?; - Ok(()) + .torrent_remove(api_ids, delete_local_data) + .await + .unwrap(); } pub async fn rename( diff --git a/src/app/mod.rs b/src/app/mod.rs index c3b2d0f..27065b7 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -3,7 +3,6 @@ mod torrent; pub mod utils; use ratatui::widgets::TableState; -use transmission_rpc::types::Torrent; pub mod action; mod command; @@ -119,36 +118,50 @@ impl<'a> App<'a> { self.show_popup = true; } - pub async fn toggle_torrent(&mut self) { - let torrent = self.selected().expect("Torrent not found"); - self.torrents.toggle(&torrent.clone()).await; + pub async fn toggle_torrents(&mut self) { + let ids = &self.selected(false); + self.torrents.toggle(ids).await; 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?; + pub async fn delete(&mut self, delete_local_data: bool) { + let ids = &self.selected(false); + self.torrents.delete(ids, delete_local_data).await; self.close_popup(); - Ok(()) } pub fn select(&mut self) { - let torrent = self.selected().expect("Torrent not found"); - if let Some(id) = torrent.id { - if self.torrents.selected.contains(&id) { - self.torrents.selected.remove(&id); - } else { - self.torrents.selected.insert(id); - } + let current_id = *self.selected(true).first().unwrap(); + if self.torrents.selected.contains(¤t_id) { + self.torrents.selected.remove(¤t_id); + } else { + self.torrents.selected.insert(current_id); } self.next(); } - fn selected(&self) -> Option<&Torrent> { - let idx = self.state.selected()?; - let torrent = self.torrents.torrents.get(idx)?; - Some(torrent) + fn selected(&self, highlighted: bool) -> Vec { + let torrents = &self.torrents.torrents; + if self.torrents.selected.is_empty() || highlighted { + let torrent_id = || { + let idx = self.state.selected()?; + let torrent = torrents.get(idx)?; + torrent.id + }; + if let Some(id) = torrent_id() { + return vec![id]; + } + } + let selected_torrents: Vec<_> = torrents + .iter() + .filter_map(|torrent| { + let id = torrent.id; + if self.torrents.selected.contains(&id?) { + return id; + } + return None; + }) + .collect(); + selected_torrents } } diff --git a/src/handler.rs b/src/handler.rs index cc3ee00..4b707ee 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -37,12 +37,12 @@ pub async fn update(app: &mut App<'_>, action: Action) -> transmission_rpc::type 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::ToggleTorrent => app.toggle_torrents().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::Delete(x) => app.delete(x).await, Action::Rename => unimplemented!(), Action::Select => app.select(), }