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))
|
.map(|id| format!("https://open.spotify.com/album/{}", id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn artist(&self) -> Option<Artist> {
|
fn artists(&self) -> Option<Vec<Artist>> {
|
||||||
Some(Artist::new(
|
Some(
|
||||||
self.artist_ids[0].clone(),
|
self.artist_ids
|
||||||
self.artists[0].clone(),
|
.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)
|
self.as_listitem().album(queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn artist(&self) -> Option<Artist> {
|
fn artists(&self) -> Option<Vec<Artist>> {
|
||||||
self.as_listitem().artist()
|
self.as_listitem().artists()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn track(&self) -> Option<Track> {
|
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> {
|
fn artists(&self) -> Option<Vec<Artist>> {
|
||||||
Some(Artist::new(
|
Some(
|
||||||
self.artist_ids[0].clone(),
|
self.artist_ids
|
||||||
self.artists[0].clone(),
|
.iter()
|
||||||
))
|
.zip(self.artists.iter())
|
||||||
|
.map(|(id, name)| Artist::new(id.clone(), name.clone()))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn track(&self) -> Option<Track> {
|
fn track(&self) -> Option<Track> {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub trait ListItem: Sync + Send + 'static {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn artist(&self) -> Option<Artist> {
|
fn artists(&self) -> Option<Vec<Artist>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use cursive::view::{Margins, ViewWrapper};
|
|||||||
use cursive::views::{Dialog, NamedView, ScrollView, SelectView};
|
use cursive::views::{Dialog, NamedView, ScrollView, SelectView};
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
|
|
||||||
use crate::commands::CommandResult;
|
|
||||||
use crate::library::Library;
|
use crate::library::Library;
|
||||||
use crate::playable::Playable;
|
use crate::playable::Playable;
|
||||||
use crate::queue::Queue;
|
use crate::queue::Queue;
|
||||||
@@ -14,6 +13,7 @@ use crate::track::Track;
|
|||||||
use crate::traits::{ListItem, ViewExt};
|
use crate::traits::{ListItem, ViewExt};
|
||||||
use crate::ui::layout::Layout;
|
use crate::ui::layout::Layout;
|
||||||
use crate::ui::modal::Modal;
|
use crate::ui::modal::Modal;
|
||||||
|
use crate::{artist::Artist, commands::CommandResult};
|
||||||
use crate::{
|
use crate::{
|
||||||
command::{Command, MoveAmount, MoveMode},
|
command::{Command, MoveAmount, MoveMode},
|
||||||
playlist::Playlist,
|
playlist::Playlist,
|
||||||
@@ -29,8 +29,13 @@ pub struct AddToPlaylistMenu {
|
|||||||
dialog: Modal<Dialog>,
|
dialog: Modal<Dialog>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SelectArtistMenu {
|
||||||
|
dialog: Modal<Dialog>,
|
||||||
|
}
|
||||||
|
|
||||||
enum ContextMenuAction {
|
enum ContextMenuAction {
|
||||||
ShowItem(Box<dyn ListItem>),
|
ShowItem(Box<dyn ListItem>),
|
||||||
|
SelectArtist(Box<Vec<Artist>>),
|
||||||
ShareUrl(String),
|
ShareUrl(String),
|
||||||
AddToPlaylist(Box<Track>),
|
AddToPlaylist(Box<Track>),
|
||||||
ShowRecommentations(Box<dyn ListItem>),
|
ShowRecommentations(Box<dyn ListItem>),
|
||||||
@@ -94,6 +99,36 @@ impl ContextMenu {
|
|||||||
.with_name("addtrackmenu")
|
.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 {
|
fn track_already_added() -> Dialog {
|
||||||
Dialog::text("This track is already in your playlist")
|
Dialog::text("This track is already in your playlist")
|
||||||
.title("Track already exists")
|
.title("Track already exists")
|
||||||
@@ -103,8 +138,19 @@ impl ContextMenu {
|
|||||||
|
|
||||||
pub fn new(item: &dyn ListItem, queue: Arc<Queue>, library: Arc<Library>) -> NamedView<Self> {
|
pub fn new(item: &dyn ListItem, queue: Arc<Queue>, library: Arc<Library>) -> NamedView<Self> {
|
||||||
let mut content: SelectView<ContextMenuAction> = SelectView::new();
|
let mut content: SelectView<ContextMenuAction> = SelectView::new();
|
||||||
if let Some(a) = item.artist() {
|
if let Some(a) = item.artists() {
|
||||||
content.add_item("Show artist", ContextMenuAction::ShowItem(Box::new(a)));
|
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()) {
|
if let Some(a) = item.album(queue.clone()) {
|
||||||
content.add_item("Show album", ContextMenuAction::ShowItem(Box::new(a)));
|
content.add_item("Show album", ContextMenuAction::ShowItem(Box::new(a)));
|
||||||
@@ -161,6 +207,10 @@ impl ContextMenu {
|
|||||||
let mut track: Track = *track.clone();
|
let mut track: Track = *track.clone();
|
||||||
track.toggle_saved(library);
|
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 {
|
impl ViewWrapper for ContextMenu {
|
||||||
wrap_impl!(self.dialog: Modal<Dialog>);
|
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 => {
|
GotoMode::Artist => {
|
||||||
if let Some(artist) = item.artist() {
|
if let Some(artists) = item.artists() {
|
||||||
let view =
|
return match artists.len() {
|
||||||
ArtistView::new(queue, library, &artist).as_boxed_view_ext();
|
0 => Ok(CommandResult::Consumed(None)),
|
||||||
return Ok(CommandResult::View(view));
|
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