move stuff around a little
This commit is contained in:
parent
d73076f197
commit
34e64f5e51
3 changed files with 95 additions and 99 deletions
109
src/app/mod.rs
109
src/app/mod.rs
|
@ -2,17 +2,11 @@ use std::{collections::BTreeMap, net::SocketAddr, time::Duration};
|
||||||
|
|
||||||
use crossterm::event::{Event, EventStream, KeyCode, KeyEvent, KeyEventKind};
|
use crossterm::event::{Event, EventStream, KeyCode, KeyEvent, KeyEventKind};
|
||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use joecalsend::{
|
use joecalsend::{JoecalService, JoecalUploadRequest, TransferEvent, UploadDialog, error::Result};
|
||||||
Config, JoecalService, JoecalUploadRequest, Listeners, TransferEvent, UploadDialog,
|
|
||||||
error::Result, models::Device,
|
|
||||||
};
|
|
||||||
use julid::Julid;
|
use julid::Julid;
|
||||||
use log::{LevelFilter, debug, error, info, warn};
|
use log::{LevelFilter, debug, error, warn};
|
||||||
use ratatui::{DefaultTerminal, Frame, widgets::TableState};
|
use ratatui::{Frame, widgets::TableState};
|
||||||
use tokio::{
|
use tokio::sync::mpsc::UnboundedReceiver;
|
||||||
sync::mpsc::{UnboundedReceiver, unbounded_channel},
|
|
||||||
task::JoinSet,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
|
|
||||||
|
@ -40,58 +34,6 @@ pub enum CurrentScreen {
|
||||||
Logging,
|
Logging,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
pub async fn start_and_run(
|
|
||||||
terminal: &mut DefaultTerminal,
|
|
||||||
config: Config,
|
|
||||||
device: Device,
|
|
||||||
) -> Result<()> {
|
|
||||||
let (event_tx, event_listener) = unbounded_channel();
|
|
||||||
|
|
||||||
let service = JoecalService::new(device, event_tx)
|
|
||||||
.await
|
|
||||||
.expect("Could not create JoecalService");
|
|
||||||
|
|
||||||
let mut app = App::new(service, event_listener);
|
|
||||||
|
|
||||||
let mut handles = JoinSet::new();
|
|
||||||
app.service.start(&config, &mut handles).await;
|
|
||||||
loop {
|
|
||||||
terminal.draw(|frame| app.draw(frame))?;
|
|
||||||
app.handle_events().await?;
|
|
||||||
|
|
||||||
if let Some(&top) = app.screen.last()
|
|
||||||
&& top == CurrentScreen::Stopping
|
|
||||||
{
|
|
||||||
app.service.stop().await;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let peers = app.service.peers.lock().await;
|
|
||||||
app.peers.clear();
|
|
||||||
peers.iter().for_each(|(fingerprint, (addr, device))| {
|
|
||||||
let alias = device.alias.clone();
|
|
||||||
app.peers
|
|
||||||
.insert(addr.to_owned(), (alias, fingerprint.to_owned()));
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut stale_uploads = Vec::new();
|
|
||||||
let now = chrono::Utc::now().timestamp_millis() as u64;
|
|
||||||
for (id, request) in app.uploads.iter() {
|
|
||||||
if request.tx.is_closed() || (now - id.timestamp()) > 60_000 {
|
|
||||||
stale_uploads.push(*id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for id in stale_uploads {
|
|
||||||
app.uploads.remove(&id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shutdown(&mut handles).await;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(service: JoecalService, event_listener: UnboundedReceiver<TransferEvent>) -> Self {
|
pub fn new(service: JoecalService, event_listener: UnboundedReceiver<TransferEvent>) -> Self {
|
||||||
App {
|
App {
|
||||||
|
@ -105,7 +47,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_events(&mut self) -> Result<()> {
|
pub async fn handle_events(&mut self) -> Result<()> {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
event = self.events.next().fuse() => {
|
event = self.events.next().fuse() => {
|
||||||
if let Some(Ok(evt)) = event {
|
if let Some(Ok(evt)) = event {
|
||||||
|
@ -138,7 +80,7 @@ impl App {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_key_event(&mut self, key_event: KeyEvent) {
|
pub fn handle_key_event(&mut self, key_event: KeyEvent) {
|
||||||
match self.screen.last().unwrap() {
|
match self.screen.last().unwrap() {
|
||||||
CurrentScreen::Logging => match key_event.code {
|
CurrentScreen::Logging => match key_event.code {
|
||||||
KeyCode::Esc => self.pop(),
|
KeyCode::Esc => self.pop(),
|
||||||
|
@ -167,7 +109,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept(&mut self) {
|
pub fn accept(&mut self) {
|
||||||
let Some(idx) = self.upload_state.selected() else {
|
let Some(idx) = self.upload_state.selected() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -185,7 +127,7 @@ impl App {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deny(&mut self) {
|
pub fn deny(&mut self) {
|
||||||
let Some(idx) = self.upload_state.selected() else {
|
let Some(idx) = self.upload_state.selected() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -204,15 +146,15 @@ impl App {
|
||||||
self.uploads.remove(key);
|
self.uploads.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self, frame: &mut Frame) {
|
pub fn draw(&mut self, frame: &mut Frame) {
|
||||||
frame.render_widget(self, frame.area());
|
frame.render_widget(self, frame.area());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit(&mut self) {
|
pub fn exit(&mut self) {
|
||||||
self.screen.push(CurrentScreen::Stopping);
|
self.screen.push(CurrentScreen::Stopping);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(&mut self) {
|
pub fn send(&mut self) {
|
||||||
let last = self.screen.last();
|
let last = self.screen.last();
|
||||||
match last {
|
match last {
|
||||||
Some(CurrentScreen::Sending) => {}
|
Some(CurrentScreen::Sending) => {}
|
||||||
|
@ -220,7 +162,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv(&mut self) {
|
pub fn recv(&mut self) {
|
||||||
let last = self.screen.last();
|
let last = self.screen.last();
|
||||||
match last {
|
match last {
|
||||||
Some(CurrentScreen::Receiving) => {}
|
Some(CurrentScreen::Receiving) => {}
|
||||||
|
@ -228,7 +170,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn logs(&mut self) {
|
pub fn logs(&mut self) {
|
||||||
let last = self.screen.last();
|
let last = self.screen.last();
|
||||||
match last {
|
match last {
|
||||||
Some(CurrentScreen::Logging) => {}
|
Some(CurrentScreen::Logging) => {}
|
||||||
|
@ -236,7 +178,7 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop(&mut self) {
|
pub fn pop(&mut self) {
|
||||||
self.screen.pop();
|
self.screen.pop();
|
||||||
if self.screen.last().is_none() {
|
if self.screen.last().is_none() {
|
||||||
self.screen.push(CurrentScreen::Main);
|
self.screen.push(CurrentScreen::Main);
|
||||||
|
@ -253,26 +195,3 @@ fn change_log_level(delta: isize) {
|
||||||
|
|
||||||
log::set_max_level(level);
|
log::set_max_level(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn shutdown(handles: &mut JoinSet<Listeners>) {
|
|
||||||
let mut alarm = tokio::time::interval(tokio::time::Duration::from_secs(5));
|
|
||||||
alarm.tick().await;
|
|
||||||
loop {
|
|
||||||
tokio::select! {
|
|
||||||
join_result = handles.join_next() => {
|
|
||||||
match join_result {
|
|
||||||
Some(handle) => match handle {
|
|
||||||
Ok(h) => info!("Stopped {h:?}"),
|
|
||||||
Err(e) => error!("Got error {e:?}"),
|
|
||||||
}
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ = alarm.tick() => {
|
|
||||||
info!("Exit timeout reached, aborting all unjoined tasks");
|
|
||||||
handles.abort_all();
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ use axum::{
|
||||||
extract::{ConnectInfo, State},
|
extract::{ConnectInfo, State},
|
||||||
};
|
};
|
||||||
use log::{debug, error, trace, warn};
|
use log::{debug, error, trace, warn};
|
||||||
use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig, V4IfAddr};
|
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
use crate::{Config, JoecalService, RunningState, models::Device};
|
use crate::{Config, JoecalService, RunningState, models::Device};
|
||||||
|
|
84
src/main.rs
84
src/main.rs
|
@ -1,8 +1,11 @@
|
||||||
use joecalsend::{Config, error, models::Device};
|
use joecalsend::{Config, JoecalService, Listeners, error, models::Device};
|
||||||
use local_ip_address::local_ip;
|
use log::{error, info};
|
||||||
|
use ratatui::DefaultTerminal;
|
||||||
|
use tokio::{sync::mpsc::unbounded_channel, task::JoinSet};
|
||||||
use tui_logger::{LevelFilter, init_logger, set_env_filter_from_env};
|
use tui_logger::{LevelFilter, init_logger, set_env_filter_from_env};
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
|
use app::{App, CurrentScreen};
|
||||||
|
|
||||||
fn main() -> error::Result<()> {
|
fn main() -> error::Result<()> {
|
||||||
let device = Device::default();
|
let device = Device::default();
|
||||||
|
@ -18,8 +21,83 @@ fn main() -> error::Result<()> {
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
|
|
||||||
let mut terminal = ratatui::init();
|
let mut terminal = ratatui::init();
|
||||||
let result = app::start_and_run(&mut terminal, config, device);
|
let result = start_and_run(&mut terminal, config, device);
|
||||||
ratatui::restore();
|
ratatui::restore();
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn start_and_run(
|
||||||
|
terminal: &mut DefaultTerminal,
|
||||||
|
config: Config,
|
||||||
|
device: Device,
|
||||||
|
) -> error::Result<()> {
|
||||||
|
let (event_tx, event_listener) = unbounded_channel();
|
||||||
|
|
||||||
|
let service = JoecalService::new(device, event_tx)
|
||||||
|
.await
|
||||||
|
.expect("Could not create JoecalService");
|
||||||
|
|
||||||
|
let mut app = App::new(service, event_listener);
|
||||||
|
|
||||||
|
let mut handles = JoinSet::new();
|
||||||
|
app.service.start(&config, &mut handles).await;
|
||||||
|
loop {
|
||||||
|
terminal.draw(|frame| app.draw(frame))?;
|
||||||
|
app.handle_events().await?;
|
||||||
|
|
||||||
|
if let Some(&top) = app.screen.last()
|
||||||
|
&& top == CurrentScreen::Stopping
|
||||||
|
{
|
||||||
|
app.service.stop().await;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let peers = app.service.peers.lock().await;
|
||||||
|
app.peers.clear();
|
||||||
|
peers.iter().for_each(|(fingerprint, (addr, device))| {
|
||||||
|
let alias = device.alias.clone();
|
||||||
|
app.peers
|
||||||
|
.insert(addr.to_owned(), (alias, fingerprint.to_owned()));
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut stale_uploads = Vec::with_capacity(app.uploads.len());
|
||||||
|
let now = chrono::Utc::now().timestamp_millis() as u64;
|
||||||
|
for (id, request) in app.uploads.iter() {
|
||||||
|
if request.tx.is_closed() || (now - id.timestamp()) > 60_000 {
|
||||||
|
stale_uploads.push(*id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for id in stale_uploads {
|
||||||
|
app.uploads.remove(&id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown(&mut handles).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn shutdown(handles: &mut JoinSet<Listeners>) {
|
||||||
|
let mut alarm = tokio::time::interval(tokio::time::Duration::from_secs(5));
|
||||||
|
alarm.tick().await;
|
||||||
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
join_result = handles.join_next() => {
|
||||||
|
match join_result {
|
||||||
|
Some(handle) => match handle {
|
||||||
|
Ok(h) => info!("Stopped {h:?}"),
|
||||||
|
Err(e) => error!("Got error {e:?}"),
|
||||||
|
}
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = alarm.tick() => {
|
||||||
|
info!("Exit timeout reached, aborting all unjoined tasks");
|
||||||
|
handles.abort_all();
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue