Move from tui to ratatui
Tui is no longer supported, ratatui is the new hotness. Fortunately there is very little difference between the two, except I've noticed a fun new bug in the help screen. (Maybe it's been there the whole time?)
This commit is contained in:
parent
7e047626df
commit
b381f71692
3 changed files with 423 additions and 236 deletions
617
Cargo.lock
generated
617
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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.25", features = ["event-stream"] }
|
crossterm = { version = "0.28.1", 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]
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,8 @@ use crossterm::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use log::{error, info, warn, Level, Metadata, Record};
|
use log::{error, info, warn, Level, Metadata, Record};
|
||||||
use std::collections::vec_deque::VecDeque;
|
use ratatui::{
|
||||||
use std::collections::{HashMap, HashSet};
|
backend::CrosstermBackend,
|
||||||
use std::io::stdout;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use tokio::sync::oneshot;
|
|
||||||
use tokio_stream::StreamExt;
|
|
||||||
use tui::{
|
|
||||||
backend::{Backend, CrosstermBackend},
|
|
||||||
layout::{Constraint, Direction, Layout, Margin, Rect},
|
layout::{Constraint, Direction, Layout, Margin, Rect},
|
||||||
style::{Color, Modifier, Style},
|
style::{Color, Modifier, Style},
|
||||||
widgets::{
|
widgets::{
|
||||||
|
|
@ -30,6 +23,13 @@ use tui::{
|
||||||
},
|
},
|
||||||
Frame, Terminal,
|
Frame, Terminal,
|
||||||
};
|
};
|
||||||
|
use std::collections::vec_deque::VecDeque;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::io::stdout;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
pub enum UIEvent {
|
pub enum UIEvent {
|
||||||
Connected(u16),
|
Connected(u16),
|
||||||
|
|
@ -301,7 +301,7 @@ impl UI {
|
||||||
Ok(code)
|
Ok(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_connected<T: Backend>(&mut self, frame: &mut Frame<T>) {
|
fn render_connected(&mut self, frame: &mut Frame) {
|
||||||
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.size());
|
.split(frame.area());
|
||||||
|
|
||||||
self.render_ports(frame, chunks[0]);
|
self.render_ports(frame, chunks[0]);
|
||||||
if self.show_logs {
|
if self.show_logs {
|
||||||
|
|
@ -322,7 +322,7 @@ impl UI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_ports<B: Backend>(&mut self, frame: &mut Frame<B>, size: Rect) {
|
fn render_ports(&mut self, frame: &mut Frame, size: Rect) {
|
||||||
let enabled_port_style = Style::default();
|
let enabled_port_style = Style::default();
|
||||||
let disabled_port_style = Style::default().fg(Color::DarkGray);
|
let disabled_port_style = Style::default().fg(Color::DarkGray);
|
||||||
let broken_port_style =
|
let broken_port_style =
|
||||||
|
|
@ -358,17 +358,16 @@ impl UI {
|
||||||
Constraint::Length(size.width),
|
Constraint::Length(size.width),
|
||||||
];
|
];
|
||||||
|
|
||||||
let port_list = Table::new(rows)
|
let port_list = Table::new(rows, &widths)
|
||||||
.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<B: Backend>(&mut self, frame: &mut Frame<B>) {
|
fn render_help(&mut self, frame: &mut Frame) {
|
||||||
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"]),
|
||||||
|
|
@ -387,10 +386,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.size(),
|
frame.area(),
|
||||||
);
|
);
|
||||||
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);
|
||||||
|
|
||||||
|
|
@ -398,8 +397,7 @@ impl UI {
|
||||||
Constraint::Length(key_width),
|
Constraint::Length(key_width),
|
||||||
Constraint::Length(binding_width),
|
Constraint::Length(binding_width),
|
||||||
];
|
];
|
||||||
let keybindings = Table::new(keybindings)
|
let keybindings = Table::new(keybindings, keybindings_widths)
|
||||||
.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));
|
||||||
|
|
||||||
|
|
@ -407,7 +405,7 @@ impl UI {
|
||||||
frame.render_widget(keybindings, inner_area);
|
frame.render_widget(keybindings, inner_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_logs<B: Backend>(&mut self, frame: &mut Frame<B>, size: Rect) {
|
fn render_logs(&mut self, frame: &mut Frame, 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();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue