Compare commits

..

No commits in common. "4fe255e7d26757a7c2c96c61d068c76a2a678e8b" and "7e047626dfb47fdef6dea6e3f937cf895b110853" have entirely different histories.

3 changed files with 240 additions and 428 deletions

617
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -17,18 +17,18 @@ bench = false
anyhow = "1.0" anyhow = "1.0"
bytes = "1" bytes = "1"
copypasta = "0.10.1" copypasta = "0.10.1"
crossterm = { version = "0.28.1", features = ["event-stream"] } crossterm = { version = "0.25", features = ["event-stream"] }
env_logger = { version = "0.11.5", default-features = false } env_logger = { version = "0.11.5", default-features = false }
home = "0.5.4" home = "0.5.4"
indoc = "1" indoc = "1"
log = { version = "0.4", features = ["std"] } log = { version = "0.4", features = ["std"] }
open = "3" open = "3"
rand = "0.8.5" rand = "0.8.5"
ratatui = "0.28.0"
thiserror = "1.0" thiserror = "1.0"
tokio = { version = "1", features = ["io-std", "io-util", "macros", "net", "process", "rt", "rt-multi-thread", "fs"] } tokio = { version = "1", features = ["io-std", "io-util", "macros", "net", "process", "rt", "rt-multi-thread", "fs"] }
tokio-stream = "0.1" tokio-stream = "0.1"
toml = "0.5" toml = "0.5"
tui = "0.19"
xdg = "2" xdg = "2"
[dev-dependencies] [dev-dependencies]

View file

@ -14,15 +14,6 @@ use crossterm::{
}, },
}; };
use log::{error, info, warn, Level, Metadata, Record}; use log::{error, info, warn, Level, Metadata, Record};
use ratatui::{
backend::CrosstermBackend,
layout::{Constraint, Direction, Layout, Margin, Rect},
style::{Color, Modifier, Style},
widgets::{
Block, Borders, List, ListItem, ListState, Row, Table, TableState,
},
Frame, Terminal,
};
use std::collections::vec_deque::VecDeque; use std::collections::vec_deque::VecDeque;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::io::stdout; use std::io::stdout;
@ -30,6 +21,15 @@ use std::sync::{Arc, Mutex};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tokio_stream::StreamExt; use tokio_stream::StreamExt;
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Constraint, Direction, Layout, Margin, Rect},
style::{Color, Modifier, Style},
widgets::{
Block, Borders, List, ListItem, ListState, Row, Table, TableState,
},
Frame, Terminal,
};
pub enum UIEvent { pub enum UIEvent {
Connected(u16), Connected(u16),
@ -301,7 +301,7 @@ impl UI {
Ok(code) Ok(code)
} }
fn render_connected(&mut self, frame: &mut Frame) { fn render_connected<T: Backend>(&mut self, frame: &mut Frame<T>) {
let constraints = if self.show_logs { let constraints = if self.show_logs {
vec![Constraint::Percentage(50), Constraint::Percentage(50)] vec![Constraint::Percentage(50), Constraint::Percentage(50)]
} else { } else {
@ -311,7 +311,7 @@ impl UI {
let chunks = Layout::default() let chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints(constraints) .constraints(constraints)
.split(frame.area()); .split(frame.size());
self.render_ports(frame, chunks[0]); self.render_ports(frame, chunks[0]);
if self.show_logs { if self.show_logs {
@ -322,11 +322,11 @@ impl UI {
} }
} }
fn render_ports(&mut self, frame: &mut Frame, size: Rect) { fn render_ports<B: Backend>(&mut self, frame: &mut Frame<B>, size: Rect) {
let enabled_port_style = Style::reset(); let enabled_port_style = Style::default();
let disabled_port_style = Style::reset().fg(Color::DarkGray); let disabled_port_style = Style::default().fg(Color::DarkGray);
let broken_port_style = let broken_port_style =
Style::reset().fg(Color::Red).add_modifier(Modifier::DIM); Style::default().fg(Color::Red).add_modifier(Modifier::DIM);
let mut rows = Vec::new(); let mut rows = Vec::new();
let ports = self.get_ui_ports(); let ports = self.get_ui_ports();
@ -358,16 +358,17 @@ impl UI {
Constraint::Length(size.width), Constraint::Length(size.width),
]; ];
let port_list = Table::new(rows, &widths) let port_list = Table::new(rows)
.header(Row::new(vec!["fwd", "Port", "Description"])) .header(Row::new(vec!["fwd", "Port", "Description"]))
.block(Block::default().title("Ports").borders(Borders::ALL)) .block(Block::default().title("Ports").borders(Borders::ALL))
.column_spacing(1) .column_spacing(1)
.widths(&widths)
.highlight_symbol(">> "); .highlight_symbol(">> ");
frame.render_stateful_widget(port_list, size, &mut self.selection); frame.render_stateful_widget(port_list, size, &mut self.selection);
} }
fn render_help(&mut self, frame: &mut Frame) { fn render_help<B: Backend>(&mut self, frame: &mut Frame<B>) {
let keybindings = vec![ let keybindings = vec![
Row::new(vec!["↑ / k", "Move cursor up"]), Row::new(vec!["↑ / k", "Move cursor up"]),
Row::new(vec!["↓ / j", "Move cursor down"]), Row::new(vec!["↓ / j", "Move cursor down"]),
@ -386,10 +387,10 @@ impl UI {
let help_popup_area = centered_rect( let help_popup_area = centered_rect(
65, 65,
keybindings.len() as u16 + border_lines, keybindings.len() as u16 + border_lines,
frame.area(), frame.size(),
); );
let inner_area = let inner_area =
help_popup_area.inner(Margin { vertical: 1, horizontal: 1 }); help_popup_area.inner(&Margin { vertical: 1, horizontal: 1 });
let key_width = 7; let key_width = 7;
let binding_width = inner_area.width.saturating_sub(key_width); let binding_width = inner_area.width.saturating_sub(key_width);
@ -397,16 +398,16 @@ impl UI {
Constraint::Length(key_width), Constraint::Length(key_width),
Constraint::Length(binding_width), Constraint::Length(binding_width),
]; ];
let keybindings = Table::new(keybindings, keybindings_widths) let keybindings = Table::new(keybindings)
.widths(keybindings_widths)
.column_spacing(1) .column_spacing(1)
.block(Block::default().title("Keys").borders(Borders::ALL)) .block(Block::default().title("Keys").borders(Borders::ALL));
.style(Style::reset());
// keybindings // keybindings
frame.render_widget(keybindings, inner_area); frame.render_widget(keybindings, inner_area);
} }
fn render_logs(&mut self, frame: &mut Frame, size: Rect) { fn render_logs<B: Backend>(&mut self, frame: &mut Frame<B>, size: Rect) {
let items: Vec<_> = let items: Vec<_> =
self.lines.iter().map(|l| ListItem::new(&l[..])).collect(); self.lines.iter().map(|l| ListItem::new(&l[..])).collect();