2024-08-10 08:30:23 +01:00
|
|
|
//
|
|
|
|
mod handlers;
|
|
|
|
pub mod messages;
|
2024-08-12 21:25:24 +01:00
|
|
|
mod model;
|
2024-08-10 08:30:23 +01:00
|
|
|
|
2024-08-12 21:25:24 +01:00
|
|
|
use std::sync::mpsc::Sender;
|
|
|
|
|
|
|
|
use actix::{Actor, ActorContext as _, Context};
|
2024-08-10 08:30:23 +01:00
|
|
|
|
2024-08-12 21:25:24 +01:00
|
|
|
pub use model::*;
|
2024-08-10 08:30:23 +01:00
|
|
|
|
|
|
|
use ratatui::{
|
2024-08-12 21:25:24 +01:00
|
|
|
crossterm::event::{self, KeyCode, KeyEventKind},
|
|
|
|
DefaultTerminal,
|
2024-08-10 08:30:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Tui {
|
2024-08-12 21:25:24 +01:00
|
|
|
terminal: Option<DefaultTerminal>,
|
2024-08-10 08:30:23 +01:00
|
|
|
signal_shutdown: Sender<()>,
|
2024-08-12 21:25:24 +01:00
|
|
|
pub state: State,
|
2024-08-10 08:30:23 +01:00
|
|
|
}
|
|
|
|
impl Actor for Tui {
|
|
|
|
type Context = Context<Self>;
|
|
|
|
fn started(&mut self, _ctx: &mut Self::Context) {
|
2024-08-12 21:25:24 +01:00
|
|
|
self.terminal.replace(ratatui::init());
|
2024-08-10 08:30:23 +01:00
|
|
|
}
|
|
|
|
fn stopped(&mut self, _ctx: &mut Self::Context) {
|
2024-08-12 21:25:24 +01:00
|
|
|
self.terminal.take();
|
|
|
|
ratatui::restore();
|
2024-08-10 08:30:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
impl Tui {
|
|
|
|
pub fn new(signal_shutdown: Sender<()>) -> Self {
|
|
|
|
Self {
|
|
|
|
terminal: None,
|
|
|
|
signal_shutdown,
|
2024-08-12 21:25:24 +01:00
|
|
|
state: State::initial(),
|
2024-08-10 08:30:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-12 21:25:24 +01:00
|
|
|
pub const fn state(&self) -> &State {
|
|
|
|
&self.state
|
|
|
|
}
|
|
|
|
|
|
|
|
fn draw(&mut self) -> std::io::Result<()> {
|
|
|
|
let t = self.terminal.take();
|
|
|
|
if let Some(mut terminal) = t {
|
|
|
|
terminal.draw(|frame| {
|
|
|
|
frame.render_widget(self.state(), frame.area());
|
|
|
|
})?;
|
|
|
|
self.terminal = Some(terminal);
|
|
|
|
} else {
|
|
|
|
eprintln!("No terminal setup");
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-08-10 08:30:23 +01:00
|
|
|
|
2024-08-12 21:25:24 +01:00
|
|
|
fn handle_input(&self, ctx: &mut <Self as actix::Actor>::Context) -> std::io::Result<()> {
|
|
|
|
if event::poll(std::time::Duration::from_millis(16))? {
|
|
|
|
if let event::Event::Key(key) = event::read()? {
|
|
|
|
if key.kind == KeyEventKind::Press {
|
|
|
|
match key.code {
|
|
|
|
KeyCode::Char('q') => {
|
|
|
|
ctx.stop();
|
|
|
|
if let Err(err) = self.signal_shutdown.send(()) {
|
|
|
|
tracing::error!(?err, "Failed to signal shutdown");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::Esc => {
|
|
|
|
//
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-08-10 08:30:23 +01:00
|
|
|
}
|