use crate::action::Action;
use crate::app::InputMode;
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers};
use std::time::Duration;
pub fn poll_action(timeout: Duration, mode: &InputMode) -> Option<Action> {
if event::poll(timeout).ok()? {
if let Event::Key(key) = event::read().ok()? {
return map_key(key, mode);
}
}
None
}
fn map_key(key: KeyEvent, mode: &InputMode) -> Option<Action> {
if key.kind != crossterm::event::KeyEventKind::Press {
return None;
}
match mode {
InputMode::Normal => map_normal(key),
InputMode::Search => map_search(key),
}
}
fn map_normal(key: KeyEvent) -> Option<Action> {
match (key.modifiers, key.code) {
(_, KeyCode::Char('q')) => Some(Action::Quit),
(_, KeyCode::Esc) => Some(Action::Quit),
(KeyModifiers::CONTROL, KeyCode::Char('c')) => Some(Action::Quit),
(_, KeyCode::Char('/')) => Some(Action::EnterSearch),
(KeyModifiers::CONTROL, KeyCode::Char('f')) => Some(Action::EnterSearch),
(_, KeyCode::Up) | (_, KeyCode::Char('k')) => Some(Action::PrevStation),
(_, KeyCode::Down) | (_, KeyCode::Char('j')) => Some(Action::NextStation),
(_, KeyCode::Enter) => Some(Action::PlaySelected),
(_, KeyCode::Char(' ')) => Some(Action::TogglePause),
(_, KeyCode::Char('s')) => Some(Action::Stop),
(_, KeyCode::Char('+')) | (_, KeyCode::Char('=')) => Some(Action::VolumeUp),
(_, KeyCode::Char('-')) => Some(Action::VolumeDown),
(_, KeyCode::Char('m')) => Some(Action::ToggleMute),
(_, KeyCode::Char('f')) => Some(Action::ToggleFavorite),
(_, KeyCode::Tab) => Some(Action::NextGenre),
(_, KeyCode::BackTab) => Some(Action::PrevGenre),
(_, KeyCode::Char('?')) | (_, KeyCode::Char('h')) => Some(Action::ToggleHelp),
(_, KeyCode::Char('b')) => Some(Action::CycleLayout),
(_, KeyCode::Char('p')) => Some(Action::NextDeckPage),
(_, KeyCode::Char('v')) => Some(Action::ToggleVisualizerMode),
(_, KeyCode::Char(',')) => Some(Action::ToggleSettings),
(_, KeyCode::Char('r')) => Some(Action::ToggleRecording),
_ => None,
}
}
fn map_search(key: KeyEvent) -> Option<Action> {
match (key.modifiers, key.code) {
(_, KeyCode::Esc) => Some(Action::ExitSearch),
(_, KeyCode::Enter) => Some(Action::SearchConfirm),
(_, KeyCode::Up) => Some(Action::PrevStation),
(_, KeyCode::Down) => Some(Action::NextStation),
(_, KeyCode::Backspace) => Some(Action::SearchBackspace),
(KeyModifiers::CONTROL, KeyCode::Char('c')) => Some(Action::Quit),
(_, KeyCode::Char(c)) => Some(Action::SearchInput(c)),
_ => None,
}
}