Add hjkl controls for AddToPlaylistMenu (#335)
* Add hjkl controls for AddToPlaylistMenu * turn off autojump in contextmenu for vim bindings Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
This commit is contained in:
@@ -2,9 +2,6 @@ use std::collections::HashMap;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::command::{
|
|
||||||
parse, Command, GotoMode, JumpMode, MoveAmount, MoveMode, SeekDirection, ShiftMode, TargetMode,
|
|
||||||
};
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::library::Library;
|
use crate::library::Library;
|
||||||
use crate::queue::{Queue, RepeatSetting};
|
use crate::queue::{Queue, RepeatSetting};
|
||||||
@@ -14,6 +11,13 @@ use crate::ui::contextmenu::ContextMenu;
|
|||||||
use crate::ui::help::HelpView;
|
use crate::ui::help::HelpView;
|
||||||
use crate::ui::layout::Layout;
|
use crate::ui::layout::Layout;
|
||||||
use crate::UserData;
|
use crate::UserData;
|
||||||
|
use crate::{
|
||||||
|
command::{
|
||||||
|
parse, Command, GotoMode, JumpMode, MoveAmount, MoveMode, SeekDirection, ShiftMode,
|
||||||
|
TargetMode,
|
||||||
|
},
|
||||||
|
ui::contextmenu::AddToPlaylistMenu,
|
||||||
|
};
|
||||||
use cursive::event::{Event, Key};
|
use cursive::event::{Event, Key};
|
||||||
use cursive::traits::View;
|
use cursive::traits::View;
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
@@ -211,6 +215,8 @@ impl CommandManager {
|
|||||||
fn handle_callbacks(&self, s: &mut Cursive, cmd: &Command) -> Result<Option<String>, String> {
|
fn handle_callbacks(&self, s: &mut Cursive, cmd: &Command) -> Result<Option<String>, String> {
|
||||||
let local = if let Some(mut contextmenu) = s.find_name::<ContextMenu>("contextmenu") {
|
let local = if let Some(mut contextmenu) = s.find_name::<ContextMenu>("contextmenu") {
|
||||||
contextmenu.on_command(s, cmd)?
|
contextmenu.on_command(s, cmd)?
|
||||||
|
} else if let Some(mut add_track_menu) = s.find_name::<AddToPlaylistMenu>("addtrackmenu") {
|
||||||
|
add_track_menu.on_command(s, cmd)?
|
||||||
} else {
|
} else {
|
||||||
let mut main = s
|
let mut main = s
|
||||||
.find_name::<Layout>("main")
|
.find_name::<Layout>("main")
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub struct Playlist {
|
|||||||
pub snapshot_id: String,
|
pub snapshot_id: String,
|
||||||
pub num_tracks: usize,
|
pub num_tracks: usize,
|
||||||
pub tracks: Option<Vec<Track>>,
|
pub tracks: Option<Vec<Track>>,
|
||||||
pub collaborative: bool
|
pub collaborative: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Playlist {
|
impl Playlist {
|
||||||
@@ -143,7 +143,7 @@ impl From<&FullPlaylist> for Playlist {
|
|||||||
snapshot_id: list.snapshot_id.clone(),
|
snapshot_id: list.snapshot_id.clone(),
|
||||||
num_tracks: list.tracks.total as usize,
|
num_tracks: list.tracks.total as usize,
|
||||||
tracks: None,
|
tracks: None,
|
||||||
collaborative: list.collaborative
|
collaborative: list.collaborative,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ use cursive::Cursive;
|
|||||||
|
|
||||||
use crate::commands::CommandResult;
|
use crate::commands::CommandResult;
|
||||||
use crate::library::Library;
|
use crate::library::Library;
|
||||||
|
use crate::playable::Playable;
|
||||||
use crate::queue::Queue;
|
use crate::queue::Queue;
|
||||||
use crate::track::Track;
|
use crate::track::Track;
|
||||||
use crate::traits::{ListItem, ViewExt};
|
use crate::traits::{ListItem, ViewExt};
|
||||||
use crate::playable::Playable;
|
|
||||||
use crate::ui::layout::Layout;
|
use crate::ui::layout::Layout;
|
||||||
use crate::ui::modal::Modal;
|
use crate::ui::modal::Modal;
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -25,6 +25,10 @@ pub struct ContextMenu {
|
|||||||
dialog: Modal<Dialog>,
|
dialog: Modal<Dialog>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AddToPlaylistMenu {
|
||||||
|
dialog: Modal<Dialog>,
|
||||||
|
}
|
||||||
|
|
||||||
enum ContextMenuAction {
|
enum ContextMenuAction {
|
||||||
ShowItem(Box<dyn ListItem>),
|
ShowItem(Box<dyn ListItem>),
|
||||||
ShareUrl(String),
|
ShareUrl(String),
|
||||||
@@ -38,8 +42,8 @@ impl ContextMenu {
|
|||||||
library: Arc<Library>,
|
library: Arc<Library>,
|
||||||
spotify: Arc<Spotify>,
|
spotify: Arc<Spotify>,
|
||||||
track: Track,
|
track: Track,
|
||||||
) -> Modal<Dialog> {
|
) -> NamedView<AddToPlaylistMenu> {
|
||||||
let mut list_select: SelectView<Playlist> = SelectView::new().autojump();
|
let mut list_select: SelectView<Playlist> = SelectView::new();
|
||||||
let current_user_id = library.user_id.as_ref().unwrap();
|
let current_user_id = library.user_id.as_ref().unwrap();
|
||||||
|
|
||||||
for list in library.items().iter() {
|
for list in library.items().iter() {
|
||||||
@@ -82,8 +86,12 @@ impl ContextMenu {
|
|||||||
.title("Add track to playlist")
|
.title("Add track to playlist")
|
||||||
.dismiss_button("Cancel")
|
.dismiss_button("Cancel")
|
||||||
.padding(Margins::lrtb(1, 1, 1, 0))
|
.padding(Margins::lrtb(1, 1, 1, 0))
|
||||||
.content(ScrollView::new(list_select));
|
.content(ScrollView::new(list_select.with_name("addplaylist_select")));
|
||||||
Modal::new(dialog)
|
|
||||||
|
AddToPlaylistMenu {
|
||||||
|
dialog: Modal::new_ext(dialog),
|
||||||
|
}
|
||||||
|
.with_name("addtrackmenu")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn track_already_added() -> Dialog {
|
fn track_already_added() -> Dialog {
|
||||||
@@ -94,7 +102,7 @@ impl ContextMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(item: &dyn ListItem, queue: Arc<Queue>, library: Arc<Library>) -> NamedView<Self> {
|
pub fn new(item: &dyn ListItem, queue: Arc<Queue>, library: Arc<Library>) -> NamedView<Self> {
|
||||||
let mut content: SelectView<ContextMenuAction> = SelectView::new().autojump();
|
let mut content: SelectView<ContextMenuAction> = SelectView::new();
|
||||||
if let Some(a) = item.artist() {
|
if let Some(a) = item.artist() {
|
||||||
content.add_item("Show artist", ContextMenuAction::ShowItem(Box::new(a)));
|
content.add_item("Show artist", ContextMenuAction::ShowItem(Box::new(a)));
|
||||||
}
|
}
|
||||||
@@ -170,48 +178,59 @@ impl ContextMenu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ViewExt for AddToPlaylistMenu {
|
||||||
|
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
|
||||||
|
handle_move_command::<Playlist>(&mut self.dialog, s, cmd, "addplaylist_select")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ViewExt for ContextMenu {
|
impl ViewExt for ContextMenu {
|
||||||
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
|
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
|
||||||
match cmd {
|
handle_move_command::<ContextMenuAction>(&mut self.dialog, s, cmd, "contextmenu_select")
|
||||||
Command::Back => {
|
|
||||||
s.pop_layer();
|
|
||||||
Ok(CommandResult::Consumed(None))
|
|
||||||
}
|
|
||||||
Command::Move(mode, amount) => self
|
|
||||||
.dialog
|
|
||||||
.call_on_name(
|
|
||||||
"contextmenu_select",
|
|
||||||
|select: &mut SelectView<ContextMenuAction>| {
|
|
||||||
let items = select.len();
|
|
||||||
match mode {
|
|
||||||
MoveMode::Up => {
|
|
||||||
match amount {
|
|
||||||
MoveAmount::Extreme => select.set_selection(0),
|
|
||||||
MoveAmount::Integer(amount) => {
|
|
||||||
select.select_up(*amount as usize)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(CommandResult::Consumed(None))
|
|
||||||
}
|
|
||||||
MoveMode::Down => {
|
|
||||||
match amount {
|
|
||||||
MoveAmount::Extreme => select.set_selection(items),
|
|
||||||
MoveAmount::Integer(amount) => {
|
|
||||||
select.select_down(*amount as usize)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(CommandResult::Consumed(None))
|
|
||||||
}
|
|
||||||
_ => Ok(CommandResult::Consumed(None)),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap_or(Ok(CommandResult::Consumed(None))),
|
|
||||||
_ => Ok(CommandResult::Consumed(None)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_move_command<T: 'static>(
|
||||||
|
sel: &mut Modal<Dialog>,
|
||||||
|
s: &mut Cursive,
|
||||||
|
cmd: &Command,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<CommandResult, String> {
|
||||||
|
match cmd {
|
||||||
|
Command::Back => {
|
||||||
|
s.pop_layer();
|
||||||
|
Ok(CommandResult::Consumed(None))
|
||||||
|
}
|
||||||
|
Command::Move(mode, amount) => sel
|
||||||
|
.call_on_name(name, |select: &mut SelectView<T>| {
|
||||||
|
let items = select.len();
|
||||||
|
match mode {
|
||||||
|
MoveMode::Up => {
|
||||||
|
match amount {
|
||||||
|
MoveAmount::Extreme => select.set_selection(0),
|
||||||
|
MoveAmount::Integer(amount) => select.select_up(*amount as usize),
|
||||||
|
};
|
||||||
|
Ok(CommandResult::Consumed(None))
|
||||||
|
}
|
||||||
|
MoveMode::Down => {
|
||||||
|
match amount {
|
||||||
|
MoveAmount::Extreme => select.set_selection(items),
|
||||||
|
MoveAmount::Integer(amount) => select.select_down(*amount as usize),
|
||||||
|
};
|
||||||
|
Ok(CommandResult::Consumed(None))
|
||||||
|
}
|
||||||
|
_ => Ok(CommandResult::Consumed(None)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or(Ok(CommandResult::Consumed(None))),
|
||||||
|
_ => Ok(CommandResult::Consumed(None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ViewWrapper for AddToPlaylistMenu {
|
||||||
|
wrap_impl!(self.dialog: Modal<Dialog>);
|
||||||
|
}
|
||||||
|
|
||||||
impl ViewWrapper for ContextMenu {
|
impl ViewWrapper for ContextMenu {
|
||||||
wrap_impl!(self.dialog: Modal<Dialog>);
|
wrap_impl!(self.dialog: Modal<Dialog>);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user