diff --git a/app/css/elements/menu.less b/app/css/elements/menu.less
index 318df05..bfa8310 100644
--- a/app/css/elements/menu.less
+++ b/app/css/elements/menu.less
@@ -47,7 +47,7 @@ cyp-commands {
}
button {
- flex: 0 0 @breakpoint-menu/6;
+ flex: 0 1 @breakpoint-menu/6;
&.last {
order: 1;
margin-left: auto;
diff --git a/app/css/mixins.less b/app/css/mixins.less
index 53ebfbe..dda1a25 100644
--- a/app/css/mixins.less
+++ b/app/css/mixins.less
@@ -25,6 +25,7 @@
.selectable {
border-left: 4px solid transparent;
+ cursor: pointer;
&.selected {
border-left-color: var(--primary);
@@ -34,9 +35,9 @@
.item {
.flex-row;
.selectable;
- padding: 8px;
+ padding: 8px 4px;
- &:nth-child(odd) {
+ &:nth-child(odd) { // FIXME nutno poresit lepe s ohledem na search
background-color: var(--bg-alt);
}
}
\ No newline at end of file
diff --git a/app/cyp.css b/app/cyp.css
index 5e97a06..0a943f3 100644
--- a/app/cyp.css
+++ b/app/cyp.css
@@ -109,6 +109,7 @@ select {
*/
.selectable {
border-left: 4px solid transparent;
+ cursor: pointer;
}
.selectable.selected {
border-left-color: var(--primary);
@@ -117,7 +118,8 @@ select {
flex-direction: row;
align-items: center;
border-left: 4px solid transparent;
- padding: 8px;
+ cursor: pointer;
+ padding: 8px 4px;
}
.item:not([hidden]) {
display: flex;
@@ -490,7 +492,7 @@ cyp-commands[hidden] {
top: 100%;
}
cyp-commands button {
- flex: 0 0 80px;
+ flex: 0 1 80px;
}
cyp-commands button.last {
order: 1;
@@ -500,7 +502,8 @@ cyp-song {
flex-direction: row;
align-items: center;
border-left: 4px solid transparent;
- padding: 8px;
+ cursor: pointer;
+ padding: 8px 4px;
}
cyp-song:not([hidden]) {
display: flex;
@@ -824,7 +827,8 @@ cyp-playlist {
flex-direction: row;
align-items: center;
border-left: 4px solid transparent;
- padding: 8px;
+ cursor: pointer;
+ padding: 8px 4px;
}
cyp-playlist:not([hidden]) {
display: flex;
diff --git a/app/icons/arrow-down-bold.svg b/app/icons/arrow-down-bold.svg
new file mode 100644
index 0000000..640bb20
--- /dev/null
+++ b/app/icons/arrow-down-bold.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/icons/arrow-up-bold.svg b/app/icons/arrow-up-bold.svg
new file mode 100644
index 0000000..ce46818
--- /dev/null
+++ b/app/icons/arrow-up-bold.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/js/elements/queue.js b/app/js/elements/queue.js
index 5dad233..c909c50 100644
--- a/app/js/elements/queue.js
+++ b/app/js/elements/queue.js
@@ -3,6 +3,18 @@ import Component from "../component.js";
import Song from "./song.js";
+function generateMoveCommands(items, diff, all) {
+ const COMPARE = (a, b) => all.indexOf(a) - all.indexOf(b);
+
+ return items.sort(COMPARE)
+ .map(item => {
+ let index = all.indexOf(item) + diff;
+ if (index < 0 || index >= all.length) { return null; } // this does not move
+ return `moveid ${item.data["Id"]} ${index}`;
+ })
+ .filter(command => command);
+}
+
class Queue extends Component {
constructor() {
super({selection:"multi"});
@@ -63,6 +75,18 @@ class Queue extends Component {
sel.addCommandAll();
+ sel.addCommand(async items => {
+ const commands = generateMoveCommands(items, -1, Array.from(this.children));
+ await this._mpd.command(commands);
+ this._sync();
+ }, {label:"Up", icon:"arrow-up-bold"});
+
+ sel.addCommand(async items => {
+ const commands = generateMoveCommands(items, +1, Array.from(this.children));
+ await this._mpd.command(commands.reverse()); // move last first
+ this._sync();
+ }, {label:"Down", icon:"arrow-down-bold"});
+
sel.addCommand(async items => {
let name = prompt("Save selected songs as a playlist?", "name");
if (name === null) { return; }
@@ -72,8 +96,7 @@ class Queue extends Component {
return `playlistadd "${name}" "${this._mpd.escape(item.data["file"])}"`;
});
- await this._mpd.command(commands);
- // FIXME notify?
+ await this._mpd.command(commands); // FIXME notify?
}, {label:"Save", icon:"content-save"});
sel.addCommand(async items => {
diff --git a/app/js/icons.js b/app/js/icons.js
index 811ef25..2f638ae 100644
--- a/app/js/icons.js
+++ b/app/js/icons.js
@@ -35,6 +35,9 @@ ICONS["settings"] = `