use anyhow::Result;
use crossterm::{
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::{backend::CrosstermBackend, Terminal};
use std::io::{self, Stdout};
use std::panic;
use crate::config::paths::EnvelopePaths;
use crate::config::settings::Settings;
use crate::storage::Storage;
use super::app::App;
use super::event::{Event, EventHandler};
use super::handler::handle_event;
pub type Tui = Terminal<CrosstermBackend<Stdout>>;
pub fn init_terminal() -> Result<Tui> {
let original_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
let _ = restore_terminal_impl();
original_hook(panic_info);
}));
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let terminal = Terminal::new(backend)?;
Ok(terminal)
}
pub fn restore_terminal() -> Result<()> {
restore_terminal_impl()?;
Ok(())
}
fn restore_terminal_impl() -> Result<()> {
disable_raw_mode()?;
execute!(io::stdout(), LeaveAlternateScreen)?;
Ok(())
}
pub fn run_tui(storage: &Storage, settings: &Settings, paths: &EnvelopePaths) -> Result<()> {
let mut terminal = init_terminal()?;
let mut app = App::new(storage, settings, paths);
if let Ok(accounts) = storage.accounts.get_active() {
if let Some(first) = accounts.first() {
app.selected_account = Some(first.id);
}
}
let events = EventHandler::default();
loop {
terminal.draw(|frame| {
super::views::render(frame, &mut app);
})?;
match events.next()? {
Event::Key(key_event) => {
handle_event(&mut app, Event::Key(key_event))?;
}
Event::Mouse(mouse_event) => {
handle_event(&mut app, Event::Mouse(mouse_event))?;
}
Event::Resize(_, _) => {
}
Event::Tick => {
}
}
if app.should_quit {
break;
}
}
restore_terminal()?;
Ok(())
}