// 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>>, signal_shutdown: Sender<()>, last_ping: Instant, } impl Actor for Tui { type Context = Context; 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>> { execute!(stderr(), EnterAlternateScreen)?; enable_raw_mode()?; Terminal::new(CrosstermBackend::new(stderr())) } fn restore() -> std::io::Result<()> { execute!(stderr(), LeaveAlternateScreen)?; disable_raw_mode() }