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>