diff --git a/src/discovery.rs b/src/discovery.rs index 2d975b9..8f9b16d 100644 --- a/src/discovery.rs +++ b/src/discovery.rs @@ -27,12 +27,15 @@ impl JoecalState { let mut buf = [0; 65536]; let mut timeout = tokio::time::interval(Duration::from_secs(5)); + timeout.tick().await; loop { tokio::select! { _ = timeout.tick() => { - let rstate = self.running_state.lock().await; - if *rstate == RunningState::Stopping + let rstate = { + *self.running_state.lock().await + }; + if rstate == RunningState::Stopping { break; } @@ -45,7 +48,6 @@ impl JoecalState { } Err(e) => { eprintln!("Error receiving message: {e}"); - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; } } } @@ -63,8 +65,10 @@ impl JoecalState { let mut src = src; src.set_port(device.port); // Update the port to the one the device sent - let mut peers = self.peers.lock().await; - peers.insert(device.fingerprint.clone(), (src, device.clone())); + { + let mut peers = self.peers.lock().await; + peers.insert(device.fingerprint.clone(), (src, device.clone())); + } if device.announce != Some(true) { return; diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index e515fc1..bcecc34 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -23,6 +23,7 @@ use tokio::{ }; pub mod ui; +pub mod widgets; pub type Peers = BTreeMap; diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs index 92a40fa..926e1c6 100644 --- a/src/frontend/ui.rs +++ b/src/frontend/ui.rs @@ -1,23 +1,12 @@ use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Margin, Rect}, - style::Stylize, - text::Line, - widgets::{Block, Borders, List, ListItem, Padding}, }; -use crate::{ - App, - frontend::{CurrentScreen, Peers}, -}; - -enum Action { - PushScreen(CurrentScreen), - PopScreen, -} +use crate::{App, frontend::widgets::*}; impl App { - pub fn draw(&self, frame: &mut Frame) { + pub fn draw(&mut self, frame: &mut Frame) { let [top, middle, bottom] = Layout::default() .direction(Direction::Vertical) .constraints([Constraint::Min(3), Constraint::Min(3), Constraint::Min(3)]) @@ -34,62 +23,15 @@ impl App { .cloned() .unwrap(); - network_info(frame, footer_left.inner(Margin::new(1, 1))); - peers(&self.peers, frame, footer_right.inner(Margin::new(1, 1))); + let peers = PeersWidget { peers: &self.peers }; + frame.render_widget(peers, footer_right.inner(Margin::new(1, 1))); + frame.render_widget(NetworkInfoWidget, footer_left.inner(Margin::new(1, 1))); + // draw the main frame last frame.render_widget(self, frame.area()); } } -fn peers(peers: &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 title = Line::from(" Peers ".bold()).centered(); - 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); -} - -fn network_info(frame: &mut Frame, area: Rect) { - let udp: Line = format!("UDP socket:\t\t\t {:?}", joecalsend::LISTENING_SOCKET_ADDR) - .yellow() - .into(); - let multicast: Line = format!( - "Multicast address:\t\t {:?}:{}", - joecalsend::MULTICAST_IP, - joecalsend::DEFAULT_PORT - ) - .yellow() - .into(); - let http: Line = format!( - "HTTP address:\t\t\t {:?}", - joecalsend::LISTENING_SOCKET_ADDR - ) - .yellow() - .into(); - let items = [ - ListItem::new(udp), - ListItem::new(multicast), - ListItem::new(http), - ]; - let title = Line::from(" Listeners ".bold()).centered(); - 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); -} - // 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 { diff --git a/src/frontend/widgets.rs b/src/frontend/widgets.rs new file mode 100644 index 0000000..8c3a7ed --- /dev/null +++ b/src/frontend/widgets.rs @@ -0,0 +1,76 @@ +use ratatui::{ + buffer::Buffer, + layout::Rect, + style::Stylize, + text::Line, + widgets::{Block, Borders, List, ListItem, Padding, Widget}, +}; + +use super::Peers; + +#[derive(Debug, Clone)] +pub struct PeersWidget<'p> { + pub peers: &'p Peers, +} + +impl<'p> Widget for PeersWidget<'p> { + fn render(self, area: Rect, buf: &mut Buffer) + where + Self: Sized, + { + let mut items = Vec::with_capacity(self.peers.len()); + for (k, v) in self.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 title = Line::from(" Peers ".bold()).centered(); + let block = Block::default() + .title(title) + .borders(Borders::all()) + .padding(Padding::uniform(1)); + let list = List::new(items).block(block); + list.render(area, buf); + } +} + +#[derive(Debug, Clone)] +pub struct NetworkInfoWidget; + +impl Widget for NetworkInfoWidget { + fn render(self, area: Rect, buf: &mut Buffer) + where + Self: Sized, + { + let udp: Line = format!("UDP socket:\t\t\t {:?}", joecalsend::LISTENING_SOCKET_ADDR) + .yellow() + .into(); + let multicast: Line = format!( + "Multicast address:\t\t {:?}:{}", + joecalsend::MULTICAST_IP, + joecalsend::DEFAULT_PORT + ) + .yellow() + .into(); + let http: Line = format!( + "HTTP address:\t\t\t {:?}", + joecalsend::LISTENING_SOCKET_ADDR + ) + .yellow() + .into(); + let items = [ + ListItem::new(udp), + ListItem::new(multicast), + ListItem::new(http), + ]; + let title = Line::from(" Listeners ".bold()).centered(); + let block = Block::default() + .title(title) + .borders(Borders::all()) + .padding(Padding::uniform(1)); + let list = List::new(items).block(block); + list.render(area, buf); + } +}