@@ -44,6 +44,7 @@ have them configurable.
|
|||||||
* `s` opens a dialog to save the queue to a playlist
|
* `s` opens a dialog to save the queue to a playlist
|
||||||
* `F2`: Search
|
* `F2`: Search
|
||||||
* `F3`: Playlists
|
* `F3`: Playlists
|
||||||
|
* `d` deletes the currently selected playlist
|
||||||
* Tracks and playlists can be played using `Return` and queued using `Space`
|
* Tracks and playlists can be played using `Return` and queued using `Space`
|
||||||
* `Shift-p` toggles playback of a track
|
* `Shift-p` toggles playback of a track
|
||||||
* `Shift-s` stops a track
|
* `Shift-s` stops a track
|
||||||
|
|||||||
@@ -288,6 +288,16 @@ impl CommandManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if let Some(Some(dialog)) = s
|
||||||
|
.call_on_id("playlists", |v: &mut ui::playlists::PlaylistView| {
|
||||||
|
v.delete_dialog()
|
||||||
|
})
|
||||||
|
{
|
||||||
|
s.add_layer(dialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut layout = ui::layout::Layout::new(status, &event_manager, theme)
|
let mut layout = ui::layout::Layout::new(status, &event_manager, theme)
|
||||||
.view("search", search.with_id("search"), "Search")
|
.view("search", search.with_id("search"), "Search")
|
||||||
.view("playlists", playlistsview, "Playlists")
|
.view("playlists", playlistsview.with_id("playlists"), "Playlists")
|
||||||
.view("queue", queueview, "Queue");
|
.view("queue", queueview, "Queue");
|
||||||
|
|
||||||
// initial view is queue
|
// initial view is queue
|
||||||
|
|||||||
@@ -150,6 +150,16 @@ impl Playlists {
|
|||||||
store.len() - 1
|
store.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_playlist(&self, id: &str) {
|
||||||
|
let mut store = self.store.write().expect("can't writelock playlists");
|
||||||
|
if let Some(position) = store.iter().position(|ref i| i.meta.id == id) {
|
||||||
|
if self.spotify.delete_playlist(id) {
|
||||||
|
store.remove(position);
|
||||||
|
self.save_cache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn overwrite_playlist(&self, id: &str, tracks: &[Track]) {
|
pub fn overwrite_playlist(&self, id: &str, tracks: &[Track]) {
|
||||||
debug!("saving {} tracks to {}", tracks.len(), id);
|
debug!("saving {} tracks to {}", tracks.len(), id);
|
||||||
self.spotify.overwrite_playlist(id, &tracks);
|
self.spotify.overwrite_playlist(id, &tracks);
|
||||||
|
|||||||
@@ -404,6 +404,11 @@ impl Spotify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_playlist(&self, id: &str) -> bool {
|
||||||
|
self.api_with_retry(|api| api.user_playlist_unfollow(&self.user, id))
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_playlist(
|
pub fn create_playlist(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use cursive::traits::Identifiable;
|
use cursive::traits::Identifiable;
|
||||||
use cursive::view::ViewWrapper;
|
use cursive::view::ViewWrapper;
|
||||||
use cursive::views::IdView;
|
use cursive::views::{Dialog, IdView};
|
||||||
|
use cursive::Cursive;
|
||||||
|
|
||||||
use playlists::{Playlist, Playlists};
|
use playlists::{Playlist, Playlists};
|
||||||
use queue::Queue;
|
use queue::Queue;
|
||||||
use ui::listview::ListView;
|
use ui::listview::ListView;
|
||||||
|
use ui::modal::Modal;
|
||||||
|
|
||||||
pub struct PlaylistView {
|
pub struct PlaylistView {
|
||||||
list: IdView<ListView<Playlist>>,
|
list: IdView<ListView<Playlist>>,
|
||||||
|
playlists: Playlists,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const LIST_ID: &str = "playlist_list";
|
pub const LIST_ID: &str = "playlist_list";
|
||||||
@@ -17,7 +20,32 @@ impl PlaylistView {
|
|||||||
pub fn new(playlists: &Playlists, queue: Arc<Queue>) -> PlaylistView {
|
pub fn new(playlists: &Playlists, queue: Arc<Queue>) -> PlaylistView {
|
||||||
let list = ListView::new(playlists.store.clone(), queue).with_id(LIST_ID);
|
let list = ListView::new(playlists.store.clone(), queue).with_id(LIST_ID);
|
||||||
|
|
||||||
PlaylistView { list }
|
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.meta.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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user