feat: add Selected enum

This commit is contained in:
Kristofers Solo 2024-02-22 10:54:25 +02:00
parent 429f059c33
commit eb43995718
4 changed files with 71 additions and 56 deletions

View File

@ -1,43 +1,26 @@
use std::path::Path; use std::{collections::HashSet, path::Path, vec};
use tracing::debug;
use transmission_rpc::types::{Id, Torrent, TorrentAction, TorrentStatus}; use transmission_rpc::types::{Id, Torrent, TorrentAction, TorrentStatus};
use super::Torrents; use super::{types::Selected, Torrents};
impl Torrents { impl Torrents {
pub async fn toggle(&mut self, ids: &Vec<i64>) { pub async fn toggle(&mut self, ids: Selected) {
debug!("ID list - {:?}", ids); let ids: HashSet<_> = ids.into();
let torrents = self.torrents.iter().filter(|torrent| {
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 let Some(id) = torrent.id {
if ids.contains(&id) { return ids.contains(&id);
let action = match torrent.status { }
Some(TorrentStatus::Stopped) => TorrentAction::Start, false
_ => TorrentAction::Stop, });
};
if !api_ids.is_empty() { for torrent in torrents {
if let Err(err) = self.client.torrent_action(action, api_ids.clone()).await let action = match torrent.status {
{ Some(TorrentStatus::Stopped) => TorrentAction::Start,
eprintln!("Error toggling torrent: {}", err); _ => TorrentAction::Stop,
} };
} if let Some(id) = torrent.id() {
} self.client.torrent_action(action, vec![id]).await.unwrap();
} }
} }
} }
@ -90,16 +73,9 @@ impl Torrents {
Ok(()) Ok(())
} }
pub async fn delete(&mut self, ids: &Vec<i64>, delete_local_data: bool) { pub async fn delete(&mut self, ids: Selected, 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 self.client
.torrent_remove(api_ids, delete_local_data) .torrent_remove(ids.into(), delete_local_data)
.await .await
.unwrap(); .unwrap();
} }

View File

@ -5,7 +5,9 @@ pub mod utils;
use ratatui::widgets::TableState; use ratatui::widgets::TableState;
pub mod action; pub mod action;
mod command; mod command;
pub mod types;
use self::types::Selected;
pub use self::{tab::Tab, torrent::Torrents}; pub use self::{tab::Tab, torrent::Torrents};
/// Main Application. /// Main Application.
@ -119,28 +121,29 @@ impl<'a> App<'a> {
} }
pub async fn toggle_torrents(&mut self) { pub async fn toggle_torrents(&mut self) {
let ids = &self.selected(false); let ids = self.selected(false);
self.torrents.toggle(ids).await; self.torrents.toggle(ids).await;
self.close_popup(); self.close_popup();
} }
pub async fn delete(&mut self, delete_local_data: bool) { pub async fn delete(&mut self, delete_local_data: bool) {
let ids = &self.selected(false); let ids = self.selected(false);
self.torrents.delete(ids, delete_local_data).await; self.torrents.delete(ids, delete_local_data).await;
self.close_popup(); self.close_popup();
} }
pub fn select(&mut self) { pub fn select(&mut self) {
let current_id = *self.selected(true).first().unwrap(); if let Selected::Current(current_id) = self.selected(true) {
if self.torrents.selected.contains(&current_id) { if self.torrents.selected.contains(&current_id) {
self.torrents.selected.remove(&current_id); self.torrents.selected.remove(&current_id);
} else { } else {
self.torrents.selected.insert(current_id); self.torrents.selected.insert(current_id);
}
} }
self.next(); self.next();
} }
fn selected(&self, highlighted: bool) -> Vec<i64> { fn selected(&self, highlighted: bool) -> Selected {
let torrents = &self.torrents.torrents; let torrents = &self.torrents.torrents;
if self.torrents.selected.is_empty() || highlighted { if self.torrents.selected.is_empty() || highlighted {
let torrent_id = || { let torrent_id = || {
@ -149,19 +152,19 @@ impl<'a> App<'a> {
torrent.id torrent.id
}; };
if let Some(id) = torrent_id() { if let Some(id) = torrent_id() {
return vec![id]; return Selected::Current(id);
} }
} }
let selected_torrents: Vec<_> = torrents let selected_torrents = torrents
.iter() .iter()
.filter_map(|torrent| { .filter_map(|torrent| {
let id = torrent.id; let id = torrent.id;
if self.torrents.selected.contains(&id?) { if self.torrents.selected.contains(&id?) {
return id; return id;
} }
return None; None
}) })
.collect(); .collect();
selected_torrents Selected::List(selected_torrents)
} }
} }

36
src/app/types.rs Normal file
View File

@ -0,0 +1,36 @@
use std::collections::HashSet;
use transmission_rpc::types::Id;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Selected {
Current(i64),
List(HashSet<i64>),
}
impl Into<HashSet<i64>> for Selected {
fn into(self) -> HashSet<i64> {
match self {
Selected::Current(id) => vec![id].into_iter().collect(),
Selected::List(ids) => ids,
}
}
}
impl Into<Vec<i64>> for Selected {
fn into(self) -> Vec<i64> {
match self {
Selected::Current(id) => vec![id],
Selected::List(ids) => ids.into_iter().collect(),
}
}
}
impl Into<Vec<Id>> for Selected {
fn into(self) -> Vec<Id> {
match self {
Selected::Current(id) => vec![Id::Id(id)],
Selected::List(ids) => ids.into_iter().map(Id::Id).collect(),
}
}
}

View File

@ -24,7 +24,7 @@ pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> {
return field.value(torrent.clone()).set_style(highlight_style); return field.value(torrent.clone()).set_style(highlight_style);
} }
} }
return field.value(torrent.clone()).into(); field.value(torrent.clone()).into()
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
) )