implement preliminary queue view

this approach needs some (re)work, as the UI is not fully sync'd with the data,
yet. it'd probably be better to have an event system triggered by the queue,
that will cause a UI refresh or similar.
This commit is contained in:
Henrik Friedrichsen
2019-02-26 23:30:16 +01:00
parent ce566b0fb9
commit 204cb18410
4 changed files with 82 additions and 0 deletions

View File

@@ -91,6 +91,10 @@ fn main() {
let search = ui::search::SearchView::new(spotify.clone(), queue.clone());
cursive.add_fullscreen_layer(search.view);
let queuescreen = cursive.add_active_screen();
let mut queue = ui::queue::QueueView::new(queue.clone(), spotify.clone());
cursive.add_fullscreen_layer(queue.view.take().unwrap());
let logscreen = cursive.add_active_screen();
let logpanel = Panel::new(logview).title("Log");
cursive.add_fullscreen_layer(logpanel);
@@ -98,7 +102,13 @@ fn main() {
cursive.add_global_callback(Key::F1, move |s| {
s.set_screen(logscreen);
});
cursive.add_global_callback(Key::F2, move |s| {
s.set_screen(queuescreen);
queue.redraw(s);
});
cursive.add_global_callback(Key::F3, move |s| {
s.set_screen(searchscreen);
});

View File

@@ -1,4 +1,5 @@
use std::collections::VecDeque;
use std::collections::vec_deque::Iter;
use rspotify::spotify::model::track::FullTrack;
@@ -12,10 +13,16 @@ impl Queue {
queue: VecDeque::new(),
}
}
pub fn remove(&mut self, index: usize) -> Option<FullTrack> {
self.queue.remove(index)
}
pub fn enqueue(&mut self, track: FullTrack) {
self.queue.push_back(track);
}
pub fn dequeue(&mut self) -> Option<FullTrack> {
self.queue.pop_front()
}
pub fn iter(&self) -> Iter<FullTrack> {
self.queue.iter()
}
}

View File

@@ -1 +1,2 @@
pub mod queue;
pub mod search;

64
src/ui/queue.rs Normal file
View File

@@ -0,0 +1,64 @@
use cursive::direction::Orientation;
use cursive::traits::Boxable;
use cursive::traits::Identifiable;
use cursive::views::*;
use cursive::Cursive;
use std::sync::Arc;
use std::sync::Mutex;
use librespot::core::spotify_id::SpotifyId;
use queue::Queue;
use spotify::Spotify;
pub struct QueueView {
pub view: Option<Panel<LinearLayout>>,
queue: Arc<Mutex<Queue>>,
spotify: Arc<Spotify>,
}
impl QueueView {
pub fn new(queue: Arc<Mutex<Queue>>, spotify: Arc<Spotify>) -> QueueView {
let queuelist = ListView::new().with_id("queue_list").full_width();
let scrollable = ScrollView::new(queuelist).full_width().full_height();
let layout = LinearLayout::new(Orientation::Vertical).child(scrollable);
let panel = Panel::new(layout).title("Queue");
QueueView {
view: Some(panel),
queue: queue,
spotify: spotify
}
}
pub fn redraw(&self, s: &mut Cursive) {
let mut queuelist: ViewRef<ListView> = s.find_id("queue_list").unwrap();
queuelist.clear();
let queue_ref = self.queue.clone();
let queue = self.queue.lock().unwrap();
for (index, track) in queue.iter().enumerate() {
let artists = track
.artists
.iter()
.map(|ref artist| artist.name.clone())
.collect::<Vec<String>>()
.join(", ");
let formatted = format!("{} - {}", artists, track.name);
let trackid = SpotifyId::from_base62(&track.id).expect("could not load track");
let s = self.spotify.clone();
let queue_ref = queue_ref.clone();
let button = Button::new_raw(formatted, move |_cursive| {
s.load(trackid);
s.play();
queue_ref.lock().unwrap().remove(index);
// TODO: update view representation, preferably, queue changes
// cause a view refresh
});
queuelist.add_child("", button);
}
}
}