Files
Gotcha/crates/tui/src/main.rs
2026-08-03 21:15:16 +02:00

82 lines
2.6 KiB
Rust

mod app;
mod editor;
mod ui;
use std::{env, error::Error, io, time::Duration};
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyEventKind},
execute,
};
use gotcha_gitea::Config;
const HELP: &str = "\
Gotcha TUI
Usage: gotcha-tui [--server SERVER]
Keyboard:
1..5 switch Home, Issues, Repos, PRs, Milestones
j/k, arrows move selection
n/p or ]/[ next/previous page
Enter open selected item
Backspace go back (edits text inside an editor)
a/e/c/x/d add, edit, comment, toggle state, delete
/, v, b, * filters, activity filter, branch, repository favorite
f browse files from a repository commit view
r reload
s choose or manage servers
, edit TUI preferences
q back, or quit from a root pane
Editors use Tab/Shift-Tab between fields, normal cursor/editing keys, Ctrl-S to
save, and Esc to cancel. Mouse clicks select items, double-click opens them,
and the scroll wheel moves through lists.";
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let requested_server = parse_args()?;
let config = Config::load()?;
let mut app = app::App::new(config, requested_server.as_deref()).await?;
let mut terminal = ratatui::init();
execute!(io::stdout(), EnableMouseCapture)?;
let result = run(&mut terminal, &mut app).await;
execute!(io::stdout(), DisableMouseCapture)?;
ratatui::restore();
result
}
async fn run(
terminal: &mut ratatui::DefaultTerminal,
app: &mut app::App,
) -> Result<(), Box<dyn Error>> {
while !app.should_quit {
terminal.draw(|frame| ui::draw(frame, app))?;
if event::poll(Duration::from_millis(100))? {
match event::read()? {
Event::Key(key) if key.kind == KeyEventKind::Press => app.handle_key(key).await,
Event::Mouse(mouse) => app.handle_mouse(mouse).await,
Event::Resize(_, _) => {}
_ => {}
}
} else if app.should_auto_reload() {
app.reload().await;
}
}
Ok(())
}
fn parse_args() -> Result<Option<String>, String> {
let args: Vec<_> = env::args().skip(1).collect();
match args.as_slice() {
[] => Ok(None),
[help] if matches!(help.as_str(), "-h" | "--help" | "help") => {
println!("{HELP}");
std::process::exit(0);
}
[option, server] if option == "--server" => Ok(Some(server.clone())),
_ => Err(format!("invalid arguments\n\n{HELP}")),
}
}