use color_eyre::Result;
use crossterm::event;
use crossterm::event::Event;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyEventKind;
use crossterm::event::KeyModifiers;
use crate::merge_request;
use super::App;
use super::InputFocus;
use super::Screens;
impl App {
pub(crate) fn handle_crossterm_events(&mut self) -> Result<()> {
match event::read()? {
Event::Key(key) if key.kind == KeyEventKind::Press => self.on_key_event(key),
Event::Mouse(_) => {}
Event::Resize(_, _) => {}
_ => {}
}
Ok(())
}
pub(crate) fn on_key_event(&mut self, key: KeyEvent) {
match key.code {
KeyCode::Char('c') | KeyCode::Char('C') => {
if key.modifiers == KeyModifiers::CONTROL {
self.quit();
}
}
_ => {}
}
match self.screen {
Screens::RepoSelection => self.on_key_event_selection(key),
Screens::CreateMR => self.on_key_event_create_mr(key),
Screens::ReviewerSelection => self.on_key_event_select_reviewers(key),
Screens::Finalize => self.on_key_event_overview(key),
}
}
pub(crate) fn on_key_event_selection(&mut self, key: KeyEvent) {
match key.code {
KeyCode::Esc | KeyCode::Char('q') => {
self.quit();
}
KeyCode::Down | KeyCode::Char('j') => {
if !self.dirs.is_empty() {
self.selected_index = (self.selected_index + 1) % self.dirs.len();
}
}
KeyCode::Up | KeyCode::Char('k') => {
if !self.dirs.is_empty() {
if self.selected_index == 0 {
self.selected_index = self.dirs.len() - 1;
} else {
self.selected_index -= 1;
}
}
}
KeyCode::Char(' ') => {
if self.selected_repos.contains(&self.selected_index) {
self.selected_repos.remove(&self.selected_index);
} else {
self.selected_repos.insert(self.selected_index);
}
}
KeyCode::Enter => {
if !self.selected_repos.is_empty() {
self.screen = Screens::CreateMR;
}
}
_ => {}
}
}
pub(crate) fn on_key_event_create_mr(&mut self, key: KeyEvent) {
match key.code {
KeyCode::Tab => {
self.input_focus = match self.input_focus {
InputFocus::Title => InputFocus::Description,
InputFocus::Description => InputFocus::Label,
InputFocus::Label => InputFocus::Title,
};
}
KeyCode::Backspace => match self.input_focus {
InputFocus::Title => {
self.mr_title.pop();
}
InputFocus::Description => {
self.mr_description.pop();
}
InputFocus::Label => {}
},
KeyCode::Char(c) => match self.input_focus {
InputFocus::Title => self.mr_title.push(c),
InputFocus::Description => self.mr_description.push(c),
InputFocus::Label => match c {
'j' => {
if !self.config.labels.is_empty() {
let idx = self.selected_label;
self.selected_label = (idx + 1) % self.config.labels.len();
}
}
'k' => {
if !self.config.labels.is_empty() {
let idx = self.selected_label;
self.selected_label = if idx == 0 {
self.config.labels.len() - 1
} else {
idx - 1
};
}
}
_ => {}
},
},
KeyCode::Down => {
if self.input_focus == InputFocus::Label && !self.config.labels.is_empty() {
let idx = self.selected_label;
self.selected_label = (idx + 1) % self.config.labels.len();
}
}
KeyCode::Up => {
if self.input_focus == InputFocus::Label && !self.config.labels.is_empty() {
let idx = self.selected_label;
self.selected_label = if idx == 0 {
self.config.labels.len() - 1
} else {
idx - 1
};
}
}
KeyCode::Enter => {
self.screen = Screens::ReviewerSelection;
}
KeyCode::Esc => {
self.screen = Screens::RepoSelection;
}
_ => {}
}
}
pub(crate) fn on_key_event_select_reviewers(&mut self, key: KeyEvent) {
match key.code {
KeyCode::Down | KeyCode::Char('j') => {
if !self.config.reviewers.is_empty() {
self.reviewer_index = (self.reviewer_index + 1) % self.config.reviewers.len();
}
}
KeyCode::Up | KeyCode::Char('h') => {
if !self.config.reviewers.is_empty() {
if self.reviewer_index == 0 {
self.reviewer_index = self.config.reviewers.len() - 1;
} else {
self.reviewer_index -= 1;
}
}
}
KeyCode::Char(' ') => {
if self.selected_reviewers.contains(&self.reviewer_index) {
self.selected_reviewers.remove(&self.reviewer_index);
} else {
self.selected_reviewers.insert(self.reviewer_index);
}
}
KeyCode::Enter => {
self.screen = Screens::Finalize;
}
KeyCode::Esc => {
self.screen = Screens::CreateMR;
}
_ => {}
}
}
pub(crate) fn on_key_event_overview(&mut self, key: KeyEvent) {
match key.code {
KeyCode::Char('y') | KeyCode::Enter => {
self.mr = Some(merge_request::MergeRequest {
title: self.mr_title.clone(),
description: self.mr_description.clone(),
reviewers: self
.selected_reviewers
.iter()
.map(|&i| self.config.reviewers[i].clone())
.collect(),
labels: self
.config
.labels
.keys()
.nth(self.selected_label)
.map(|k| vec![k.clone()])
.unwrap_or_default(),
assignee: self.config.assignee.clone(),
});
self.quit_completed();
}
KeyCode::Char('n') | KeyCode::Esc => {
self.screen = Screens::ReviewerSelection;
}
_ => {}
}
}
}