use crossterm::event::{KeyEvent, KeyEventKind};
use futures::StreamExt;
use tokio::sync::mpsc;
#[derive(Debug, Clone)]
pub enum Event {
Key(KeyEvent),
Tick,
Refresh, }
pub struct EventHandler {
rx: mpsc::UnboundedReceiver<Event>,
}
impl EventHandler {
pub fn new(tick_rate_ms: u64, refresh_interval_secs: u64) -> Self {
let (tx, rx) = mpsc::unbounded_channel();
tokio::spawn(async move {
let mut reader = crossterm::event::EventStream::new();
let mut tick_interval =
tokio::time::interval(std::time::Duration::from_millis(tick_rate_ms));
let mut refresh_interval =
tokio::time::interval(std::time::Duration::from_secs(refresh_interval_secs));
refresh_interval.tick().await;
loop {
tokio::select! {
maybe_event = reader.next() => {
if let Some(Ok(crossterm::event::Event::Key(key))) = maybe_event {
if key.kind == KeyEventKind::Press && tx.send(Event::Key(key)).is_err() {
break;
}
}
}
_ = tick_interval.tick() => {
if tx.send(Event::Tick).is_err() {
break;
}
}
_ = refresh_interval.tick() => {
if tx.send(Event::Refresh).is_err() {
break;
}
}
}
}
});
EventHandler { rx }
}
pub async fn next(&mut self) -> Event {
self.rx.recv().await.unwrap_or(Event::Tick)
}
}