mod actor;
mod app;
mod cli;
mod ui;
use std::io;
use std::time::Duration;
use color_eyre::Result;
use crossterm::{
ExecutableCommand,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
};
use ratatui::prelude::*;
use tokio::sync::mpsc;
use actor::{RefreshActor, RefreshControl, TmuxActor, TmuxCommand, TmuxResponse, UIActor, UIEvent};
use app::UIState;
use cli::Cli;
#[tokio::main]
async fn main() -> Result<()> {
color_eyre::install()?;
let cmd = Cli::parse_with_color()?;
enable_raw_mode()?;
io::stdout().execute(EnterAlternateScreen)?;
let terminal = Terminal::new(CrosstermBackend::new(io::stdout()))?;
let result = run_app(terminal, cmd.interval).await;
disable_raw_mode()?;
io::stdout().execute(LeaveAlternateScreen)?;
result
}
async fn run_app(terminal: Terminal<CrosstermBackend<io::Stdout>>, interval_ms: u64) -> Result<()> {
let (tmux_cmd_tx, tmux_cmd_rx) = mpsc::channel::<TmuxCommand>(32);
let (tmux_resp_tx, tmux_resp_rx) = mpsc::channel::<TmuxResponse>(32);
let (ui_event_tx, ui_event_rx) = mpsc::channel::<UIEvent>(32);
let refresh_control = RefreshControl::new();
let state = UIState::new(interval_ms);
let interval = Duration::from_millis(interval_ms);
let tmux_actor = TmuxActor::new(tmux_cmd_rx, tmux_resp_tx);
let refresh_actor = RefreshActor::new(
tmux_cmd_tx.clone(),
ui_event_tx,
refresh_control.clone(),
interval,
);
let ui_actor = UIActor::new(
terminal,
state,
tmux_cmd_tx,
tmux_resp_rx,
ui_event_rx,
refresh_control,
);
let tmux_handle = tokio::spawn(async move {
tmux_actor.run().await;
});
let refresh_handle = tokio::spawn(async move {
refresh_actor.run().await;
});
let result = ui_actor.run().await;
tmux_handle.abort();
refresh_handle.abort();
result
}