pub mod app;
pub mod event;
pub mod ui;
pub mod views;
use std::io;
use std::path::PathBuf;
use crossterm::{
event::DisableMouseCapture,
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::backend::CrosstermBackend;
use ratatui::Terminal;
use app::App;
use event::{Event, EventHandler};
pub fn run(team: Option<String>, repo_path: Option<PathBuf>) -> crate::Result<()> {
let repo_path = match repo_path {
Some(p) => p,
None => std::env::current_dir().map_err(|e| crate::Error::Other(e.to_string()))?,
};
enable_raw_mode().map_err(|e| crate::Error::Other(format!("Failed to enable raw mode: {e}")))?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)
.map_err(|e| crate::Error::Other(format!("Failed to enter alternate screen: {e}")))?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)
.map_err(|e| crate::Error::Other(format!("Failed to create terminal: {e}")))?;
let mut app = App::new(team, repo_path);
let events = EventHandler::new(250);
let result = run_loop(&mut terminal, &mut app, &events);
disable_raw_mode().ok();
execute!(terminal.backend_mut(), LeaveAlternateScreen, DisableMouseCapture).ok();
terminal.show_cursor().ok();
result
}
fn run_loop(
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
app: &mut App,
events: &EventHandler,
) -> crate::Result<()> {
loop {
terminal
.draw(|frame| ui::draw(frame, app))
.map_err(|e| crate::Error::Other(format!("Draw error: {e}")))?;
match events.next() {
Ok(Event::Key(key)) => {
app.handle_key(key);
if app.should_quit {
return Ok(());
}
}
Ok(Event::Tick) => {
app.tick();
}
Ok(Event::Resize(_, _)) => {
}
Err(e) => {
return Err(crate::Error::Other(format!("Event error: {e}")));
}
}
}
}