Merge pull request #13 from felipesere/develop
Implement basic playlist that simply queues songs
This commit is contained in:
@@ -36,6 +36,7 @@ have them configurable.
|
|||||||
* `F1`: Debug log
|
* `F1`: Debug log
|
||||||
* `F2`: Queue
|
* `F2`: Queue
|
||||||
* `F3`: Search
|
* `F3`: Search
|
||||||
|
* `F4`: Playlists, then hit `Return` to queue all songs from the playlist
|
||||||
* Tracks can be played using `Return` and queued using `Space`
|
* Tracks 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
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ fn main() {
|
|||||||
let search = ui::search::SearchView::new(spotify.clone(), queue.clone());
|
let search = ui::search::SearchView::new(spotify.clone(), queue.clone());
|
||||||
cursive.add_fullscreen_layer(search.view);
|
cursive.add_fullscreen_layer(search.view);
|
||||||
|
|
||||||
|
let playlistscreen = cursive.add_active_screen();
|
||||||
|
let playlists = ui::playlist::PlaylistView::new(queue.clone(), spotify.clone());
|
||||||
|
cursive.add_fullscreen_layer(playlists.view);
|
||||||
|
|
||||||
let queuescreen = cursive.add_active_screen();
|
let queuescreen = cursive.add_active_screen();
|
||||||
let mut queueview = ui::queue::QueueView::new(queue.clone(), spotify.clone());
|
let mut queueview = ui::queue::QueueView::new(queue.clone(), spotify.clone());
|
||||||
cursive.add_fullscreen_layer(queueview.view.take().unwrap());
|
cursive.add_fullscreen_layer(queueview.view.take().unwrap());
|
||||||
@@ -157,6 +161,10 @@ fn main() {
|
|||||||
s.set_screen(searchscreen);
|
s.set_screen(searchscreen);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cursive.add_global_callback(Key::F4, move |s| {
|
||||||
|
s.set_screen(playlistscreen);
|
||||||
|
});
|
||||||
|
|
||||||
// cursive event loop
|
// cursive event loop
|
||||||
while cursive.is_running() {
|
while cursive.is_running() {
|
||||||
cursive.step();
|
cursive.step();
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ use librespot::playback::player::Player;
|
|||||||
|
|
||||||
use rspotify::spotify::client::Spotify as SpotifyAPI;
|
use rspotify::spotify::client::Spotify as SpotifyAPI;
|
||||||
use rspotify::spotify::model::search::SearchTracks;
|
use rspotify::spotify::model::search::SearchTracks;
|
||||||
|
use rspotify::spotify::model::playlist::{SimplifiedPlaylist, PlaylistTrack};
|
||||||
|
use rspotify::spotify::model::page::Page;
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
|
||||||
@@ -49,6 +51,7 @@ pub struct Spotify {
|
|||||||
pub api: SpotifyAPI,
|
pub api: SpotifyAPI,
|
||||||
channel: mpsc::UnboundedSender<WorkerCommand>,
|
channel: mpsc::UnboundedSender<WorkerCommand>,
|
||||||
events: EventManager,
|
events: EventManager,
|
||||||
|
user: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Worker {
|
struct Worker {
|
||||||
@@ -184,6 +187,7 @@ impl Spotify {
|
|||||||
api: api,
|
api: api,
|
||||||
channel: tx,
|
channel: tx,
|
||||||
events: events,
|
events: events,
|
||||||
|
user: user,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +227,14 @@ impl Spotify {
|
|||||||
self.api.search_track(query, limit, offset, None)
|
self.api.search_track(query, limit, offset, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_user_playlist(&self, limit: u32, offset: u32) -> Result<Page<SimplifiedPlaylist>, Error> {
|
||||||
|
self.api.current_user_playlists(limit, offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user_playlist_tracks(&self, playlist_id: &str) -> Result<Page<PlaylistTrack>, Error> {
|
||||||
|
self.api.user_playlist_tracks(&self.user, playlist_id, None, 50, 0, None)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load(&self, track: SpotifyId) {
|
pub fn load(&self, track: SpotifyId) {
|
||||||
info!("loading track: {:?}", track);
|
info!("loading track: {:?}", track);
|
||||||
self.channel
|
self.channel
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod queue;
|
pub mod queue;
|
||||||
pub mod search;
|
pub mod search;
|
||||||
pub mod trackbutton;
|
pub mod trackbutton;
|
||||||
|
pub mod playlist;
|
||||||
|
|||||||
42
src/ui/playlist.rs
Normal file
42
src/ui/playlist.rs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use cursive::direction::Orientation;
|
||||||
|
use cursive::traits::Boxable;
|
||||||
|
use cursive::views::*;
|
||||||
|
|
||||||
|
use spotify::Spotify;
|
||||||
|
use queue::Queue;
|
||||||
|
|
||||||
|
pub struct PlaylistView {
|
||||||
|
pub view: Panel<LinearLayout>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlaylistView {
|
||||||
|
pub fn new(queue: Arc<Mutex<Queue>>, spotify: Arc<Spotify>) -> PlaylistView {
|
||||||
|
let mut results = SelectView::new();
|
||||||
|
let playlists = spotify.current_user_playlist(50, 0).unwrap().items;
|
||||||
|
|
||||||
|
for playlist in &playlists {
|
||||||
|
results.add_item(playlist.name.clone(), playlist.id.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let spotify_ref = spotify.clone();
|
||||||
|
results.set_on_submit(move |_s, id| {
|
||||||
|
let tracks = spotify_ref.user_playlist_tracks(id).unwrap().items;
|
||||||
|
|
||||||
|
let mut l_queue = queue.lock().expect("Could not aquire lock");
|
||||||
|
for playlist_track in tracks {
|
||||||
|
l_queue.enqueue(playlist_track.track.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let scrollable = ScrollView::new(results).full_width().full_height();
|
||||||
|
let layout = LinearLayout::new(Orientation::Vertical).child(scrollable);
|
||||||
|
let rootpanel = Panel::new(layout).title("Playlists");
|
||||||
|
|
||||||
|
PlaylistView {
|
||||||
|
view: rootpanel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user