joecalsend/src/ui.rs
2025-07-08 16:31:00 -07:00

95 lines
3 KiB
Rust

use ratatui::{
Frame,
layout::{Constraint, Direction, Layout, Rect},
style::Stylize,
text::Line,
widgets::{Block, Borders, List, ListItem},
};
use crate::App;
// helper function to create a centered rect using up certain percentage of the
// available rect `r`
fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
// Cut the given rectangle into three vertical pieces
let popup_layout = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Percentage((100 - percent_y) / 2),
Constraint::Percentage(percent_y),
Constraint::Percentage((100 - percent_y) / 2),
])
.split(r);
// Then cut the middle vertical piece into three width-wise pieces
Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Percentage((100 - percent_x) / 2),
Constraint::Percentage(percent_x),
Constraint::Percentage((100 - percent_x) / 2),
])
.split(popup_layout[1])[1] // Return the middle chunk
}
impl App {
pub fn draw(&self, frame: &mut Frame) {
let [top, middle, bottom] = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Min(3), Constraint::Min(3), Constraint::Min(3)])
.split(frame.area())
.as_array()
.cloned()
.unwrap();
let [footer_left, footer_right] = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(bottom)
.as_array()
.cloned()
.unwrap();
frame.render_widget(self, frame.area());
network_info(frame, footer_left);
peers(&self.peers, frame, footer_right);
}
}
fn peers(peers: &crate::Peers, frame: &mut Frame, area: Rect) {
let mut items = Vec::with_capacity(peers.len());
for (k, v) in peers.iter() {
let item = format!("{:?}: {} ({})", k, v.0, v.1);
let s = Line::from(item.yellow());
let item = ListItem::new(s);
items.push(item);
}
let block = Block::default().title("Peers").borders(Borders::all());
let list = List::new(items).block(block);
frame.render_widget(list, area);
}
fn network_info(frame: &mut Frame, area: Rect) {
let udp: Line = format!("UDP socket: {:?}", joecalsend::LISTENING_SOCKET_ADDR)
.yellow()
.into();
let multicast: Line = format!(
"Multicast address: {:?}:{}",
joecalsend::MULTICAST_IP,
joecalsend::DEFAULT_PORT
)
.yellow()
.into();
let http: Line = format!("HTTP address: {:?}", joecalsend::LISTENING_SOCKET_ADDR)
.yellow()
.into();
let items = [
ListItem::new(udp),
ListItem::new(multicast),
ListItem::new(http),
];
let block = Block::default().title("Listeners").borders(Borders::all());
let list = List::new(items).block(block);
frame.render_widget(list, area);
}