Add TUI download pause and queued delete
This commit is contained in:
@@ -2,8 +2,8 @@ use crate::models::DownloadEntry;
|
||||
use crate::ui::{
|
||||
COLOR_PRIMARY, HIGHLIGHT_SYMBOL, border_style, border_type, error_style,
|
||||
format_bytes_progress, format_progress_bar, format_shortcuts_styled,
|
||||
format_speed, header_style, highlight_style, inactive_style, primary_style,
|
||||
warning_style,
|
||||
format_speed, header_style, highlight_style, inactive_style, info_style,
|
||||
primary_style, warning_style,
|
||||
};
|
||||
use color_eyre::Result;
|
||||
use ratatui::{
|
||||
@@ -229,6 +229,7 @@ impl MultiDownloadProgress {
|
||||
let status_icon = match download.status {
|
||||
DownloadStatus::Queued => "⋯",
|
||||
DownloadStatus::InProgress { .. } => "⧗",
|
||||
DownloadStatus::Paused { .. } => "⏸",
|
||||
DownloadStatus::Completed => "✓",
|
||||
DownloadStatus::Failed => "✗",
|
||||
DownloadStatus::TimedOut => "⏱",
|
||||
@@ -269,6 +270,7 @@ impl MultiDownloadProgress {
|
||||
let style = match download.status {
|
||||
DownloadStatus::Queued => inactive_style(),
|
||||
DownloadStatus::InProgress { .. } => warning_style(),
|
||||
DownloadStatus::Paused { .. } => info_style(),
|
||||
DownloadStatus::Completed => primary_style(),
|
||||
DownloadStatus::Failed | DownloadStatus::TimedOut => {
|
||||
error_style()
|
||||
@@ -352,6 +354,10 @@ pub fn render_download_stats(
|
||||
.iter()
|
||||
.filter(|d| matches!(d.download.status, DownloadStatus::Queued))
|
||||
.count();
|
||||
let paused = downloads
|
||||
.iter()
|
||||
.filter(|d| matches!(d.download.status, DownloadStatus::Paused { .. }))
|
||||
.count();
|
||||
|
||||
let total_downloaded: u64 = downloads
|
||||
.iter()
|
||||
@@ -430,6 +436,14 @@ pub fn render_download_stats(
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" queued"),
|
||||
Span::raw(", "),
|
||||
Span::styled(
|
||||
paused.to_string(),
|
||||
Style::default()
|
||||
.fg(COLOR_PRIMARY)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" paused"),
|
||||
]);
|
||||
|
||||
let stats_paragraph = Paragraph::new(stats_line);
|
||||
|
||||
@@ -238,6 +238,8 @@ impl MainTui {
|
||||
vec![
|
||||
("1-3", "focus pane"),
|
||||
("↑↓", "navigate"),
|
||||
("p", "pause/resume"),
|
||||
("d", "delete queued"),
|
||||
("q", "quit"),
|
||||
]
|
||||
}
|
||||
@@ -617,11 +619,73 @@ impl MainTui {
|
||||
self.state.downloads_table_state.select(Some(new));
|
||||
}
|
||||
}
|
||||
KeyCode::Char('p') => {
|
||||
self.toggle_selected_download_pause();
|
||||
}
|
||||
KeyCode::Char('d') => {
|
||||
self.remove_selected_queued_download();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn toggle_selected_download_pause(&mut self) {
|
||||
let Some(index) = self.state.downloads_table_state.selected() else {
|
||||
return;
|
||||
};
|
||||
let Some(download_entry) = self.state.downloads.get(index) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let download = &download_entry.download;
|
||||
match download.status {
|
||||
DownloadStatus::InProgress { .. } => {
|
||||
self.client
|
||||
.pause_download(&download.username, &download.filename);
|
||||
}
|
||||
DownloadStatus::Paused { .. } => {
|
||||
self.client
|
||||
.resume_download(&download.username, &download.filename);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_selected_queued_download(&mut self) {
|
||||
let Some(index) = self.state.downloads_table_state.selected() else {
|
||||
return;
|
||||
};
|
||||
let Some(download_entry) = self.state.downloads.get(index) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let download = &download_entry.download;
|
||||
if !matches!(download.status, DownloadStatus::Queued) {
|
||||
return;
|
||||
}
|
||||
|
||||
if !self
|
||||
.client
|
||||
.remove_queued_download(&download.username, &download.filename)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.state.downloads.remove(index);
|
||||
self.select_download_after_removal(index);
|
||||
}
|
||||
|
||||
fn select_download_after_removal(&mut self, removed_index: usize) {
|
||||
if self.state.downloads.is_empty() {
|
||||
self.state.downloads_table_state.select(None);
|
||||
return;
|
||||
}
|
||||
|
||||
let next_index = removed_index.min(self.state.downloads.len() - 1);
|
||||
self.state.downloads_table_state.select(Some(next_index));
|
||||
}
|
||||
|
||||
fn handle_mouse_event(&mut self, mouse: MouseEvent) -> Result<()> {
|
||||
if let MouseEventKind::Down(MouseButton::Left) = mouse.kind {
|
||||
let (col, row) = (mouse.column, mouse.row);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::models::DownloadEntry;
|
||||
use crate::ui::{
|
||||
HIGHLIGHT_SYMBOL, border_style, border_type, error_style, format_bytes,
|
||||
format_speed, header_style, highlight_style, inactive_style, success_style,
|
||||
warning_style,
|
||||
format_speed, header_style, highlight_style, inactive_style, info_style,
|
||||
success_style, warning_style,
|
||||
};
|
||||
use ratatui::{
|
||||
Frame,
|
||||
@@ -52,6 +52,7 @@ pub fn render_downloads_pane(
|
||||
let (status_icon, status_style) = match &download.status {
|
||||
DownloadStatus::Queued => ("⋯", inactive_style()),
|
||||
DownloadStatus::InProgress { .. } => ("⧗", warning_style()),
|
||||
DownloadStatus::Paused { .. } => ("⏸", info_style()),
|
||||
DownloadStatus::Completed => ("✓", success_style()),
|
||||
DownloadStatus::Failed => ("✗", error_style()),
|
||||
DownloadStatus::TimedOut => ("⏱", error_style()),
|
||||
@@ -74,6 +75,21 @@ pub fn render_downloads_pane(
|
||||
percent
|
||||
)
|
||||
}
|
||||
DownloadStatus::Paused { .. } => {
|
||||
let percent = if download.size > 0 {
|
||||
(download.bytes_downloaded() as f64
|
||||
/ download.size as f64
|
||||
* 100.0) as u8
|
||||
} else {
|
||||
0
|
||||
};
|
||||
format!(
|
||||
"Paused {}/{} ({}%)",
|
||||
format_bytes(download.bytes_downloaded()),
|
||||
format_bytes(download.size),
|
||||
percent
|
||||
)
|
||||
}
|
||||
DownloadStatus::Completed => "Completed".to_string(),
|
||||
DownloadStatus::Failed => "Failed".to_string(),
|
||||
DownloadStatus::TimedOut => "Timed out".to_string(),
|
||||
|
||||
@@ -139,6 +139,7 @@ pub fn status_color(status: &str) -> Color {
|
||||
match status {
|
||||
"queued" => COLOR_INACTIVE,
|
||||
"in_progress" => COLOR_WARNING,
|
||||
"paused" => COLOR_INFO,
|
||||
"completed" => COLOR_PRIMARY,
|
||||
"failed" | "timed_out" => COLOR_ERROR,
|
||||
_ => Color::default(),
|
||||
|
||||
Reference in New Issue
Block a user