Implement saved tracks, albums, and artists
This commit is contained in:
79
src/ui/library.rs
Normal file
79
src/ui/library.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use cursive::view::ViewWrapper;
|
||||
use cursive::views::Dialog;
|
||||
use cursive::Cursive;
|
||||
|
||||
use commands::CommandResult;
|
||||
use library::Library;
|
||||
use queue::Queue;
|
||||
use traits::ViewExt;
|
||||
use ui::listview::ListView;
|
||||
use ui::modal::Modal;
|
||||
use ui::tabview::TabView;
|
||||
|
||||
pub struct LibraryView {
|
||||
list: TabView,
|
||||
library: Arc<Library>,
|
||||
}
|
||||
|
||||
impl LibraryView {
|
||||
pub fn new(queue: Arc<Queue>, library: Arc<Library>) -> Self {
|
||||
let tabs = TabView::new()
|
||||
.tab("tracks", "Tracks", ListView::new(library.tracks.clone(), queue.clone()))
|
||||
.tab("albums", "Albums", ListView::new(library.albums.clone(), queue.clone()))
|
||||
.tab("artists", "Artists", ListView::new(library.artists.clone(), queue.clone()))
|
||||
.tab("playlists", "Playlists", ListView::new(library.playlists.clone(), queue.clone()));
|
||||
|
||||
Self {
|
||||
list: tabs,
|
||||
library,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete_dialog(&mut self) -> Option<Modal<Dialog>> {
|
||||
return None;
|
||||
|
||||
// TODO
|
||||
//let store = self.library.items();
|
||||
//let current = store.get(self.list.get_selected_index());
|
||||
|
||||
//if let Some(playlist) = current {
|
||||
// let library = self.library.clone();
|
||||
// let id = playlist.id.clone();
|
||||
// let dialog = Dialog::text("Are you sure you want to delete this playlist?")
|
||||
// .padding((1, 1, 1, 0))
|
||||
// .title("Delete playlist")
|
||||
// .dismiss_button("No")
|
||||
// .button("Yes", move |s: &mut Cursive| {
|
||||
// library.delete_playlist(&id);
|
||||
// s.pop_layer();
|
||||
// });
|
||||
// Some(Modal::new(dialog))
|
||||
//} else {
|
||||
// None
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewWrapper for LibraryView {
|
||||
wrap_impl!(self.list: TabView);
|
||||
}
|
||||
|
||||
impl ViewExt for LibraryView {
|
||||
fn on_command(
|
||||
&mut self,
|
||||
s: &mut Cursive,
|
||||
cmd: &str,
|
||||
args: &[String],
|
||||
) -> Result<CommandResult, String> {
|
||||
if cmd == "delete" {
|
||||
if let Some(dialog) = self.delete_dialog() {
|
||||
s.add_layer(dialog);
|
||||
}
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
|
||||
self.list.on_command(s, cmd, args)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod layout;
|
||||
pub mod library;
|
||||
pub mod listview;
|
||||
pub mod modal;
|
||||
pub mod playlists;
|
||||
pub mod queue;
|
||||
pub mod search;
|
||||
pub mod statusbar;
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use cursive::traits::Identifiable;
|
||||
use cursive::view::ViewWrapper;
|
||||
use cursive::views::{Dialog, IdView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use commands::CommandResult;
|
||||
use playlists::{Playlist, Playlists};
|
||||
use queue::Queue;
|
||||
use traits::ViewExt;
|
||||
use ui::listview::ListView;
|
||||
use ui::modal::Modal;
|
||||
|
||||
pub struct PlaylistView {
|
||||
list: IdView<ListView<Playlist>>,
|
||||
playlists: Playlists,
|
||||
}
|
||||
|
||||
pub const LIST_ID: &str = "playlist_list";
|
||||
impl PlaylistView {
|
||||
pub fn new(playlists: &Playlists, queue: Arc<Queue>) -> PlaylistView {
|
||||
let list = ListView::new(playlists.store.clone(), queue).with_id(LIST_ID);
|
||||
|
||||
PlaylistView {
|
||||
list,
|
||||
playlists: playlists.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete_dialog(&mut self) -> Option<Modal<Dialog>> {
|
||||
let list = self.list.get_mut();
|
||||
let store = self.playlists.items();
|
||||
let current = store.get(list.get_selected_index());
|
||||
|
||||
if let Some(playlist) = current {
|
||||
let playlists = self.playlists.clone();
|
||||
let id = playlist.id.clone();
|
||||
let dialog = Dialog::text("Are you sure you want to delete this playlist?")
|
||||
.padding((1, 1, 1, 0))
|
||||
.title("Delete playlist")
|
||||
.dismiss_button("No")
|
||||
.button("Yes", move |s: &mut Cursive| {
|
||||
playlists.delete_playlist(&id);
|
||||
s.pop_layer();
|
||||
});
|
||||
Some(Modal::new(dialog))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewWrapper for PlaylistView {
|
||||
wrap_impl!(self.list: IdView<ListView<Playlist>>);
|
||||
}
|
||||
|
||||
impl ViewExt for PlaylistView {
|
||||
fn on_command(
|
||||
&mut self,
|
||||
s: &mut Cursive,
|
||||
cmd: &str,
|
||||
args: &[String],
|
||||
) -> Result<CommandResult, String> {
|
||||
if cmd == "delete" {
|
||||
if let Some(dialog) = self.delete_dialog() {
|
||||
s.add_layer(dialog);
|
||||
}
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
|
||||
self.list.on_command(s, cmd, args)
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use std::cmp::min;
|
||||
use std::sync::Arc;
|
||||
|
||||
use commands::CommandResult;
|
||||
use playlists::Playlists;
|
||||
use library::Library;
|
||||
use queue::Queue;
|
||||
use track::Track;
|
||||
use traits::ViewExt;
|
||||
@@ -17,17 +17,17 @@ use ui::modal::Modal;
|
||||
|
||||
pub struct QueueView {
|
||||
list: ListView<Track>,
|
||||
playlists: Arc<Playlists>,
|
||||
library: Arc<Library>,
|
||||
queue: Arc<Queue>,
|
||||
}
|
||||
|
||||
impl QueueView {
|
||||
pub fn new(queue: Arc<Queue>, playlists: Arc<Playlists>) -> QueueView {
|
||||
pub fn new(queue: Arc<Queue>, library: Arc<Library>) -> QueueView {
|
||||
let list = ListView::new(queue.queue.clone(), queue.clone());
|
||||
|
||||
QueueView {
|
||||
list,
|
||||
playlists,
|
||||
library,
|
||||
queue,
|
||||
}
|
||||
}
|
||||
@@ -35,20 +35,20 @@ impl QueueView {
|
||||
fn save_dialog_cb(
|
||||
s: &mut Cursive,
|
||||
queue: Arc<Queue>,
|
||||
playlists: Arc<Playlists>,
|
||||
library: Arc<Library>,
|
||||
id: Option<String>,
|
||||
) {
|
||||
let tracks = queue.queue.read().unwrap().clone();
|
||||
match id {
|
||||
Some(id) => {
|
||||
playlists.overwrite_playlist(&id, &tracks);
|
||||
library.overwrite_playlist(&id, &tracks);
|
||||
s.pop_layer();
|
||||
}
|
||||
None => {
|
||||
s.pop_layer();
|
||||
let edit = EditView::new()
|
||||
.on_submit(move |s: &mut Cursive, name| {
|
||||
playlists.save_playlist(name, &tracks);
|
||||
library.save_playlist(name, &tracks);
|
||||
s.pop_layer();
|
||||
})
|
||||
.with_id("name")
|
||||
@@ -63,16 +63,16 @@ impl QueueView {
|
||||
}
|
||||
}
|
||||
|
||||
fn save_dialog(queue: Arc<Queue>, playlists: Arc<Playlists>) -> Modal<Dialog> {
|
||||
fn save_dialog(queue: Arc<Queue>, library: Arc<Library>) -> Modal<Dialog> {
|
||||
let mut list_select: SelectView<Option<String>> = SelectView::new().autojump();
|
||||
list_select.add_item("[Create new]", None);
|
||||
|
||||
for list in playlists.items().iter() {
|
||||
for list in library.items().iter() {
|
||||
list_select.add_item(list.name.clone(), Some(list.id.clone()));
|
||||
}
|
||||
|
||||
list_select.set_on_submit(move |s, selected| {
|
||||
Self::save_dialog_cb(s, queue.clone(), playlists.clone(), selected.clone())
|
||||
Self::save_dialog_cb(s, queue.clone(), library.clone(), selected.clone())
|
||||
});
|
||||
|
||||
let dialog = Dialog::new()
|
||||
@@ -92,9 +92,9 @@ impl ViewWrapper for QueueView {
|
||||
Event::Char('s') => {
|
||||
debug!("save list");
|
||||
let queue = self.queue.clone();
|
||||
let playlists = self.playlists.clone();
|
||||
let library = self.library.clone();
|
||||
let cb = move |s: &mut Cursive| {
|
||||
let dialog = Self::save_dialog(queue.clone(), playlists.clone());
|
||||
let dialog = Self::save_dialog(queue.clone(), library.clone());
|
||||
s.add_layer(dialog)
|
||||
};
|
||||
EventResult::Consumed(Some(Callback::from_fn(cb)))
|
||||
|
||||
@@ -13,7 +13,8 @@ use album::Album;
|
||||
use artist::Artist;
|
||||
use commands::CommandResult;
|
||||
use events::EventManager;
|
||||
use playlists::{Playlist, Playlists};
|
||||
use library::Library;
|
||||
use playlist::Playlist;
|
||||
use queue::Queue;
|
||||
use spotify::{Spotify, URIType};
|
||||
use track::Track;
|
||||
@@ -218,7 +219,7 @@ impl SearchView {
|
||||
_append: bool,
|
||||
) -> u32 {
|
||||
if let Some(results) = spotify.playlist(&query) {
|
||||
let pls = vec![Playlists::process_full_playlist(&results, &&spotify)];
|
||||
let pls = vec![Library::process_full_playlist(&results, &&spotify)];
|
||||
let mut r = playlists.write().unwrap();
|
||||
*r = pls;
|
||||
return 1;
|
||||
@@ -238,7 +239,7 @@ impl SearchView {
|
||||
.playlists
|
||||
.items
|
||||
.iter()
|
||||
.map(|sp| Playlists::process_simplified_playlist(sp, &&spotify))
|
||||
.map(|sp| Library::process_simplified_playlist(sp, &&spotify))
|
||||
.collect();
|
||||
let mut r = playlists.write().unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user