diff --git a/front/package.json b/front/package.json
index 732fdb4067ef3a515dc24f0d045be2caf4cd5554..7cec50319a142649dedfb00645418b195c9bf339 100644
--- a/front/package.json
+++ b/front/package.json
@@ -19,7 +19,8 @@
"semantic-ui-css": "^2.2.10",
"vue": "^2.3.3",
"vue-resource": "^1.3.4",
- "vue-router": "^2.3.1"
+ "vue-router": "^2.3.1",
+ "vuedraggable": "^2.14.1"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
diff --git a/front/src/audio/queue.js b/front/src/audio/queue.js
index ba0af486f53b30f95872fb115b303a455c8ef6cf..c91c1d2acceb52cdc69daf71b95b7e693f3913ad 100644
--- a/front/src/audio/queue.js
+++ b/front/src/audio/queue.js
@@ -92,6 +92,24 @@ class Queue {
}
cache.set('volume', newValue)
}
+
+ reorder (oldIndex, newIndex) {
+ // called when the user uses drag / drop to reorder
+ // tracks in queue
+ if (oldIndex === this.currentIndex) {
+ this.currentIndex = newIndex
+ return
+ }
+ if (oldIndex < this.currentIndex && newIndex >= this.currentIndex) {
+ // item before was moved after
+ this.currentIndex -= 1
+ }
+ if (oldIndex > this.currentIndex && newIndex <= this.currentIndex) {
+ // item after was moved before
+ this.currentIndex += 1
+ }
+ }
+
append (track, index) {
this.previousQueue = null
index = index || this.tracks.length
diff --git a/front/src/components/Sidebar.vue b/front/src/components/Sidebar.vue
index c98dc2f0132c8f7d60b1e4d72e97dd190ca338a0..90e6d2d06031657a09e8c251a14847a985f04e4c 100644
--- a/front/src/components/Sidebar.vue
+++ b/front/src/components/Sidebar.vue
@@ -50,27 +50,27 @@
</div>
<div class="ui bottom attached tab" data-tab="queue">
<table class="ui compact inverted very basic fixed single line table">
- <tbody>
- <tr @click="queue.play(index)" v-for="(track, index) in queue.tracks" :class="[{'active': index === queue.currentIndex}]">
- <td class="right aligned">{{ index + 1}}</td>
- <td class="center aligned">
- <img class="ui mini image" v-if="track.album.cover" :src="backend.absoluteUrl(track.album.cover)">
- <img class="ui mini image" v-else src="../assets/audio/default-cover.png">
- </td>
- <td colspan="4">
- <strong>{{ track.title }}</strong><br />
- {{ track.artist.name }}
- </td>
- <td>
- <template v-if="favoriteTracks.objects[track.id]">
- <i @click.stop="queue.cleanTrack(index)" class="pink heart icon"></i>
- </template
- </td>
- <td>
- <i @click.stop="queue.cleanTrack(index)" class="circular trash icon"></i>
- </td>
- </tr>
- </tbody>
+ <draggable v-model="queue.tracks" element="tbody" @update="reorder">
+ <tr @click="queue.play(index)" v-for="(track, index) in queue.tracks" :key="index" :class="[{'active': index === queue.currentIndex}]">
+ <td class="right aligned">{{ index + 1}}</td>
+ <td class="center aligned">
+ <img class="ui mini image" v-if="track.album.cover" :src="backend.absoluteUrl(track.album.cover)">
+ <img class="ui mini image" v-else src="../assets/audio/default-cover.png">
+ </td>
+ <td colspan="4">
+ <strong>{{ track.title }}</strong><br />
+ {{ track.artist.name }}
+ </td>
+ <td>
+ <template v-if="favoriteTracks.objects[track.id]">
+ <i @click.stop="queue.cleanTrack(index)" class="pink heart icon"></i>
+ </template
+ </td>
+ <td>
+ <i @click.stop="queue.cleanTrack(index)" class="circular trash icon"></i>
+ </td>
+ </tr>
+ </draggable>
</table>
<div v-if="radios.running" class="ui black message">
@@ -98,6 +98,7 @@ import SearchBar from '@/components/audio/SearchBar'
import auth from '@/auth'
import queue from '@/audio/queue'
import backend from '@/audio/backend'
+import draggable from 'vuedraggable'
import radios from '@/radios'
import $ from 'jquery'
@@ -107,7 +108,8 @@ export default {
components: {
Player,
SearchBar,
- Logo
+ Logo,
+ draggable
},
data () {
return {
@@ -120,6 +122,11 @@ export default {
},
mounted () {
$(this.$el).find('.menu .item').tab()
+ },
+ methods: {
+ reorder (e) {
+ this.queue.reorder(e.oldIndex, e.newIndex)
+ }
}
}
</script>