76 lines
1.9 KiB
Rust
76 lines
1.9 KiB
Rust
|
//
|
||
|
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()
|
||
|
}
|