use a vec instead of vecdeque for screen state stack

This commit is contained in:
Joe Ardent 2025-07-14 16:05:08 -07:00
parent 90312a4332
commit b5a950d49e
5 changed files with 44 additions and 17 deletions

10
Cargo.lock generated
View file

@ -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",

View file

@ -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"] }

View file

@ -24,7 +24,7 @@ pub type Peers = BTreeMap<SocketAddr, (String, String)>;
pub struct App {
pub state: JoecalState,
pub screen: VecDeque<CurrentScreen>,
pub screen: Vec<CurrentScreen>,
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()));

View file

@ -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);
}

View file

@ -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;