use crossterm::event::Event as CrosstermEvent;
use crossterm::event::{EventStream, KeyEventKind};
use futures::StreamExt;
use tokio::sync::mpsc;
use crate::components::events::{AppEvent, AppTx, InputEvent};
pub struct EventHandler {
tx: AppTx,
rx: mpsc::UnboundedReceiver<AppEvent>,
crossterm_stream: EventStream,
}
impl EventHandler {
pub fn new() -> Self {
let (tx, rx) = mpsc::unbounded_channel();
Self {
tx,
rx,
crossterm_stream: EventStream::new(),
}
}
pub fn app_sender(&self) -> AppTx {
self.tx.clone()
}
pub async fn next(&mut self) -> AppEvent {
loop {
tokio::select! {
biased;
Some(msg) = self.rx.recv() => return msg,
Some(Ok(event)) = self.crossterm_stream.next() => {
log::debug!("RAW EVENT: {:?}", event);
match event {
CrosstermEvent::Key(key) if key.kind != KeyEventKind::Release => {
return AppEvent::Input(InputEvent::Key(key));
}
CrosstermEvent::Mouse(mouse) => return AppEvent::Input(InputEvent::Mouse(mouse)),
_ => continue,
}
}
}
}
}
}