use std::path::PathBuf;
use bitrouter_providers::acp::types::AgentEvent;
use crossterm::event::{Event as CrosstermEvent, EventStream, KeyEvent, MouseEvent};
use futures::StreamExt;
use tokio::sync::mpsc;
#[derive(Debug)]
pub enum AppEvent {
Key(KeyEvent),
Mouse(MouseEvent),
Resize { _width: u16, _height: u16 },
Tick,
Agent(AgentEvent),
InstallProgress { agent_id: String, percent: u8 },
InstallComplete {
agent_id: String,
binary_path: PathBuf,
},
InstallFailed { agent_id: String, message: String },
}
pub struct EventHandler {
tx: mpsc::Sender<AppEvent>,
rx: mpsc::Receiver<AppEvent>,
}
impl EventHandler {
pub fn new() -> Self {
let (tx, rx) = mpsc::channel(256);
let pump_tx = tx.clone();
tokio::spawn(terminal_event_pump(pump_tx));
Self { tx, rx }
}
pub fn sender(&self) -> mpsc::Sender<AppEvent> {
self.tx.clone()
}
pub async fn next(&mut self) -> Option<AppEvent> {
self.rx.recv().await
}
}
async fn terminal_event_pump(tx: mpsc::Sender<AppEvent>) {
let mut stream = EventStream::new();
while let Some(Ok(event)) = stream.next().await {
let app_event = match event {
CrosstermEvent::Key(k) => AppEvent::Key(k),
CrosstermEvent::Resize(w, h) => AppEvent::Resize {
_width: w,
_height: h,
},
CrosstermEvent::Mouse(m) => AppEvent::Mouse(m),
_ => AppEvent::Tick,
};
if tx.send(app_event).await.is_err() {
break; }
}
}