From 83a394790f8a62a8bb85403b47ec51fe3fdc1e0e Mon Sep 17 00:00:00 2001 From: Henrik Friedrichsen Date: Tue, 26 Mar 2019 22:24:20 +0100 Subject: [PATCH] implement deletion of playlists closes #11 --- README.md | 1 + src/commands.rs | 10 ++++++++++ src/main.rs | 2 +- src/playlists.rs | 10 ++++++++++ src/spotify.rs | 5 +++++ src/ui/playlists.rs | 32 ++++++++++++++++++++++++++++++-- 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aacaa16..d6418c7 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ have them configurable. * `s` opens a dialog to save the queue to a playlist * `F2`: Search * `F3`: Playlists + * `d` deletes the currently selected playlist * Tracks and playlists can be played using `Return` and queued using `Space` * `Shift-p` toggles playback of a track * `Shift-s` stops a track diff --git a/src/commands.rs b/src/commands.rs index 10879bb..0d58040 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -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) }), ); diff --git a/src/main.rs b/src/main.rs index 9a54419..7df333b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -160,7 +160,7 @@ fn main() { let mut layout = ui::layout::Layout::new(status, &event_manager, theme) .view("search", search.with_id("search"), "Search") - .view("playlists", playlistsview, "Playlists") + .view("playlists", playlistsview.with_id("playlists"), "Playlists") .view("queue", queueview, "Queue"); // initial view is queue diff --git a/src/playlists.rs b/src/playlists.rs index d1d2c8d..897ce3f 100644 --- a/src/playlists.rs +++ b/src/playlists.rs @@ -150,6 +150,16 @@ impl Playlists { 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]) { debug!("saving {} tracks to {}", tracks.len(), id); self.spotify.overwrite_playlist(id, &tracks); diff --git a/src/spotify.rs b/src/spotify.rs index c3fa5f0..f5b9c17 100644 --- a/src/spotify.rs +++ b/src/spotify.rs @@ -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( &self, name: &str, diff --git a/src/ui/playlists.rs b/src/ui/playlists.rs index 753bc5b..eafceac 100644 --- a/src/ui/playlists.rs +++ b/src/ui/playlists.rs @@ -2,14 +2,17 @@ use std::sync::Arc; use cursive::traits::Identifiable; use cursive::view::ViewWrapper; -use cursive::views::IdView; +use cursive::views::{Dialog, IdView}; +use cursive::Cursive; use playlists::{Playlist, Playlists}; use queue::Queue; use ui::listview::ListView; +use ui::modal::Modal; pub struct PlaylistView { list: IdView>, + playlists: Playlists, } pub const LIST_ID: &str = "playlist_list"; @@ -17,7 +20,32 @@ impl PlaylistView { pub fn new(playlists: &Playlists, queue: Arc) -> PlaylistView { 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> { + 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 + } } }