Add select artist dialog when multiple artists
This commit is contained in:
committed by
Henrik Friedrichsen
parent
68e51f263d
commit
2b20670743
13
src/album.rs
13
src/album.rs
@@ -248,10 +248,13 @@ impl ListItem for Album {
|
||||
.map(|id| format!("https://open.spotify.com/album/{}", id))
|
||||
}
|
||||
|
||||
fn artist(&self) -> Option<Artist> {
|
||||
Some(Artist::new(
|
||||
self.artist_ids[0].clone(),
|
||||
self.artists[0].clone(),
|
||||
))
|
||||
fn artists(&self) -> Option<Vec<Artist>> {
|
||||
Some(
|
||||
self.artist_ids
|
||||
.iter()
|
||||
.zip(self.artists.iter())
|
||||
.map(|(id, name)| Artist::new(id.clone(), name.clone()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,8 +120,8 @@ impl ListItem for Playable {
|
||||
self.as_listitem().album(queue)
|
||||
}
|
||||
|
||||
fn artist(&self) -> Option<Artist> {
|
||||
self.as_listitem().artist()
|
||||
fn artists(&self) -> Option<Vec<Artist>> {
|
||||
self.as_listitem().artists()
|
||||
}
|
||||
|
||||
fn track(&self) -> Option<Track> {
|
||||
|
||||
13
src/track.rs
13
src/track.rs
@@ -287,11 +287,14 @@ impl ListItem for Track {
|
||||
}
|
||||
}
|
||||
|
||||
fn artist(&self) -> Option<Artist> {
|
||||
Some(Artist::new(
|
||||
self.artist_ids[0].clone(),
|
||||
self.artists[0].clone(),
|
||||
))
|
||||
fn artists(&self) -> Option<Vec<Artist>> {
|
||||
Some(
|
||||
self.artist_ids
|
||||
.iter()
|
||||
.zip(self.artists.iter())
|
||||
.map(|(id, name)| Artist::new(id.clone(), name.clone()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn track(&self) -> Option<Track> {
|
||||
|
||||
@@ -39,7 +39,7 @@ pub trait ListItem: Sync + Send + 'static {
|
||||
None
|
||||
}
|
||||
|
||||
fn artist(&self) -> Option<Artist> {
|
||||
fn artists(&self) -> Option<Vec<Artist>> {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ use cursive::view::{Margins, ViewWrapper};
|
||||
use cursive::views::{Dialog, NamedView, ScrollView, SelectView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use crate::commands::CommandResult;
|
||||
use crate::library::Library;
|
||||
use crate::playable::Playable;
|
||||
use crate::queue::Queue;
|
||||
@@ -14,6 +13,7 @@ use crate::track::Track;
|
||||
use crate::traits::{ListItem, ViewExt};
|
||||
use crate::ui::layout::Layout;
|
||||
use crate::ui::modal::Modal;
|
||||
use crate::{artist::Artist, commands::CommandResult};
|
||||
use crate::{
|
||||
command::{Command, MoveAmount, MoveMode},
|
||||
playlist::Playlist,
|
||||
@@ -29,8 +29,13 @@ pub struct AddToPlaylistMenu {
|
||||
dialog: Modal<Dialog>,
|
||||
}
|
||||
|
||||
pub struct SelectArtistMenu {
|
||||
dialog: Modal<Dialog>,
|
||||
}
|
||||
|
||||
enum ContextMenuAction {
|
||||
ShowItem(Box<dyn ListItem>),
|
||||
SelectArtist(Box<Vec<Artist>>),
|
||||
ShareUrl(String),
|
||||
AddToPlaylist(Box<Track>),
|
||||
ShowRecommentations(Box<dyn ListItem>),
|
||||
@@ -94,6 +99,36 @@ impl ContextMenu {
|
||||
.with_name("addtrackmenu")
|
||||
}
|
||||
|
||||
pub fn select_artist_dialog(
|
||||
library: Arc<Library>,
|
||||
queue: Arc<Queue>,
|
||||
artists: Vec<Artist>,
|
||||
) -> NamedView<SelectArtistMenu> {
|
||||
let mut list_select = SelectView::<Artist>::new();
|
||||
|
||||
for artist in artists {
|
||||
list_select.add_item(artist.name.clone(), artist);
|
||||
}
|
||||
|
||||
list_select.set_on_submit(move |s, selected| {
|
||||
if let Some(view) = selected.open(queue.clone(), library.clone()) {
|
||||
s.call_on_name("main", move |v: &mut Layout| v.push_view(view));
|
||||
s.pop_layer();
|
||||
}
|
||||
});
|
||||
|
||||
let dialog = Dialog::new()
|
||||
.title("Select artist")
|
||||
.dismiss_button("Cancel")
|
||||
.padding(Margins::lrtb(1, 1, 1, 0))
|
||||
.content(ScrollView::new(list_select.with_name("artist_select")));
|
||||
|
||||
SelectArtistMenu {
|
||||
dialog: Modal::new_ext(dialog),
|
||||
}
|
||||
.with_name("selectartist")
|
||||
}
|
||||
|
||||
fn track_already_added() -> Dialog {
|
||||
Dialog::text("This track is already in your playlist")
|
||||
.title("Track already exists")
|
||||
@@ -103,8 +138,19 @@ impl ContextMenu {
|
||||
|
||||
pub fn new(item: &dyn ListItem, queue: Arc<Queue>, library: Arc<Library>) -> NamedView<Self> {
|
||||
let mut content: SelectView<ContextMenuAction> = SelectView::new();
|
||||
if let Some(a) = item.artist() {
|
||||
content.add_item("Show artist", ContextMenuAction::ShowItem(Box::new(a)));
|
||||
if let Some(a) = item.artists() {
|
||||
let action = match a.len() {
|
||||
0 => None,
|
||||
1 => Some(ContextMenuAction::ShowItem(Box::new(a[0].clone()))),
|
||||
_ => Some(ContextMenuAction::SelectArtist(Box::new(a))),
|
||||
};
|
||||
|
||||
if let Some(a) = action {
|
||||
content.add_item(
|
||||
"Show artist",
|
||||
a
|
||||
)
|
||||
}
|
||||
}
|
||||
if let Some(a) = item.album(queue.clone()) {
|
||||
content.add_item("Show album", ContextMenuAction::ShowItem(Box::new(a)));
|
||||
@@ -161,6 +207,10 @@ impl ContextMenu {
|
||||
let mut track: Track = *track.clone();
|
||||
track.toggle_saved(library);
|
||||
}
|
||||
ContextMenuAction::SelectArtist(artists) => {
|
||||
let dialog = Self::select_artist_dialog(library, queue, *artists.clone());
|
||||
s.add_layer(dialog);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -232,3 +282,7 @@ impl ViewWrapper for AddToPlaylistMenu {
|
||||
impl ViewWrapper for ContextMenu {
|
||||
wrap_impl!(self.dialog: Modal<Dialog>);
|
||||
}
|
||||
|
||||
impl ViewWrapper for SelectArtistMenu {
|
||||
wrap_impl!(self.dialog: Modal<Dialog>);
|
||||
}
|
||||
|
||||
@@ -617,10 +617,22 @@ impl<I: ListItem + Clone> ViewExt for ListView<I> {
|
||||
}
|
||||
}
|
||||
GotoMode::Artist => {
|
||||
if let Some(artist) = item.artist() {
|
||||
let view =
|
||||
ArtistView::new(queue, library, &artist).as_boxed_view_ext();
|
||||
return Ok(CommandResult::View(view));
|
||||
if let Some(artists) = item.artists() {
|
||||
return match artists.len() {
|
||||
0 => Ok(CommandResult::Consumed(None)),
|
||||
1 => {
|
||||
let view = ArtistView::new(queue, library, &artists[0]).as_boxed_view_ext();
|
||||
Ok(CommandResult::View(view))
|
||||
}
|
||||
_ => {
|
||||
let dialog = ContextMenu::select_artist_dialog(
|
||||
library, queue, artists,
|
||||
);
|
||||
_s.add_layer(dialog);
|
||||
|
||||
Ok(CommandResult::Consumed(None))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user