git-next/crates/cli/src/tui/actor/mod.rs

76 lines
1.9 KiB
Rust
Raw Normal View History

//
mod handlers;
pub mod messages;
use std::{
io::{stderr, Stderr},
sync::mpsc::Sender,
time::Instant,
};
use actix::{Actor, Context};
use ratatui::{
crossterm::{
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
},
prelude::CrosstermBackend,
Terminal,
};
#[derive(Debug)]
pub struct Tui {
terminal: Option<Terminal<CrosstermBackend<Stderr>>>,
signal_shutdown: Sender<()>,
last_ping: Instant,
}
impl Actor for Tui {
type Context = Context<Self>;
fn started(&mut self, _ctx: &mut Self::Context) {
match init() {
Err(err) => {
eprintln!("Failed to enable raw mode: {err:?}");
}
Ok(terminal) => {
self.terminal.replace(terminal);
}
}
}
fn stopped(&mut self, _ctx: &mut Self::Context) {
if let Err(err) = restore() {
match std::env::consts::OS {
"linux" | "macos" => {
eprintln!(
"Failed to restore terminal: Type `reset` to restore terminal: {err:?}"
);
}
"windows" => {
println!("Failed to restore terminal: Reopen a new terminal: {err:?}");
}
_ => println!("Failed to restore terminal: {err:?}"),
}
}
}
}
impl Tui {
pub fn new(signal_shutdown: Sender<()>) -> Self {
Self {
terminal: None,
signal_shutdown,
last_ping: Instant::now(),
}
}
}
fn init() -> std::io::Result<Terminal<CrosstermBackend<Stderr>>> {
execute!(stderr(), EnterAlternateScreen)?;
enable_raw_mode()?;
Terminal::new(CrosstermBackend::new(stderr()))
}
fn restore() -> std::io::Result<()> {
execute!(stderr(), LeaveAlternateScreen)?;
disable_raw_mode()
}