respect currently playing track when shifting queue entries
This commit is contained in:
23
src/queue.rs
23
src/queue.rs
@@ -163,6 +163,29 @@ impl Queue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.queue.read().unwrap().len()
|
||||
}
|
||||
|
||||
pub fn shift(&self, from: usize, to: usize) {
|
||||
let mut queue = self.queue.write().unwrap();
|
||||
let item = queue.remove(from);
|
||||
queue.insert(to, item);
|
||||
|
||||
// if the currently playing track is affected by the shift, update its
|
||||
// index
|
||||
let mut current = self.current_track.write().unwrap();
|
||||
if let Some(index) = *current {
|
||||
if index == from {
|
||||
current.replace(to);
|
||||
} else if index == to && from > index {
|
||||
current.replace(to + 1);
|
||||
} else if index == to && from < index {
|
||||
current.replace(to - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play(&self, index: usize, reshuffle: bool) {
|
||||
if let Some(track) = &self.queue.read().unwrap().get(index) {
|
||||
self.spotify.load(&track);
|
||||
|
||||
@@ -20,7 +20,6 @@ pub struct ListView<I: 'static + ListItem> {
|
||||
last_size: Vec2,
|
||||
scrollbar: ScrollBase,
|
||||
queue: Arc<Queue>,
|
||||
shiftable: bool,
|
||||
}
|
||||
|
||||
impl<I: ListItem> ListView<I> {
|
||||
@@ -32,15 +31,9 @@ impl<I: ListItem> ListView<I> {
|
||||
last_size: Vec2::new(0, 0),
|
||||
scrollbar: ScrollBase::new(),
|
||||
queue,
|
||||
shiftable: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shiftable(mut self) -> Self {
|
||||
self.shiftable = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_selected_index(&self) -> usize {
|
||||
self.selected
|
||||
}
|
||||
@@ -55,11 +48,6 @@ impl<I: ListItem> ListView<I> {
|
||||
let new = self.selected as i32 + delta;
|
||||
self.move_focus_to(max(new, 0) as usize);
|
||||
}
|
||||
|
||||
pub fn swap(&mut self, a: usize, b: usize) {
|
||||
let mut content = self.content.write().expect("can't writelock content");
|
||||
content.swap(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: ListItem> View for ListView<I> {
|
||||
@@ -208,7 +196,7 @@ impl<I: ListItem> ViewExt for ListView<I> {
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
|
||||
if cmd == "move" || cmd == "shift" {
|
||||
if cmd == "move" {
|
||||
if let Some(dir) = args.get(0) {
|
||||
let amount: usize = args
|
||||
.get(1)
|
||||
@@ -216,22 +204,14 @@ impl<I: ListItem> ViewExt for ListView<I> {
|
||||
.parse()
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
let shift = cmd == "shift" && self.shiftable;
|
||||
let selected = self.selected;
|
||||
let len = self.content.read().unwrap().len();
|
||||
|
||||
if dir == "up" && self.selected > 0 {
|
||||
if shift {
|
||||
self.swap(selected, selected.saturating_sub(amount));
|
||||
}
|
||||
self.move_focus(-(amount as i32));
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
|
||||
if dir == "down" && self.selected < len.saturating_sub(1) {
|
||||
if shift {
|
||||
self.swap(selected, min(selected + amount as usize, len - 1));
|
||||
}
|
||||
self.move_focus(amount as i32);
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use cursive::view::ViewWrapper;
|
||||
use cursive::views::{Dialog, EditView, ScrollView, SelectView};
|
||||
use cursive::Cursive;
|
||||
|
||||
use std::cmp::min;
|
||||
use std::sync::Arc;
|
||||
|
||||
use commands::CommandResult;
|
||||
@@ -22,7 +23,7 @@ pub struct QueueView {
|
||||
|
||||
impl QueueView {
|
||||
pub fn new(queue: Arc<Queue>, playlists: Arc<Playlists>) -> QueueView {
|
||||
let list = ListView::new(queue.queue.clone(), queue.clone()).shiftable();
|
||||
let list = ListView::new(queue.queue.clone(), queue.clone());
|
||||
|
||||
QueueView {
|
||||
list,
|
||||
@@ -124,6 +125,28 @@ impl ViewExt for QueueView {
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
|
||||
if cmd == "shift" {
|
||||
if let Some(dir) = args.get(0) {
|
||||
let amount: usize = args
|
||||
.get(1)
|
||||
.unwrap_or(&"1".to_string())
|
||||
.parse()
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
let selected = self.list.get_selected_index();
|
||||
let len = self.queue.len();
|
||||
if dir == "up" && selected > 0 {
|
||||
self.queue.shift(selected, selected.saturating_sub(amount));
|
||||
self.list.move_focus(-(amount as i32));
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
} else if dir == "down" && selected < len.saturating_sub(1) {
|
||||
self.queue
|
||||
.shift(selected, min(selected + amount as usize, len - 1));
|
||||
self.list.move_focus(amount as i32);
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.with_view_mut(move |v| v.on_command(s, cmd, args))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user