use crate::app::{AppState, Action};
use crate::input::InputEvent;
use crate::errors::ComponentError;
use crate::config;
use crossterm::event::KeyCode::*;
use crossterm::event::KeyModifiers;
pub fn handle_op_log(event: InputEvent) -> Result<Option<Action>, ComponentError> {
if let InputEvent::Key(key) = &event {
if key.kind == crossterm::event::KeyEventKind::Press {
return Ok(match key.code {
Esc | Enter | Char('q') => Some(Action::ToggleOpLog),
_ => None,
});
}
}
Ok(None)
}
pub fn handle_merge_log(event: InputEvent) -> Result<Option<Action>, ComponentError> {
if let InputEvent::Key(key) = &event {
if key.kind == crossterm::event::KeyEventKind::Press {
return Ok(match key.code {
Esc | Enter | Char('q') => Some(Action::ToggleMergeLog),
_ => None,
});
}
}
Ok(None)
}
pub fn handle_pr_helper(event: InputEvent, state: &AppState) -> Result<Option<Action>, ComponentError> {
let prs = &state.pr_list;
let max_idx = prs.len().saturating_sub(1);
if let InputEvent::Key(key) = &event {
if key.kind == crossterm::event::KeyEventKind::Press {
return Ok(match key.code {
Esc => Some(Action::HidePrHelper),
Up | Char('k') => Some(Action::PrHelperUp),
Down | Char('j') => Some(Action::PrHelperDown),
Enter => prs
.get(state.pr_selected.min(max_idx))
.map(|pr| Action::CheckoutPr(pr.number.clone())),
Char('o') => prs
.get(state.pr_selected.min(max_idx))
.map(|pr| Action::OpenPrInBrowser(pr.number.clone())),
_ => None,
});
}
}
Ok(None)
}
pub fn handle_theme_picker(event: InputEvent, state: &AppState) -> Result<Option<Action>, ComponentError> {
if let InputEvent::Key(key) = &event {
if key.kind == crossterm::event::KeyEventKind::Press {
match key.code {
Esc => {
return Ok(Some(Action::ThemePreviewCancel));
}
Char('q') => {
return Ok(Some(Action::ThemePreviewCancel));
}
Up | Char('k') => {
if state.theme_picker_selected > 0 {
let target = state.theme_picker_selected - 1;
if let Some(name) = state.available_themes.get(target) {
let mut theme = config::load_theme_by_name(name);
theme.enable_transparency = state.theme.enable_transparency;
return Ok(Some(Action::ThemePreviewSet(
target,
Box::new(theme),
)));
}
}
}
Down | Char('j') => {
let max_idx = state.available_themes.len().saturating_sub(1);
if state.theme_picker_selected < max_idx {
let target = state.theme_picker_selected + 1;
if let Some(name) = state.available_themes.get(target) {
let mut theme = config::load_theme_by_name(name);
theme.enable_transparency = state.theme.enable_transparency;
return Ok(Some(Action::ThemePreviewSet(
target,
Box::new(theme),
)));
}
}
}
Enter => {
let max_idx = state.available_themes.len().saturating_sub(1);
let selected = state.theme_picker_selected.min(max_idx);
let name = state.available_themes.get(selected).cloned();
if let Some(n) = name {
return Ok(Some(Action::ApplyTheme(n)));
}
return Ok(Some(Action::ThemePreviewCancel));
}
_ => {}
}
}
}
Ok(None)
}
pub fn handle_merge_base_picker(event: InputEvent, state: &AppState) -> Result<Option<Action>, ComponentError> {
if let InputEvent::Key(key) = &event {
if key.kind == crossterm::event::KeyEventKind::Press {
return Ok(match key.code {
Esc => Some(Action::HideMergeBasePicker),
Up | Char('k') => Some(Action::MergeBaseUp),
Down | Char('j') => Some(Action::MergeBaseDown),
Enter => {
let idx = state.merge_base_selected.min(state.merge_base_candidates.len().saturating_sub(1));
let name = state.merge_base_candidates.get(idx).cloned();
name.map(Action::ApplyMergeBase)
}
_ => None,
});
}
}
Ok(None)
}
pub fn handle_help(event: InputEvent, _state: &AppState) -> Result<Option<Action>, ComponentError> {
if let InputEvent::Key(key) = &event {
if key.kind == crossterm::event::KeyEventKind::Press {
return Ok(match key.code {
Char('q') => Some(Action::Quit),
Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => Some(Action::Quit),
Char(':') => Some(Action::ShowPalette),
Up | Char('k') => Some(Action::HelpUp),
Down | Char('j') => Some(Action::HelpDown),
Esc | Char('h') => Some(Action::ToggleHelp),
_ => None,
});
}
}
Ok(None)
}