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) {
|
pub fn play(&self, index: usize, reshuffle: bool) {
|
||||||
if let Some(track) = &self.queue.read().unwrap().get(index) {
|
if let Some(track) = &self.queue.read().unwrap().get(index) {
|
||||||
self.spotify.load(&track);
|
self.spotify.load(&track);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ pub struct ListView<I: 'static + ListItem> {
|
|||||||
last_size: Vec2,
|
last_size: Vec2,
|
||||||
scrollbar: ScrollBase,
|
scrollbar: ScrollBase,
|
||||||
queue: Arc<Queue>,
|
queue: Arc<Queue>,
|
||||||
shiftable: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: ListItem> ListView<I> {
|
impl<I: ListItem> ListView<I> {
|
||||||
@@ -32,15 +31,9 @@ impl<I: ListItem> ListView<I> {
|
|||||||
last_size: Vec2::new(0, 0),
|
last_size: Vec2::new(0, 0),
|
||||||
scrollbar: ScrollBase::new(),
|
scrollbar: ScrollBase::new(),
|
||||||
queue,
|
queue,
|
||||||
shiftable: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shiftable(mut self) -> Self {
|
|
||||||
self.shiftable = true;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_selected_index(&self) -> usize {
|
pub fn get_selected_index(&self) -> usize {
|
||||||
self.selected
|
self.selected
|
||||||
}
|
}
|
||||||
@@ -55,11 +48,6 @@ impl<I: ListItem> ListView<I> {
|
|||||||
let new = self.selected as i32 + delta;
|
let new = self.selected as i32 + delta;
|
||||||
self.move_focus_to(max(new, 0) as usize);
|
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> {
|
impl<I: ListItem> View for ListView<I> {
|
||||||
@@ -208,7 +196,7 @@ impl<I: ListItem> ViewExt for ListView<I> {
|
|||||||
return Ok(CommandResult::Consumed(None));
|
return Ok(CommandResult::Consumed(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd == "move" || cmd == "shift" {
|
if cmd == "move" {
|
||||||
if let Some(dir) = args.get(0) {
|
if let Some(dir) = args.get(0) {
|
||||||
let amount: usize = args
|
let amount: usize = args
|
||||||
.get(1)
|
.get(1)
|
||||||
@@ -216,22 +204,14 @@ impl<I: ListItem> ViewExt for ListView<I> {
|
|||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{:?}", e))?;
|
||||||
|
|
||||||
let shift = cmd == "shift" && self.shiftable;
|
|
||||||
let selected = self.selected;
|
|
||||||
let len = self.content.read().unwrap().len();
|
let len = self.content.read().unwrap().len();
|
||||||
|
|
||||||
if dir == "up" && self.selected > 0 {
|
if dir == "up" && self.selected > 0 {
|
||||||
if shift {
|
|
||||||
self.swap(selected, selected.saturating_sub(amount));
|
|
||||||
}
|
|
||||||
self.move_focus(-(amount as i32));
|
self.move_focus(-(amount as i32));
|
||||||
return Ok(CommandResult::Consumed(None));
|
return Ok(CommandResult::Consumed(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
if dir == "down" && self.selected < len.saturating_sub(1) {
|
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);
|
self.move_focus(amount as i32);
|
||||||
return Ok(CommandResult::Consumed(None));
|
return Ok(CommandResult::Consumed(None));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use cursive::view::ViewWrapper;
|
|||||||
use cursive::views::{Dialog, EditView, ScrollView, SelectView};
|
use cursive::views::{Dialog, EditView, ScrollView, SelectView};
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
|
|
||||||
|
use std::cmp::min;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use commands::CommandResult;
|
use commands::CommandResult;
|
||||||
@@ -22,7 +23,7 @@ pub struct QueueView {
|
|||||||
|
|
||||||
impl QueueView {
|
impl QueueView {
|
||||||
pub fn new(queue: Arc<Queue>, playlists: Arc<Playlists>) -> 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 {
|
QueueView {
|
||||||
list,
|
list,
|
||||||
@@ -124,6 +125,28 @@ impl ViewExt for QueueView {
|
|||||||
return Ok(CommandResult::Consumed(None));
|
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))
|
self.with_view_mut(move |v| v.on_command(s, cmd, args))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user