use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
use std::time::Duration;
use crate::app::{App, Focus, InputMode};
pub fn handle_events(app: &mut App) -> std::io::Result<bool> {
app.tick();
if event::poll(Duration::from_millis(50))?
&& let Event::Key(key) = event::read()?
{
if key.kind != KeyEventKind::Press {
return Ok(false);
}
match app.input_mode {
InputMode::Normal => handle_normal(app, key),
InputMode::Search => handle_search(app, key),
InputMode::BackendPopup => handle_backend_popup(app, key),
InputMode::ConfirmServe => handle_confirm(app, key),
InputMode::StopPopup => handle_stop_popup(app, key),
InputMode::AddDir => handle_add_dir(app, key),
}
return Ok(true);
}
Ok(false)
}
fn handle_normal(app: &mut App, key: KeyEvent) {
match key.code {
KeyCode::Char('q') | KeyCode::Esc => {
if app.focus == Focus::Tree && app.tree_source_filter.is_some() {
app.tree_source_filter = None;
app.apply_filters();
} else {
app.should_quit = true;
}
}
KeyCode::Tab => app.toggle_focus(),
KeyCode::Down | KeyCode::Char('j') => app.move_down(),
KeyCode::Up | KeyCode::Char('k') => app.move_up(),
KeyCode::Home | KeyCode::Char('g') => app.home(),
KeyCode::End | KeyCode::Char('G') => app.end(),
KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::CONTROL) => app.half_page_up(),
KeyCode::Char('d') if key.modifiers.contains(KeyModifiers::CONTROL) => app.half_page_down(),
KeyCode::Enter => {
if app.focus == Focus::Tree {
app.tree_select_source();
} else {
app.open_confirm_serve();
}
}
KeyCode::Char(' ') if app.focus == Focus::Tree => app.tree_toggle_expand(),
KeyCode::Char('a') => app.open_add_dir(),
KeyCode::Char('x') if app.focus == Focus::Tree => app.tree_remove_dir(),
KeyCode::Char('/') => app.enter_search(),
KeyCode::Char('f') => app.cycle_format_filter(),
KeyCode::Char('o') => app.cycle_sort(),
KeyCode::Char('b') => app.open_backend_popup(),
KeyCode::Char('s') => app.open_stop_popup(),
KeyCode::Char('S') => app.stop_all_servers(),
KeyCode::Char('r') => app.refresh(),
KeyCode::Char('1') => app.toggle_tree(),
KeyCode::Char('3') => app.toggle_serve_panel(),
KeyCode::Char('C') => app.clear_dead_logs(),
KeyCode::Char('w') => app.toggle_log_wrap(),
KeyCode::Left if key.modifiers.contains(KeyModifiers::SHIFT) => app.shrink_focused_pane(),
KeyCode::Right if key.modifiers.contains(KeyModifiers::SHIFT) => app.grow_focused_pane(),
KeyCode::Char('t') => app.cycle_theme(),
_ => {}
}
}
fn handle_search(app: &mut App, key: KeyEvent) {
match key.code {
KeyCode::Esc => app.clear_search(),
KeyCode::Enter => app.exit_search(),
KeyCode::Backspace => app.search_pop(),
KeyCode::Char(c) => app.search_push(c),
_ => {}
}
}
fn handle_backend_popup(app: &mut App, key: KeyEvent) {
match key.code {
KeyCode::Esc | KeyCode::Char('q') => app.cancel_popup(),
KeyCode::Down | KeyCode::Char('j') => app.backend_popup_down(),
KeyCode::Up | KeyCode::Char('k') => app.backend_popup_up(),
KeyCode::Enter => app.select_backend(),
_ => {}
}
}
fn handle_confirm(app: &mut App, key: KeyEvent) {
if app.confirm_editing_port {
match key.code {
KeyCode::Char(c) if c.is_ascii_digit() => app.confirm_port_push(c),
KeyCode::Backspace => app.confirm_port_pop(),
KeyCode::Tab | KeyCode::Enter => app.confirm_toggle_port_edit(),
KeyCode::Esc => {
app.confirm_editing_port = false;
}
_ => {}
}
return;
}
match key.code {
KeyCode::Enter | KeyCode::Char('y') => app.do_serve(),
KeyCode::Esc | KeyCode::Char('n') | KeyCode::Char('q') => app.cancel_popup(),
KeyCode::Left | KeyCode::Char('h') => app.confirm_cycle_backend_left(),
KeyCode::Right | KeyCode::Char('l') => app.confirm_cycle_backend_right(),
KeyCode::Tab | KeyCode::Char('p') => app.confirm_toggle_port_edit(),
_ => {}
}
}
fn handle_stop_popup(app: &mut App, key: KeyEvent) {
match key.code {
KeyCode::Esc | KeyCode::Char('q') => app.cancel_popup(),
KeyCode::Down | KeyCode::Char('j') => app.stop_popup_down(),
KeyCode::Up | KeyCode::Char('k') => app.stop_popup_up(),
KeyCode::Enter => app.confirm_stop(),
_ => {}
}
}
fn handle_add_dir(app: &mut App, key: KeyEvent) {
match key.code {
KeyCode::Enter => app.confirm_add_dir(),
KeyCode::Esc => app.cancel_add_dir(),
KeyCode::Backspace => app.add_dir_pop(),
KeyCode::Tab => app.add_dir_accept_completion(),
KeyCode::Down => app.add_dir_next_completion(),
KeyCode::Up => app.add_dir_prev_completion(),
KeyCode::Char(c) => app.add_dir_push(c),
_ => {}
}
}