use crate::tui::App;
use crossterm::event::{KeyCode, KeyEvent};
pub(super) fn handle_multi_diff_keys(app: &mut App, key: KeyEvent) {
if app.tabs.multi_diff.search.active {
handle_multi_diff_search(app, key);
return;
}
if app.tabs.multi_diff.show_detail_modal {
match key.code {
KeyCode::Esc | KeyCode::Char('q') => {
app.tabs.multi_diff.close_detail_modal();
}
_ => {}
}
return;
}
if app.tabs.multi_diff.show_variable_drill_down {
match key.code {
KeyCode::Esc | KeyCode::Char('q') => {
app.tabs.multi_diff.close_variable_drill_down();
}
KeyCode::Up | KeyCode::Char('k') => {
app.tabs.multi_diff.select_prev_variable_component();
}
KeyCode::Down | KeyCode::Char('j') => {
app.tabs.multi_diff.select_next_variable_component();
}
_ => {}
}
return;
}
match key.code {
KeyCode::Tab | KeyCode::Char('p') => app.tabs.multi_diff.toggle_panel(),
KeyCode::Up | KeyCode::Char('k') => app.tabs.multi_diff.select_prev(),
KeyCode::Down | KeyCode::Char('j') => app.tabs.multi_diff.select_next(),
KeyCode::Char('/') => {
app.tabs.multi_diff.search.start();
}
KeyCode::Char('f') => {
app.tabs.multi_diff.toggle_filter();
app.set_status_message(format!(
"Filter: {}",
app.tabs.multi_diff.filter_preset.label()
));
}
KeyCode::Char('s') => {
app.tabs.multi_diff.toggle_sort();
app.set_status_message(format!(
"Sort: {} {}",
app.tabs.multi_diff.sort_by.label(),
app.tabs.multi_diff.sort_direction.indicator()
));
}
KeyCode::Char('S') => {
app.tabs.multi_diff.toggle_sort_direction();
app.set_status_message(format!(
"Sort: {} {}",
app.tabs.multi_diff.sort_by.label(),
app.tabs.multi_diff.sort_direction.indicator()
));
}
KeyCode::Enter | KeyCode::Char(' ') => {
app.tabs.multi_diff.toggle_detail_modal();
}
KeyCode::Char('v') => {
app.tabs.multi_diff.toggle_variable_drill_down();
}
KeyCode::Char('x') => {
app.tabs.multi_diff.toggle_cross_target();
let status = if app.tabs.multi_diff.show_cross_target {
"Cross-target analysis: enabled"
} else {
"Cross-target analysis: disabled"
};
app.set_status_message(status.to_string());
}
KeyCode::Char('h') => {
app.tabs.multi_diff.toggle_heat_map();
let status = if app.tabs.multi_diff.heat_map_mode {
"Heat map mode: enabled"
} else {
"Heat map mode: disabled"
};
app.set_status_message(status.to_string());
}
_ => {}
}
}
pub(super) fn handle_multi_diff_search(app: &mut App, key: KeyEvent) {
match key.code {
KeyCode::Esc => {
app.tabs.multi_diff.search.cancel();
}
KeyCode::Enter => {
app.tabs.multi_diff.search.confirm();
if let Some(idx) = app.tabs.multi_diff.search.current_match_index() {
app.tabs.multi_diff.selected_target = idx;
}
}
KeyCode::Backspace => {
app.tabs.multi_diff.search.pop();
update_multi_diff_search_matches(app);
}
KeyCode::Down => {
app.tabs.multi_diff.search.next_match();
}
KeyCode::Up => {
app.tabs.multi_diff.search.prev_match();
}
KeyCode::Char(c) => {
app.tabs.multi_diff.search.push(c);
update_multi_diff_search_matches(app);
}
_ => {}
}
}
pub(super) fn update_multi_diff_search_matches(app: &mut App) {
let query = app.tabs.multi_diff.search.query.to_lowercase();
if query.is_empty() {
app.tabs.multi_diff.search.update_matches(vec![]);
return;
}
let matches: Vec<usize> = app
.data
.multi_diff_result
.as_ref()
.map_or_else(Vec::new, |result| {
result
.comparisons
.iter()
.enumerate()
.filter(|(_, comp)| comp.target.name.to_lowercase().contains(&query))
.map(|(i, _)| i)
.collect()
});
app.tabs.multi_diff.search.update_matches(matches);
}