From b5a950d49e24f60cad60f7daac06bb8e181e5c77 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Mon, 14 Jul 2025 16:05:08 -0700 Subject: [PATCH] use a vec instead of vecdeque for screen state stack --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/frontend/mod.rs | 23 +++++++++++------------ src/frontend/ui.rs | 22 ++++++++++++++++++---- src/main.rs | 5 ++++- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13aafdc..6bded1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -375,6 +375,15 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "directories" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs" version = "6.0.0" @@ -1045,6 +1054,7 @@ dependencies = [ "axum", "chrono", "crossterm", + "directories", "figment", "futures", "julid-rs", diff --git a/Cargo.toml b/Cargo.toml index 99722f9..05f736a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" axum = { version = "0.8", features = ["macros"] } chrono = "0.4" crossterm = { version = "0.28", features = ["event-stream"] } +directories = "6.0.0" figment = { version = "0.10", features = ["toml", "test", "env"] } futures = "0.3.31" julid-rs = { version = "1", default-features = false, features = ["serde"] } diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index 646e4b7..5ae17e9 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -24,7 +24,7 @@ pub type Peers = BTreeMap; pub struct App { pub state: JoecalState, - pub screen: VecDeque, + pub screen: Vec, pub events: EventStream, // addr -> (alias, fingerprint) pub peers: Peers, @@ -42,7 +42,7 @@ impl App { pub fn new(state: JoecalState) -> Self { App { state, - screen: VecDeque::from([CurrentScreen::Main]), + screen: vec![CurrentScreen::Main], peers: Default::default(), events: Default::default(), } @@ -53,7 +53,7 @@ impl App { terminal.draw(|frame| self.draw(frame))?; self.handle_events().await?; - if let Some(&top) = self.screen.back() + if let Some(&top) = self.screen.last() && top == CurrentScreen::Stopping { self.state.stop().await; @@ -105,23 +105,22 @@ impl App { } fn exit(&mut self) { - self.screen.clear(); - self.screen.push_back(CurrentScreen::Stopping); + self.screen.push(CurrentScreen::Stopping); } fn send(&mut self) { - self.screen.clear(); - self.screen.push_back(CurrentScreen::Sending); + self.screen.push(CurrentScreen::Sending); } fn recv(&mut self) { - self.screen.clear(); - self.screen.push_back(CurrentScreen::Receiving); + self.screen.push(CurrentScreen::Receiving); } fn pop(&mut self) { - if self.screen.pop_back().is_none() { - self.screen.push_back(CurrentScreen::Main); + if self.screen.last().is_none() { + self.screen.push(CurrentScreen::Main); + } else { + self.screen.pop(); } } } @@ -146,7 +145,7 @@ impl Widget for &App { let current_screen = format!( "{:?}", - self.screen.back().cloned().unwrap_or(CurrentScreen::Main) + self.screen.last().copied().unwrap_or(CurrentScreen::Main) ); let text = Text::from(Line::from(current_screen.yellow())); diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs index 76843ef..5bf6629 100644 --- a/src/frontend/ui.rs +++ b/src/frontend/ui.rs @@ -3,10 +3,18 @@ use ratatui::{ layout::{Constraint, Direction, Layout, Rect}, style::Stylize, text::Line, - widgets::{Block, Borders, List, ListItem}, + widgets::{Block, Borders, List, ListItem, Padding}, }; -use crate::{App, frontend::Peers}; +use crate::{ + App, + frontend::{CurrentScreen, Peers}, +}; + +enum Action { + PushScreen(CurrentScreen), + PopScreen, +} impl App { pub fn draw(&self, frame: &mut Frame) { @@ -43,7 +51,10 @@ fn peers(peers: &Peers, frame: &mut Frame, area: Rect) { items.push(item); } let title = Line::from(" Peers ".bold()).centered(); - let block = Block::default().title(title).borders(Borders::all()); + let block = Block::default() + .title(title) + .borders(Borders::all()) + .padding(Padding::uniform(1)); let list = List::new(items).block(block); frame.render_widget(list, area); } @@ -68,7 +79,10 @@ fn network_info(frame: &mut Frame, area: Rect) { ListItem::new(http), ]; let title = Line::from(" Listeners ".bold()).centered(); - let block = Block::default().title(title).borders(Borders::all()); + let block = Block::default() + .title(title) + .borders(Borders::all()) + .padding(Padding::uniform(1)); let list = List::new(items).block(block); frame.render_widget(list, area); } diff --git a/src/main.rs b/src/main.rs index 67a49ac..8e6c1b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,6 +44,9 @@ async fn main() -> error::Result<()> { let result = app.run(&mut terminal).await; ratatui::restore(); + let mut alarm = tokio::time::interval(tokio::time::Duration::from_secs(5)); + alarm.tick().await; + loop { tokio::select! { handle = handles.join_next() => { @@ -55,7 +58,7 @@ async fn main() -> error::Result<()> { None => break, } } - _ = tokio::time::sleep(tokio::time::Duration::from_secs(5)) => { + _ = alarm.tick() => { println!("Exit timeout reached, aborting all unjoined tasks"); handles.abort_all(); break;