use super::common_key_events;
use crate::app::{ActiveBlock, App, ArtistBlock, RecommendationsContext, TrackTableContext};
use crate::event::Key;
use crate::network::IoEvent;
use rspotify::{model::PlayableId, prelude::*};
fn handle_down_press_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let next_index = common_key_events::on_down_press_handler(
&artist.top_tracks,
Some(artist.selected_top_track_index),
);
artist.selected_top_track_index = next_index;
}
ArtistBlock::Albums => {
let next_index = common_key_events::on_down_press_handler(
&artist.albums.items,
Some(artist.selected_album_index),
);
artist.selected_album_index = next_index;
}
ArtistBlock::RelatedArtists => {
let next_index = common_key_events::on_down_press_handler(
&artist.related_artists,
Some(artist.selected_related_artist_index),
);
artist.selected_related_artist_index = next_index;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_down_press_on_hovered_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_hovered_block {
ArtistBlock::TopTracks => {
artist.artist_hovered_block = ArtistBlock::Albums;
}
ArtistBlock::Albums => {
artist.artist_hovered_block = ArtistBlock::RelatedArtists;
}
ArtistBlock::RelatedArtists => {
artist.artist_hovered_block = ArtistBlock::TopTracks;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_up_press_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let next_index = common_key_events::on_up_press_handler(
&artist.top_tracks,
Some(artist.selected_top_track_index),
);
artist.selected_top_track_index = next_index;
}
ArtistBlock::Albums => {
let next_index = common_key_events::on_up_press_handler(
&artist.albums.items,
Some(artist.selected_album_index),
);
artist.selected_album_index = next_index;
}
ArtistBlock::RelatedArtists => {
let next_index = common_key_events::on_up_press_handler(
&artist.related_artists,
Some(artist.selected_related_artist_index),
);
artist.selected_related_artist_index = next_index;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_up_press_on_hovered_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_hovered_block {
ArtistBlock::TopTracks => {
artist.artist_hovered_block = ArtistBlock::RelatedArtists;
}
ArtistBlock::Albums => {
artist.artist_hovered_block = ArtistBlock::TopTracks;
}
ArtistBlock::RelatedArtists => {
artist.artist_hovered_block = ArtistBlock::Albums;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_high_press_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let next_index = common_key_events::on_high_press_handler();
artist.selected_top_track_index = next_index;
}
ArtistBlock::Albums => {
let next_index = common_key_events::on_high_press_handler();
artist.selected_album_index = next_index;
}
ArtistBlock::RelatedArtists => {
let next_index = common_key_events::on_high_press_handler();
artist.selected_related_artist_index = next_index;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_middle_press_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let next_index = common_key_events::on_middle_press_handler(&artist.top_tracks);
artist.selected_top_track_index = next_index;
}
ArtistBlock::Albums => {
let next_index = common_key_events::on_middle_press_handler(&artist.albums.items);
artist.selected_album_index = next_index;
}
ArtistBlock::RelatedArtists => {
let next_index = common_key_events::on_middle_press_handler(&artist.related_artists);
artist.selected_related_artist_index = next_index;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_low_press_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let next_index = common_key_events::on_low_press_handler(&artist.top_tracks);
artist.selected_top_track_index = next_index;
}
ArtistBlock::Albums => {
let next_index = common_key_events::on_low_press_handler(&artist.albums.items);
artist.selected_album_index = next_index;
}
ArtistBlock::RelatedArtists => {
let next_index = common_key_events::on_low_press_handler(&artist.related_artists);
artist.selected_related_artist_index = next_index;
}
ArtistBlock::Empty => {}
}
}
}
fn handle_recommend_event_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist.clone() {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let selected_index = artist.selected_top_track_index;
if let Some(track) = artist.top_tracks.get(selected_index) {
let track_id_list: Option<Vec<String>> =
track.id.as_ref().map(|id| vec![id.id().to_string()]);
app.recommendations_context = Some(RecommendationsContext::Song);
app.recommendations_seed = track.name.clone();
app.get_recommendations_for_seed(None, track_id_list, Some(track.clone()));
}
}
ArtistBlock::RelatedArtists => {
let selected_index = artist.selected_related_artist_index;
let artist_id = &artist.related_artists[selected_index].id;
let artist_name = &artist.related_artists[selected_index].name;
let artist_id_list: Option<Vec<String>> = Some(vec![artist_id.id().to_string()]);
app.recommendations_context = Some(RecommendationsContext::Artist);
app.recommendations_seed = artist_name.clone();
app.get_recommendations_for_seed(artist_id_list, None, None);
}
_ => {}
}
}
}
fn handle_enter_event_on_selected_block(app: &mut App) {
if let Some(artist) = &mut app.artist.clone() {
match artist.artist_selected_block {
ArtistBlock::TopTracks => {
let selected_index = artist.selected_top_track_index;
let top_tracks: Vec<PlayableId<'static>> = artist
.top_tracks
.iter()
.filter_map(|track| {
track
.id
.as_ref()
.map(|id| PlayableId::Track(id.clone().into_static()))
})
.collect();
app.dispatch(IoEvent::StartPlayback(
None,
Some(top_tracks),
Some(selected_index),
));
}
ArtistBlock::Albums => {
if let Some(selected_album) = artist
.albums
.items
.get(artist.selected_album_index)
.cloned()
{
app.track_table.context = Some(TrackTableContext::AlbumSearch);
app.dispatch(IoEvent::GetAlbumTracks(Box::new(selected_album)));
}
}
ArtistBlock::RelatedArtists => {
let selected_index = artist.selected_related_artist_index;
let artist_id = artist.related_artists[selected_index]
.id
.as_ref()
.into_static();
let artist_name = artist.related_artists[selected_index].name.clone();
app.get_artist(artist_id, artist_name);
}
ArtistBlock::Empty => {}
}
}
}
fn handle_enter_event_on_hovered_block(app: &mut App) {
if let Some(artist) = &mut app.artist {
match artist.artist_hovered_block {
ArtistBlock::TopTracks => artist.artist_selected_block = ArtistBlock::TopTracks,
ArtistBlock::Albums => artist.artist_selected_block = ArtistBlock::Albums,
ArtistBlock::RelatedArtists => artist.artist_selected_block = ArtistBlock::RelatedArtists,
ArtistBlock::Empty => {}
}
}
}
pub fn handler(key: Key, app: &mut App) {
if let Some(artist) = &mut app.artist {
match key {
Key::Esc => {
artist.artist_selected_block = ArtistBlock::Empty;
}
k if common_key_events::down_event(k) => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_down_press_on_selected_block(app);
} else {
handle_down_press_on_hovered_block(app);
}
}
k if common_key_events::up_event(k) => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_up_press_on_selected_block(app);
} else {
handle_up_press_on_hovered_block(app);
}
}
k if common_key_events::left_event(k) => {
artist.artist_selected_block = ArtistBlock::Empty;
match artist.artist_hovered_block {
ArtistBlock::TopTracks => common_key_events::handle_left_event(app),
ArtistBlock::Albums => {
artist.artist_hovered_block = ArtistBlock::TopTracks;
}
ArtistBlock::RelatedArtists => {
artist.artist_hovered_block = ArtistBlock::Albums;
}
ArtistBlock::Empty => {}
}
}
k if common_key_events::right_event(k) => {
artist.artist_selected_block = ArtistBlock::Empty;
handle_down_press_on_hovered_block(app);
}
k if common_key_events::high_event(k) => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_high_press_on_selected_block(app);
}
}
k if common_key_events::middle_event(k) => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_middle_press_on_selected_block(app);
}
}
k if common_key_events::low_event(k) => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_low_press_on_selected_block(app);
}
}
Key::Enter => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_enter_event_on_selected_block(app);
} else {
handle_enter_event_on_hovered_block(app);
}
}
Key::Char('r') => {
if artist.artist_selected_block != ArtistBlock::Empty {
handle_recommend_event_on_selected_block(app);
}
}
Key::Char('w') => match artist.artist_selected_block {
ArtistBlock::Albums => app.current_user_saved_album_add(ActiveBlock::ArtistBlock),
ArtistBlock::RelatedArtists => app.user_follow_artists(ActiveBlock::ArtistBlock),
_ => (),
},
Key::Char('D') => match artist.artist_selected_block {
ArtistBlock::Albums => app.current_user_saved_album_delete(ActiveBlock::ArtistBlock),
ArtistBlock::RelatedArtists => app.user_unfollow_artists(ActiveBlock::ArtistBlock),
_ => (),
},
_ if key == app.user_config.keys.add_item_to_queue => {
if let Some(artist) = &app.artist {
if let ArtistBlock::TopTracks = artist.artist_selected_block {
if let Some(track) = artist.top_tracks.get(artist.selected_top_track_index) {
if let Some(track_id) = &track.id {
app.dispatch(IoEvent::AddItemToQueue(PlayableId::Track(
track_id.clone().into_static(),
)));
}
};
}
}
}
_ => {}
};
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::app::ActiveBlock;
#[test]
fn on_esc() {
let mut app = App::default();
handler(Key::Esc, &mut app);
let current_route = app.get_current_route();
assert_eq!(current_route.active_block, ActiveBlock::Empty);
}
}