1use crossterm::event::{KeyEvent, KeyEventKind};
2use futures::StreamExt;
3use tokio::sync::mpsc;
4
5#[derive(Debug, Clone)]
6pub enum Event {
7 Key(KeyEvent),
8 Tick,
9 Refresh, }
11
12pub struct EventHandler {
13 rx: mpsc::UnboundedReceiver<Event>,
14}
15
16impl EventHandler {
17 pub fn new(tick_rate_ms: u64, refresh_interval_secs: u64) -> Self {
18 let (tx, rx) = mpsc::unbounded_channel();
19
20 tokio::spawn(async move {
21 let mut reader = crossterm::event::EventStream::new();
22 let mut tick_interval =
23 tokio::time::interval(std::time::Duration::from_millis(tick_rate_ms));
24 let mut refresh_interval =
25 tokio::time::interval(std::time::Duration::from_secs(refresh_interval_secs));
26
27 refresh_interval.tick().await;
29
30 loop {
31 tokio::select! {
32 maybe_event = reader.next() => {
33 if let Some(Ok(crossterm::event::Event::Key(key))) = maybe_event {
34 if key.kind == KeyEventKind::Press && tx.send(Event::Key(key)).is_err() {
36 break;
37 }
38 }
39 }
40 _ = tick_interval.tick() => {
41 if tx.send(Event::Tick).is_err() {
42 break;
43 }
44 }
45 _ = refresh_interval.tick() => {
46 if tx.send(Event::Refresh).is_err() {
47 break;
48 }
49 }
50 }
51 }
52 });
53
54 EventHandler { rx }
55 }
56
57 pub async fn next(&mut self) -> Event {
58 self.rx.recv().await.unwrap_or(Event::Tick)
59 }
60}