From f9efd37d00addcbefed760da66c3736a15ec4194 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Fri, 1 Aug 2025 13:52:13 -0700 Subject: [PATCH] spiff the uploads widget --- src/app/mod.rs | 10 ++++++---- src/app/widgets.rs | 47 +++++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index f8d9556..f5a7c1b 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -9,7 +9,7 @@ use joecalsend::{ }; use julid::Julid; use log::{LevelFilter, debug, error, info}; -use ratatui::{DefaultTerminal, Frame}; +use ratatui::{DefaultTerminal, Frame, widgets::TableState}; use tokio::{ sync::mpsc::{UnboundedReceiver, unbounded_channel}, task::JoinSet, @@ -26,6 +26,7 @@ pub struct App { // addr -> (alias, fingerprint) pub peers: Peers, pub uploads: BTreeMap, + upload_state: TableState, // for getting messages back from the web server or web client about things we've done; the // other end is held by the state transfer_event_rx: OnceLock>, @@ -49,11 +50,12 @@ impl Default for App { impl App { pub fn new() -> Self { App { - state: Default::default(), screen: vec![CurrentScreen::Main], - peers: Default::default(), + state: Default::default(), events: Default::default(), + peers: Default::default(), uploads: Default::default(), + upload_state: Default::default(), transfer_event_rx: Default::default(), } } @@ -156,7 +158,7 @@ impl App { } } - fn draw(&self, frame: &mut Frame) { + fn draw(&mut self, frame: &mut Frame) { frame.render_widget(self, frame.area()); } diff --git a/src/app/widgets.rs b/src/app/widgets.rs index 96fe96c..fd04340 100644 --- a/src/app/widgets.rs +++ b/src/app/widgets.rs @@ -8,7 +8,7 @@ use ratatui::{ style::{Style, Stylize}, symbols::border, text::{Line, Text, ToLine}, - widgets::{Block, Borders, List, ListItem, Padding, Paragraph, Row, Table, Widget}, + widgets::{Block, Borders, List, ListItem, Padding, Paragraph, Row, Table, TableState, Widget}, }; use tui_logger::{TuiLoggerLevelOutput, TuiLoggerWidget, TuiWidgetState}; @@ -42,7 +42,7 @@ static LOGGING_MENU: LazyLock = LazyLock::new(|| { ]) }); -impl Widget for &App { +impl Widget for &mut App { fn render(self, area: Rect, buf: &mut Buffer) { let main_layout = Layout::vertical([Constraint::Min(5), Constraint::Min(10), Constraint::Min(3)]); @@ -67,7 +67,12 @@ impl Widget for &App { peers.render(footer_right.inner(footer_margin), buf); NetworkInfoWidget.render(footer_left.inner(footer_margin), buf); let ups: Vec<_> = self.uploads.values().collect(); - uploads(&ups, header_left.inner(header_margin), buf); + uploads( + &ups, + &mut self.upload_state, + header_left.inner(header_margin), + buf, + ); } CurrentScreen::Logging => { main_page(*mode, &LOGGING_MENU, area, buf); @@ -118,8 +123,12 @@ fn main_page(screen: CurrentScreen, menu: &Line, area: Rect, buf: &mut Buffer) { .render(area, buf); } -fn uploads(requests: &[&JoecalUploadRequest], area: Rect, buf: &mut Buffer) { - //let mut lines = Vec::new(); +fn uploads( + requests: &[&JoecalUploadRequest], + state: &mut TableState, + area: Rect, + buf: &mut Buffer, +) { let title = Line::from(" Upload Requests ").bold(); let block = Block::bordered() .title(title.centered()) @@ -127,20 +136,32 @@ fn uploads(requests: &[&JoecalUploadRequest], area: Rect, buf: &mut Buffer) { let mut rows = Vec::new(); for &req in requests { let src = req.alias.to_line().left_aligned(); + let mut size = 0; let files = req .files .values() - .map(|f| f.file_name.clone()) + .map(|f| { + size += f.size; + f.file_name.clone() + }) .collect::>(); let files = files.join(", "); - let files = Line::from(files); - rows.push(Row::new([src, files.centered()])); + let files = Line::from(files).centered(); + let size = Line::from(format!("{size}")).centered(); + rows.push(Row::new([src, size, files])); } - let widths = [Constraint::Max(20), Constraint::Min(50)]; - let table = Table::new(rows, widths) - .block(block) - .header(Row::new(["Sender".bold(), "Files".bold()])); - table.render(area, buf); + let widths = [ + Constraint::Max(20), + Constraint::Max(15), + Constraint::Min(50), + ]; + let table = Table::new(rows, widths).block(block).header(Row::new([ + "Sender".bold().into_left_aligned_line(), + "Bytes".bold().into_centered_line(), + "Files".bold().into_centered_line(), + ])); + + ratatui::widgets::StatefulWidget::render(table, area, buf, state); } #[derive(Debug, Clone)]