feat: add multiple torrent select option

This commit is contained in:
Kristofers Solo 2024-02-21 16:43:09 +02:00
parent 2a3975963c
commit b0a8d64880
6 changed files with 38 additions and 10 deletions

View File

@ -14,4 +14,5 @@ pub enum Action {
Move,
Delete(bool),
Rename,
Select,
}

View File

@ -134,6 +134,18 @@ impl<'a> App<'a> {
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);
}
}
self.next();
}
fn selected(&self) -> Option<&Torrent> {
let idx = self.state.selected()?;
let torrent = self.torrents.torrents.get(idx)?;

View File

@ -1,8 +1,8 @@
use std::fmt::Debug;
use std::{collections::HashSet, fmt::Debug};
use anyhow::Result;
use transmission_rpc::{
types::{Id, Torrent, TorrentGetField},
types::{Torrent, TorrentGetField},
TransClient,
};
@ -13,7 +13,7 @@ pub struct Torrents {
/// Constructs a new instance of [`Torrents`].
pub client: TransClient,
pub torrents: Vec<Torrent>,
pub ids: Option<Vec<Id>>,
pub selected: HashSet<i64>, // Torrent::id
pub fields: Option<Vec<TorrentGetField>>,
}
@ -24,7 +24,7 @@ impl Torrents {
Self {
client: TransClient::new(url),
torrents: Vec::new(),
ids: None,
selected: HashSet::new(),
fields: None,
}
}
@ -50,7 +50,7 @@ impl Torrents {
pub async fn update(&mut self) -> &mut Self {
self.torrents = self
.client
.torrent_get(self.fields.clone(), self.ids.clone())
.torrent_get(self.fields.clone(), None)
.await
.unwrap()
.arguments

View File

@ -63,6 +63,7 @@ impl Wrapper for TorrentGetField {
TorrentGetField::UploadedEver => String::from("Uploaded"),
TorrentGetField::Wanted => String::from("Wanted"),
TorrentGetField::WebseedsSendingToUs => String::from("Webseeds Sending to Us"),
TorrentGetField::FileCount => unimplemented!(),
}
}
@ -170,6 +171,7 @@ impl Wrapper for TorrentGetField {
None => String::from("N/A"),
},
TorrentGetField::WebseedsSendingToUs => String::from("N/A"),
TorrentGetField::FileCount => unimplemented!(),
}
}
@ -215,6 +217,7 @@ impl Wrapper for TorrentGetField {
TorrentGetField::UploadedEver => 10,
TorrentGetField::Wanted => 10,
TorrentGetField::WebseedsSendingToUs => 10,
TorrentGetField::FileCount => unimplemented!(),
}
}
}

View File

@ -19,9 +19,9 @@ pub fn get_action(key_event: KeyEvent) -> Option<Action> {
KeyCode::Char('1') => Some(Action::SwitchTab(0)),
KeyCode::Char('2') => Some(Action::SwitchTab(1)),
KeyCode::Char('3') => Some(Action::SwitchTab(2)),
KeyCode::Char('4') => Some(Action::SwitchTab(3)),
KeyCode::Char('t') | KeyCode::Enter | KeyCode::Menu => Some(Action::ToggleTorrent),
KeyCode::Char('a') => Some(Action::ToggleAll),
KeyCode::Char(' ') => Some(Action::Select),
// Other handlers you could add here.
_ => None,
}
@ -44,6 +44,7 @@ pub async fn update(app: &mut App<'_>, action: Action) -> transmission_rpc::type
Action::Move => unimplemented!(),
Action::Delete(x) => app.delete(x).await?,
Action::Rename => unimplemented!(),
Action::Select => app.select(),
}
Ok(())
}

View File

@ -1,6 +1,6 @@
use ratatui::{
layout::Constraint,
style::{Color, Style},
style::{Color, Style, Styled},
widgets::{Block, BorderType, Borders, Row, Table},
};
@ -8,7 +8,9 @@ use crate::app::{utils::Wrapper, App, Tab};
pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> {
let fields = tab.fields();
let selected = &app.torrents.selected.clone();
let torrents = &app.torrents.set_fields(None).torrents;
let highlight_style = Style::default().bg(Color::Magenta).fg(Color::Black);
let rows: Vec<Row<'_>> = torrents
.iter()
@ -16,7 +18,14 @@ pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> {
Row::new(
fields
.iter()
.map(|&field| field.value(torrent.clone()))
.map(|&field| {
if let Some(id) = &torrent.clone().id {
if selected.contains(id) {
return field.value(torrent.clone()).set_style(highlight_style);
}
}
return field.value(torrent.clone()).into();
})
.collect::<Vec<_>>(),
)
})
@ -34,6 +43,9 @@ pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> {
.collect::<Vec<_>>(),
)
.style(Style::default().fg(Color::Yellow));
let highlight_style = Style::default().bg(Color::Blue).fg(Color::Black);
Table::new(rows, widths)
.block(
Block::default()
@ -41,7 +53,6 @@ pub fn render_table<'a>(app: &mut App, tab: Tab) -> Table<'a> {
.border_type(BorderType::Rounded),
)
.header(header)
.highlight_style(Style::default().fg(Color::Red))
.highlight_symbol(">> ")
.highlight_style(highlight_style)
.column_spacing(1)
}