use crossterm::event::{self, Event, KeyCode, KeyModifiers};
use crate::error::Error;
use super::*;
impl App {
pub(super) async fn handle_event(&mut self, event: Event) -> Result<(), Error> {
match event {
Event::Key(key) => {
if key.kind == event::KeyEventKind::Press {
self.handle_key(key).await
} else {
Ok(())
}
}
Event::Mouse(mouse) => self.handle_mouse(mouse).await,
Event::Resize(_, _) => {
if self.cava_parser.is_some() {
let state = self.state.read().await;
let td = state.settings_state.current_theme();
let g = td.cava_gradient.clone();
let h = td.cava_horizontal_gradient.clone();
let cs = state.settings_state.cava_size as u32;
drop(state);
self.start_cava(&g, &h, cs);
let mut state = self.state.write().await;
state.cava_screen.clear();
}
Ok(())
}
_ => Ok(()),
}
}
pub(super) async fn handle_key(&mut self, key: event::KeyEvent) -> Result<(), Error> {
let mut state = self.state.write().await;
state.clear_notification();
let is_server_text_field =
state.page == Page::Server && state.server_state.selected_field <= 2;
let is_filtering = state.page == Page::Artists && state.artists.filter_active
|| state.page == Page::Browse && state.browse.filter_active;
if (is_server_text_field && !matches!(key.code, KeyCode::F(_))) || is_filtering {
let page = state.page;
drop(state);
return match page {
Page::Server => self.handle_server_key(key).await,
Page::Artists => self.handle_artists_key(key).await,
Page::Browse => self.handle_browse_key(key).await,
_ => Ok(()),
};
}
match (key.code, key.modifiers) {
(KeyCode::Char('q'), KeyModifiers::NONE) => {
state.should_quit = true;
return Ok(());
}
(KeyCode::F(n), _) if (1..=7).contains(&n) => {
let visible_pages = state.visible_pages();
let Some(page) = visible_pages.get(n as usize - 1).copied() else {
return Ok(());
};
state.page = page;
let on_starred = state.browse.selected_option == Some(SongOption::Starred);
let browse_tab = state.browse.browse_tab.clone();
let refresh_songs = page == Page::Browse
&& on_starred
&& browse_tab == BrowseTab::Songs
&& state.browse.starred_songs_dirty;
let refresh_albums = page == Page::Browse
&& on_starred
&& browse_tab == BrowseTab::Albums
&& state.browse.starred_albums_dirty;
drop(state);
if refresh_songs {
self.get_starred_songs().await;
self.state.write().await.browse.starred_songs_dirty = false;
}
if refresh_albums {
self.get_starred_albums().await;
self.state.write().await.browse.starred_albums_dirty = false;
}
return Ok(());
}
(KeyCode::Char('p'), KeyModifiers::NONE) | (KeyCode::Char(' '), KeyModifiers::NONE) => {
if key.code == KeyCode::Char(' ') && state.page == Page::Radio {
drop(state);
return self.handle_radio_key(key).await;
}
drop(state);
return self.toggle_pause().await;
}
(KeyCode::Char('l'), KeyModifiers::NONE) => {
drop(state);
return self.next_track().await;
}
(KeyCode::Char('h'), KeyModifiers::NONE) => {
drop(state);
return self.prev_track().await;
}
(KeyCode::Char('H'), KeyModifiers::SHIFT) => {
drop(state);
let _ = self.mpv.seek_relative(-5.0);
return Ok(());
}
(KeyCode::Char('L'), KeyModifiers::SHIFT) => {
drop(state);
let _ = self.mpv.seek_relative(5.0);
return Ok(());
}
(KeyCode::Char('t'), KeyModifiers::NONE) => {
state.settings_state.next_theme();
state.config.theme = state.settings_state.theme_name().to_string();
let label = state.settings_state.theme_name().to_string();
state.notify(format!("Theme: {}", label));
let _ = state.config.save_default();
let cava_enabled = state.settings_state.cava_enabled;
let td = state.settings_state.current_theme();
let g = td.cava_gradient.clone();
let h = td.cava_horizontal_gradient.clone();
let cs = state.settings_state.cava_size as u32;
drop(state);
if cava_enabled {
self.start_cava(&g, &h, cs);
}
return Ok(());
}
(KeyCode::Char('r'), KeyModifiers::CONTROL) => {
state.notify("Refreshing...");
drop(state);
self.load_initial_data().await;
let mut state = self.state.write().await;
state.notify("Data refreshed");
return Ok(());
}
_ => {}
}
let page = state.page;
drop(state);
match page {
Page::Browse => self.handle_browse_key(key).await,
Page::Artists => self.handle_artists_key(key).await,
Page::Queue => self.handle_queue_key(key).await,
Page::Playlists => self.handle_playlists_key(key).await,
Page::Radio => self.handle_radio_key(key).await,
Page::Server => self.handle_server_key(key).await,
Page::Settings => self.handle_settings_key(key).await,
}
}
}