use scrollview in linearlayout for playlist items

this approach is more flexible for future additions, e.g. further callbacks such
as playlist deletion.
This commit is contained in:
Henrik Friedrichsen
2019-03-04 19:13:39 +01:00
parent 7d948707fe
commit 92811a2ce3
4 changed files with 45 additions and 29 deletions

View File

@@ -37,8 +37,8 @@ mod theme;
mod ui;
use events::{Event, EventManager};
use ui::playlist::PlaylistEvent;
use queue::QueueChange;
use ui::playlist::PlaylistEvent;
fn init_logger(content: TextContent) {
let mut builder = env_logger::Builder::from_default_env();

View File

@@ -11,9 +11,9 @@ use librespot::playback::config::Bitrate;
use librespot::playback::player::Player;
use rspotify::spotify::client::Spotify as SpotifyAPI;
use rspotify::spotify::model::search::SearchTracks;
use rspotify::spotify::model::playlist::{SimplifiedPlaylist, PlaylistTrack};
use rspotify::spotify::model::page::Page;
use rspotify::spotify::model::playlist::{PlaylistTrack, SimplifiedPlaylist};
use rspotify::spotify::model::search::SearchTracks;
use failure::Error;
@@ -227,12 +227,17 @@ impl Spotify {
self.api.search_track(query, limit, offset, None)
}
pub fn current_user_playlist(&self, limit: u32, offset: u32) -> Result<Page<SimplifiedPlaylist>, Error> {
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)
self.api
.user_playlist_tracks(&self.user, playlist_id, None, 50, 0, None)
}
pub fn load(&self, track: SpotifyId) {

View File

@@ -1,4 +1,4 @@
pub mod playlist;
pub mod queue;
pub mod search;
pub mod trackbutton;
pub mod playlist;

View File

@@ -1,70 +1,81 @@
use std::sync::{Arc, Mutex};
use cursive::traits::Identifiable;
use cursive::direction::Orientation;
use cursive::traits::Boxable;
use cursive::traits::Identifiable;
use cursive::views::*;
use cursive::Cursive;
use rspotify::spotify::model::playlist::{SimplifiedPlaylist};
use spotify::Spotify;
use queue::Queue;
use spotify::Spotify;
pub enum PlaylistEvent {
Refresh,
}
pub struct PlaylistView {
pub view: Option<Panel<LinearLayout>>,
pub view: Option<Panel<BoxView<BoxView<ScrollView<IdView<LinearLayout>>>>>>, // FIXME: wow
queue: Arc<Mutex<Queue>>,
spotify: Arc<Spotify>,
}
impl PlaylistView {
pub fn new(queue: Arc<Mutex<Queue>>, spotify: Arc<Spotify>) -> PlaylistView {
let playlist_overview: IdView<SelectView> = SelectView::new().with_id("playlists_overview");
let scrollable = ScrollView::new(playlist_overview).full_width().full_height();
let layout = LinearLayout::new(Orientation::Vertical).child(scrollable);
let rootpanel = Panel::new(layout).title("Playlists");
let playlists = LinearLayout::new(Orientation::Vertical).with_id("playlists");
let scrollable = ScrollView::new(playlists).full_width().full_height();
let panel = Panel::new(scrollable).title("Playlists");
PlaylistView {
view: Some(rootpanel),
view: Some(panel),
queue: queue,
spotify: spotify,
}
}
fn clear_playlists(&self, playlist_overview: &mut ViewRef<SelectView>) {
playlist_overview.clear();
fn clear_playlists(&self, playlists: &mut ViewRef<LinearLayout>) {
while playlists.len() > 0 {
playlists.remove_child(0);
}
}
fn show_playlists(&self, playlist_overview: &mut ViewRef<SelectView>) {
let playlists = self.spotify.current_user_playlist(50, 0).unwrap().items;
for playlist in &playlists {
playlist_overview.add_item(playlist.name.clone(), playlist.id.clone());
}
fn create_button(&self, playlist: &SimplifiedPlaylist) -> BoxView<Button> {
let spotify_ref = self.spotify.clone();
let queue_ref = self.queue.clone();
playlist_overview.set_on_submit(move |_s, id| {
let tracks = spotify_ref.user_playlist_tracks(id).unwrap().items;
// TODO: implement a custom view that displays playlists similar to
// TrackButton with more detail, e.g. number of tracks, total duration.
let id = playlist.id.clone();
let button = Button::new_raw(playlist.name.clone(), move |_s| {
let tracks = spotify_ref.user_playlist_tracks(&id).unwrap().items;
let mut locked_queue = queue_ref.lock().expect("Could not aquire lock");
for playlist_track in tracks {
locked_queue.enqueue(playlist_track.track.clone());
}
});
button
}
fn show_playlists(&self, playlists: &mut ViewRef<LinearLayout>) {
let playlists_response = self.spotify.current_user_playlist(50, 0).unwrap().items;
for playlist in &playlists_response {
let button = self.create_button(playlist);
playlists.add_child(button);
}
}
pub fn handle_ev(&self, cursive: &mut Cursive, event: PlaylistEvent) {
let view_ref: Option<ViewRef<SelectView>> = cursive.find_id("playlists_overview");
let view_ref: Option<ViewRef<LinearLayout>> = cursive.find_id("playlists");
if let Some(mut playlist_overview) = view_ref {
if let Some(mut playlists) = view_ref {
match event {
PlaylistEvent::Refresh => {
self.clear_playlists(&mut playlist_overview);
self.show_playlists(&mut playlist_overview);
// FIXME: do this only once at startup or when requested by
// the user
self.clear_playlists(&mut playlists);
self.show_playlists(&mut playlists);
}
}
}
}
}