implement functionality to save queues to playlists
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use std::cmp::{max, min};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||
|
||||
use cursive::align::HAlign;
|
||||
use cursive::event::{Event, EventResult, MouseButton, MouseEvent};
|
||||
@@ -54,6 +54,12 @@ impl<I: ListItem> ListView<I> {
|
||||
let new = self.selected as i32 + delta;
|
||||
self.move_focus_to(max(new, 0) as usize);
|
||||
}
|
||||
|
||||
pub fn content(&self) -> RwLockReadGuard<Vec<I>> {
|
||||
self.content
|
||||
.read()
|
||||
.expect("could not readlock listview content")
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: ListItem> View for ListView<I> {
|
||||
|
||||
@@ -1,25 +1,98 @@
|
||||
use cursive::traits::Identifiable;
|
||||
use cursive::event::{Callback, Event, EventResult};
|
||||
use cursive::traits::{Boxable, Identifiable, View};
|
||||
use cursive::view::ViewWrapper;
|
||||
use cursive::views::IdView;
|
||||
use cursive::views::{Dialog, EditView, IdView, ScrollView, SelectView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use playlists::Playlists;
|
||||
use queue::Queue;
|
||||
use track::Track;
|
||||
use ui::listview::ListView;
|
||||
use ui::modal::Modal;
|
||||
|
||||
pub struct QueueView {
|
||||
list: IdView<ListView<Track>>,
|
||||
playlists: Arc<Playlists>,
|
||||
}
|
||||
|
||||
impl QueueView {
|
||||
pub fn new(queue: Arc<Queue>) -> QueueView {
|
||||
pub fn new(queue: Arc<Queue>, playlists: Arc<Playlists>) -> QueueView {
|
||||
let list = ListView::new(queue.queue.clone(), queue.clone()).with_id("queue_list");
|
||||
|
||||
QueueView { list: list }
|
||||
QueueView {
|
||||
list: list,
|
||||
playlists: playlists,
|
||||
}
|
||||
}
|
||||
|
||||
fn save_dialog_cb(s: &mut Cursive, playlists: Arc<Playlists>, id: Option<String>) {
|
||||
let tracks = s
|
||||
.call_on_id("queue_list", |view: &mut ListView<_>| {
|
||||
view.content().clone()
|
||||
})
|
||||
.unwrap();
|
||||
match id {
|
||||
Some(id) => {
|
||||
playlists.overwrite_playlist(&id, &tracks);
|
||||
s.pop_layer();
|
||||
}
|
||||
None => {
|
||||
s.pop_layer();
|
||||
let edit = EditView::new()
|
||||
.on_submit(move |s: &mut Cursive, name| {
|
||||
playlists.save_playlist(name, &tracks);
|
||||
s.pop_layer();
|
||||
})
|
||||
.with_id("name")
|
||||
.fixed_width(20);
|
||||
let dialog = Dialog::new()
|
||||
.title("Enter name")
|
||||
.dismiss_button("Cancel")
|
||||
.padding((1, 1, 1, 0))
|
||||
.content(edit);
|
||||
s.add_layer(Modal::new(dialog));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn save_dialog(playlists: Arc<Playlists>) -> Modal<Dialog> {
|
||||
let mut list_select: SelectView<Option<String>> = SelectView::new().autojump();
|
||||
list_select.add_item("[Create new]", None);
|
||||
|
||||
for ref list in playlists.items().iter() {
|
||||
list_select.add_item(list.meta.name.clone(), Some(list.meta.id.clone()));
|
||||
}
|
||||
|
||||
list_select.set_on_submit(move |s, selected| {
|
||||
Self::save_dialog_cb(s, playlists.clone(), selected.clone())
|
||||
});
|
||||
|
||||
let dialog = Dialog::new()
|
||||
.title("Save to existing or new playlist?")
|
||||
.dismiss_button("Cancel")
|
||||
.padding((1, 1, 1, 0))
|
||||
.content(ScrollView::new(list_select));
|
||||
Modal::new(dialog)
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewWrapper for QueueView {
|
||||
wrap_impl!(self.list: IdView<ListView<Track>>);
|
||||
|
||||
fn wrap_on_event(&mut self, ch: Event) -> EventResult {
|
||||
match ch {
|
||||
Event::Char('s') => {
|
||||
debug!("save list");
|
||||
let playlists = self.playlists.clone();
|
||||
let cb = move |s: &mut Cursive| {
|
||||
let dialog = Self::save_dialog(playlists.clone());
|
||||
s.add_layer(dialog)
|
||||
};
|
||||
EventResult::Consumed(Some(Callback::from_fn(cb)))
|
||||
}
|
||||
_ => self.list.on_event(ch),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user