Skip to content

Commit

Permalink
show album types in the artist context (#508)
Browse files Browse the repository at this point in the history
  • Loading branch information
aNNiMON authored Jul 19, 2024
1 parent 04f08f9 commit b812e58
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 33 deletions.
7 changes: 5 additions & 2 deletions spotify_player/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ pub fn handle_action_in_context(
if let Some(album) = track.album {
let context = ActionContext::Album(album.clone());
ui.popup = Some(PopupState::ActionList(
ActionListItem::Album(album, context.get_available_actions(data)),
Box::new(ActionListItem::Album(
album,
context.get_available_actions(data),
)),
new_list_state(),
));
}
Expand Down Expand Up @@ -424,7 +427,7 @@ fn handle_global_command(
let data = state.data.read();
let actions = command::construct_track_actions(&track, &data);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Track(track, actions),
Box::new(ActionListItem::Track(track, actions)),
new_list_state(),
));
}
Expand Down
4 changes: 2 additions & 2 deletions spotify_player/src/event/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn handle_key_sequence_for_popup(
construct_artist_actions(&artists[id], &data)
};
ui.popup = Some(PopupState::ActionList(
ActionListItem::Artist(artists[id].clone(), actions),
Box::new(ActionListItem::Artist(artists[id].clone(), actions)),
new_list_state(),
));
}
Expand Down Expand Up @@ -452,7 +452,7 @@ pub fn handle_item_action(
ui: &mut UIStateGuard,
) -> Result<()> {
let item = match ui.popup {
Some(PopupState::ActionList(ref item, ..)) => item.clone(),
Some(PopupState::ActionList(ref item, ..)) => *item.clone(),
_ => return Ok(()),
};

Expand Down
12 changes: 6 additions & 6 deletions spotify_player/src/event/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ fn handle_playlist_modify_command(
let mut actions = command::construct_track_actions(tracks[id], data);
actions.push(Action::DeleteFromPlaylist);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Track(tracks[id].clone(), actions),
Box::new(ActionListItem::Track(tracks[id].clone(), actions)),
new_list_state(),
));
return Ok(true);
Expand Down Expand Up @@ -324,7 +324,7 @@ fn handle_command_for_track_table_window(
Command::ShowActionsOnSelectedItem => {
let actions = command::construct_track_actions(filtered_tracks[id], data);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Track(tracks[id].clone(), actions),
Box::new(ActionListItem::Track(tracks[id].clone(), actions)),
new_list_state(),
));
}
Expand Down Expand Up @@ -368,7 +368,7 @@ pub fn handle_command_for_track_list_window(
Command::ShowActionsOnSelectedItem => {
let actions = command::construct_track_actions(tracks[id], data);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Track(tracks[id].clone(), actions),
Box::new(ActionListItem::Track(tracks[id].clone(), actions)),
new_list_state(),
));
}
Expand Down Expand Up @@ -406,7 +406,7 @@ pub fn handle_command_for_artist_list_window(
Command::ShowActionsOnSelectedItem => {
let actions = construct_artist_actions(artists[id], data);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Artist(artists[id].clone(), actions),
Box::new(ActionListItem::Artist(artists[id].clone(), actions)),
new_list_state(),
));
}
Expand Down Expand Up @@ -442,7 +442,7 @@ pub fn handle_command_for_album_list_window(
Command::ShowActionsOnSelectedItem => {
let actions = construct_album_actions(albums[id], data);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Album(albums[id].clone(), actions),
Box::new(ActionListItem::Album(albums[id].clone(), actions)),
new_list_state(),
));
}
Expand Down Expand Up @@ -480,7 +480,7 @@ pub fn handle_command_for_playlist_list_window(
Command::ShowActionsOnSelectedItem => {
let actions = construct_playlist_actions(playlists[id], data);
ui.popup = Some(PopupState::ActionList(
ActionListItem::Playlist(playlists[id].clone(), actions),
Box::new(ActionListItem::Playlist(playlists[id].clone(), actions)),
new_list_state(),
));
}
Expand Down
21 changes: 20 additions & 1 deletion spotify_player/src/state/model.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use rspotify::model as rspotify_model;
use rspotify::model::CurrentPlaybackContext;
pub use rspotify::model::{AlbumId, ArtistId, Id, PlaylistId, TrackId, UserId};
pub use rspotify::model::{AlbumId, AlbumType, ArtistId, Id, PlaylistId, TrackId, UserId};

use crate::utils::map_join;
use html_escape::decode_html_entities;
Expand Down Expand Up @@ -137,6 +137,7 @@ pub struct Album {
pub release_date: String,
pub name: String,
pub artists: Vec<Artist>,
pub album_type: Option<AlbumType>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
Expand Down Expand Up @@ -314,6 +315,15 @@ impl Album {
name: album.name,
release_date: album.release_date.unwrap_or_default(),
artists: from_simplified_artists_to_artists(album.artists),
album_type: album
.album_type
.and_then(|t| match t.to_ascii_lowercase().as_str() {
"album" => Some(AlbumType::Album),
"single" => Some(AlbumType::Single),
"appears_on" => Some(AlbumType::AppearsOn),
"compilation" => Some(AlbumType::Compilation),
_ => None,
}),
})
}

Expand All @@ -325,6 +335,14 @@ impl Album {
.unwrap_or("")
.to_string()
}

/// gets the album type
pub fn album_type(&self) -> String {
match self.album_type {
Some(t) => <&str>::from(t).to_string(),
_ => "".to_string(),
}
}
}

impl From<rspotify_model::FullAlbum> for Album {
Expand All @@ -334,6 +352,7 @@ impl From<rspotify_model::FullAlbum> for Album {
id: album.id,
release_date: album.release_date,
artists: from_simplified_artists_to_artists(album.artists),
album_type: Some(album.album_type),
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions spotify_player/src/state/ui/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub enum ContextPageUIState {
},
Artist {
top_track_table: TableState,
album_list: ListState,
album_table: TableState,
related_artist_list: ListState,
focus: ArtistFocusState,
},
Expand Down Expand Up @@ -200,12 +200,12 @@ impl PageState {
ContextPageUIState::Album { track_table } => MutableWindowState::Table(track_table),
ContextPageUIState::Artist {
top_track_table,
album_list,
album_table,
related_artist_list,
focus,
} => match focus {
ArtistFocusState::TopTracks => MutableWindowState::Table(top_track_table),
ArtistFocusState::Albums => MutableWindowState::List(album_list),
ArtistFocusState::Albums => MutableWindowState::Table(album_table),
ArtistFocusState::RelatedArtists => {
MutableWindowState::List(related_artist_list)
}
Expand Down Expand Up @@ -279,7 +279,7 @@ impl ContextPageUIState {
pub fn new_artist() -> Self {
Self::Artist {
top_track_table: utils::new_table_state(),
album_list: utils::new_list_state(),
album_table: utils::new_table_state(),
related_artist_list: utils::new_list_state(),
focus: ArtistFocusState::TopTracks,
}
Expand Down
2 changes: 1 addition & 1 deletion spotify_player/src/state/ui/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub enum PopupState {
DeviceList(ListState),
ArtistList(ArtistPopupAction, Vec<Artist>, ListState),
ThemeList(Vec<crate::config::Theme>, ListState),
ActionList(ActionListItem, ListState),
ActionList(Box<ActionListItem>, ListState),
PlaylistCreate {
name: LineInput,
desc: LineInput,
Expand Down
60 changes: 43 additions & 17 deletions spotify_player/src/ui/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ pub fn render_queue_page(

/// Render windows for an artist context page, which includes
/// - A top track table
/// - An album list
/// - An album table
/// - A related artist list
fn render_artist_context_page_windows(
is_active: bool,
Expand Down Expand Up @@ -731,19 +731,39 @@ fn render_artist_context_page_windows(
construct_and_render_block("Related Artists", &ui.theme, Borders::TOP, frame, chunks[1]);

// 3. Construct the page's widgets
// album list widget
let (album_list, n_albums) = {
let album_items = albums
.into_iter()
.map(|a| (format!("{1} • {0}", a.name, a.release_date), false))
.collect::<Vec<_>>();
// album table
let is_albums_active = is_active && focus_state == ArtistFocusState::Albums;
let n_albums = albums.len();
let album_rows = albums
.into_iter()
.map(|a| {
Row::new(vec![
Cell::from(a.release_date.clone()),
Cell::from(a.album_type()),
Cell::from(a.name.clone()),
])
.style(Style::default())
})
.collect::<Vec<_>>();

utils::construct_list_widget(
&ui.theme,
album_items,
is_active && focus_state == ArtistFocusState::Albums,
)
};
let albums_table = Table::new(
album_rows,
[
Constraint::Length(10),
Constraint::Length(6),
Constraint::Fill(1),
],
)
.header(
Row::new(vec![
Cell::from("Date"),
Cell::from("Type"),
Cell::from("Name"),
])
.style(ui.theme.table_header()),
)
.column_spacing(2)
.highlight_style(ui.theme.selection(is_albums_active));

// artist list widget
let (artist_list, n_artists) = {
Expand All @@ -770,20 +790,26 @@ fn render_artist_context_page_windows(
data,
);

let (album_list_state, artist_list_state) = match ui.current_page_mut() {
let (album_table_state, artist_list_state) = match ui.current_page_mut() {
PageState::Context {
state:
Some(ContextPageUIState::Artist {
album_list,
album_table,
related_artist_list,
..
}),
..
} => (album_list, related_artist_list),
} => (album_table, related_artist_list),
_ => return,
};

utils::render_list_window(frame, album_list, albums_rect, n_albums, album_list_state);
utils::render_table_window(
frame,
albums_table,
albums_rect,
n_albums,
album_table_state,
);
utils::render_list_window(
frame,
artist_list,
Expand Down

0 comments on commit b812e58

Please sign in to comment.