use crate::app::{AppState, KeypressResult};
use crate::ui;
use crossterm::{
cursor::{Hide, Show},
event::{self, Event, KeyEventKind},
execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
};
use ratatui::Terminal;
use ratatui::backend::{Backend, CrosstermBackend};
use std::{io, time::Duration};
pub fn run_terminal(app: &mut AppState) -> io::Result<()> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, Hide)?;
let mut terminal = Terminal::new(CrosstermBackend::new(stdout))?;
let result = event_loop(&mut terminal, app);
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen, Show)?;
result
}
fn event_loop<B: ratatui::backend::Backend>(
terminal: &mut Terminal<B>,
app: &mut AppState,
) -> io::Result<()>
where
io::Error: From<<B as Backend>::Error>,
{
loop {
if app.tick() {
terminal.draw(|f| ui::render(f, app))?;
}
if event::poll(Duration::from_millis(16))? {
match event::read()? {
Event::Key(key) if key.kind == KeyEventKind::Press => {
let result = app.handle_keypress(key);
match result {
KeypressResult::Quit => break,
KeypressResult::OpenedEditor => {
terminal.clear()?;
}
_ => {}
}
terminal.draw(|f| ui::render(f, app))?;
}
Event::Resize(_, _) => {
terminal.draw(|f| ui::render(f, app))?;
}
_ => {}
}
}
}
Ok(())
}