refactor
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
use std::io::stdout;
|
||||
use std::io::Write;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use crossterm::{
|
||||
cursor::{self, MoveTo},
|
||||
event::{Event, EventStream, KeyCode, KeyModifiers},
|
||||
terminal::{self, disable_raw_mode, enable_raw_mode},
|
||||
ExecutableCommand, QueueableCommand,
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use tokio::sync::broadcast::Sender;
|
||||
|
||||
use crate::message::Message;
|
||||
|
||||
pub(crate) struct Ui {
|
||||
sender: Sender<Message>,
|
||||
}
|
||||
|
||||
impl Ui {
|
||||
pub(crate) fn new(sender: Sender<Message>) -> Self {
|
||||
Self { sender }
|
||||
}
|
||||
|
||||
pub(crate) async fn main_loop(self) -> Result<()> {
|
||||
let mut reader = EventStream::new();
|
||||
|
||||
loop {
|
||||
enable_raw_mode()?;
|
||||
stdout().execute(cursor::Hide)?;
|
||||
|
||||
if let Some(Ok(Event::Key(key_event))) = reader.next().await {
|
||||
let should_exit = self.handle_key_event(key_event)?;
|
||||
if should_exit {
|
||||
return Ok(());
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_key_event(&self, key_event: crossterm::event::KeyEvent) -> Result<bool> {
|
||||
if Self::is_char_q(key_event) {
|
||||
self.prepare_for_program_quit()?;
|
||||
return Ok(true);
|
||||
};
|
||||
if Self::is_ctrl_c(key_event) {
|
||||
self.prepare_for_program_quit()?;
|
||||
self.sender.send(Message::CtrlC)?;
|
||||
bail!("<Ctrl-C>");
|
||||
}
|
||||
if Self::is_space(key_event) {
|
||||
self.sender.send(Message::TogglePause)?;
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn prepare_for_program_quit(&self) -> Result<()> {
|
||||
self.sender.send(Message::Quit)?;
|
||||
disable_raw_mode()?;
|
||||
stdout().execute(cursor::Show)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_char_q(key_event: crossterm::event::KeyEvent) -> bool {
|
||||
key_event.code == KeyCode::Char('q')
|
||||
}
|
||||
|
||||
fn is_space(key_event: crossterm::event::KeyEvent) -> bool {
|
||||
key_event.code == KeyCode::Char(' ')
|
||||
}
|
||||
|
||||
fn is_ctrl_c(key_event: crossterm::event::KeyEvent) -> bool {
|
||||
key_event.code == KeyCode::Char('c') && key_event.modifiers.contains(KeyModifiers::CONTROL)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clear_terminal() -> Result<()> {
|
||||
let mut stdout = stdout();
|
||||
stdout.queue(terminal::Clear(terminal::ClearType::All))?;
|
||||
stdout.queue(terminal::Clear(terminal::ClearType::Purge))?;
|
||||
stdout.queue(MoveTo(0, 0))?;
|
||||
stdout.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user