diff --git a/Cargo.lock b/Cargo.lock index 7c82756..13aafdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -302,6 +302,7 @@ checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags", "crossterm_winapi", + "futures-core", "mio", "parking_lot", "rustix 0.38.44", @@ -519,6 +520,21 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8866fac38f53fc87fa3ae1b09ddd723e0482f8fa74323518b4c59df2c55a00a" +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -526,6 +542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -534,6 +551,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -552,10 +597,16 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -993,7 +1044,9 @@ version = "0.1.0" dependencies = [ "axum", "chrono", + "crossterm", "figment", + "futures", "julid-rs", "local-ip-address", "mime", diff --git a/Cargo.toml b/Cargo.toml index 046adde..99722f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,9 @@ edition = "2024" [dependencies] axum = { version = "0.8", features = ["macros"] } chrono = "0.4" +crossterm = { version = "0.28", features = ["event-stream"] } figment = { version = "0.10", features = ["toml", "test", "env"] } +futures = "0.3.31" julid-rs = { version = "1", default-features = false, features = ["serde"] } local-ip-address = "0.6" mime = "0.3" diff --git a/src/main.rs b/src/main.rs index 1506002..b8b993b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,14 @@ #![feature(slice_as_array)] use std::{collections::BTreeMap, io, net::SocketAddr}; +use futures::{FutureExt, StreamExt}; use joecalsend::{Config, JoecalState, error, models::Device}; use local_ip_address::local_ip; use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig, V4IfAddr}; use ratatui::{ DefaultTerminal, buffer::Buffer, - crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}, + crossterm::event::{Event, EventStream, KeyCode, KeyEvent, KeyEventKind}, layout::Rect, style::Stylize, symbols::border, @@ -71,6 +72,7 @@ pub struct App { screen: CurrentScreen, // addr -> (alias, fingerprint) peers: Peers, + events: EventStream, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -87,6 +89,7 @@ impl App { state, screen: CurrentScreen::Main, peers: Default::default(), + events: Default::default(), } } @@ -96,6 +99,7 @@ impl App { self.handle_events().await?; if self.screen == CurrentScreen::Stopping { + self.state.stop().await; break; } @@ -113,37 +117,44 @@ impl App { } async fn handle_events(&mut self) -> io::Result<()> { - match event::read()? { - // it's important to check that the event is a key press event as - // crossterm also emits key release and repeat events on Windows. - Event::Key(key_event) if key_event.kind == KeyEventKind::Press => { - self.handle_key_event(key_event).await + tokio::select! { + event = self.events.next().fuse() => { + if let Some(Ok(evt)) = event { + match evt { + Event::Key(key) + if key.kind == KeyEventKind::Press + => self.handle_key_event(key), + Event::Mouse(_) => {} + Event::Resize(_, _) => {} + _ => {} + } + } } - _ => {} - }; + _ = tokio::time::sleep(tokio::time::Duration::from_millis(100)) => {} + } + Ok(()) } - async fn handle_key_event(&mut self, key_event: KeyEvent) { + fn handle_key_event(&mut self, key_event: KeyEvent) { match key_event.code { - KeyCode::Char('q') => self.exit().await, - KeyCode::Char('s') => self.send().await, - KeyCode::Char('r') => self.recv().await, + KeyCode::Char('q') => self.exit(), + KeyCode::Char('s') => self.send(), + KeyCode::Char('r') => self.recv(), KeyCode::Char('d') => {} _ => {} } } - async fn exit(&mut self) { - self.state.stop().await; + fn exit(&mut self) { self.screen = CurrentScreen::Stopping; } - async fn send(&mut self) { + fn send(&mut self) { self.screen = CurrentScreen::Sending; } - async fn recv(&mut self) { + fn recv(&mut self) { self.screen = CurrentScreen::Receiving; } }