Update vuedraggable

This commit is contained in:
Kasper Seweryn 2022-05-01 10:02:20 +02:00 committed by Georg Krause
parent b7d66232f6
commit 7e53e9a511
5 changed files with 122 additions and 113 deletions

View File

@ -43,7 +43,7 @@
"vue-upload-component": "2.8.22", "vue-upload-component": "2.8.22",
"vue3-gettext": "2.2.0-alpha.1", "vue3-gettext": "2.2.0-alpha.1",
"vue3-lazyload": "0.2.5-beta", "vue3-lazyload": "0.2.5-beta",
"vuedraggable": "2.24.3", "vuedraggable": "4.1.0",
"vuex": "4.0.2", "vuex": "4.0.2",
"vuex-persistedstate": "4.1.0", "vuex-persistedstate": "4.1.0",
"vuex-router-sync": "5.0.0" "vuex-router-sync": "5.0.0"

View File

@ -156,7 +156,7 @@
:title="labels.previousTrack" :title="labels.previousTrack"
:aria-label="labels.previousTrack" :aria-label="labels.previousTrack"
class="control" class="control"
:disabled="emptyQueue" :disabled="emptyQueue ? true : null"
@click.prevent.stop="$store.dispatch('queue/previous')" @click.prevent.stop="$store.dispatch('queue/previous')"
> >
<i :class="['ui', 'backward step', {'disabled': emptyQueue}, 'icon']" /> <i :class="['ui', 'backward step', {'disabled': emptyQueue}, 'icon']" />
@ -187,7 +187,7 @@
:title="labels.next" :title="labels.next"
:aria-label="labels.next" :aria-label="labels.next"
class="control" class="control"
:disabled="!hasNext" :disabled="hasNext ? true : null"
@click.prevent.stop="$store.dispatch('queue/next')" @click.prevent.stop="$store.dispatch('queue/next')"
> >
<i :class="['ui', {'disabled': !hasNext}, 'forward step', 'icon']" /> <i :class="['ui', {'disabled': !hasNext}, 'forward step', 'icon']" />
@ -237,76 +237,78 @@
</div> </div>
<table class="ui compact very basic fixed single line selectable unstackable table"> <table class="ui compact very basic fixed single line selectable unstackable table">
<draggable <draggable
v-model="tracks" v-model:list="tracks"
tag="tbody" tag="tbody"
handle=".handle" handle=".handle"
@update="reorder" @update="reorder"
item-key="id"
> >
<tr <template #item="{ element: track, index }">
v-for="(track, index) in tracks" <tr
:key="index" :key="track.id"
:class="['queue-item', {'active': index === queue.currentIndex}]" :class="['queue-item', {'active': index === queue.currentIndex}]"
>
<td class="handle">
<i class="grip lines icon" />
</td>
<td
class="image-cell"
@click="$store.dispatch('queue/currentIndex', index)"
> >
<img <td class="handle">
v-if="track.cover && track.cover.urls.original" <i class="grip lines icon" />
class="ui mini image" </td>
alt="" <td
:src="$store.getters['instance/absoluteUrl'](track.cover.urls.medium_square_crop)" class="image-cell"
@click="$store.dispatch('queue/currentIndex', index)"
> >
<img <img
v-else-if="track.album && track.album.cover && track.album.cover.urls.original" v-if="track.cover && track.cover.urls.original"
class="ui mini image" class="ui mini image"
alt="" alt=""
:src="$store.getters['instance/absoluteUrl'](track.album.cover.urls.medium_square_crop)" :src="$store.getters['instance/absoluteUrl'](track.cover.urls.medium_square_crop)"
>
<img
v-else-if="track.album && track.album.cover && track.album.cover.urls.original"
class="ui mini image"
alt=""
:src="$store.getters['instance/absoluteUrl'](track.album.cover.urls.medium_square_crop)"
>
<img
v-else
class="ui mini image"
alt=""
src="../assets/audio/default-cover.png"
>
</td>
<td
colspan="3"
@click="$store.dispatch('queue/currentIndex', index)"
> >
<img <button
v-else class="title reset ellipsis"
class="ui mini image" :title="track.title"
alt="" :aria-label="labels.selectTrack"
src="../assets/audio/default-cover.png" >
> <strong>{{ track.title }}</strong><br>
</td> <span>
<td
colspan="3"
@click="$store.dispatch('queue/currentIndex', index)"
>
<button
class="title reset ellipsis"
:title="track.title"
:aria-label="labels.selectTrack"
>
<strong>{{ track.title }}</strong><br>
<span>
{{ track.artist.name }} {{ track.artist.name }}
</span> </span>
</button> </button>
</td> </td>
<td class="duration-cell"> <td class="duration-cell">
<template v-if="track.uploads.length > 0"> <template v-if="track.uploads.length > 0">
{{ time.durationFormatted(track.uploads[0].duration) }} {{ time.durationFormatted(track.uploads[0].duration) }}
</template> </template>
</td> </td>
<td class="controls"> <td class="controls">
<template v-if="$store.getters['favorites/isFavorite'](track.id)"> <template v-if="$store.getters['favorites/isFavorite'](track.id)">
<i class="pink heart icon" /> <i class="pink heart icon" />
</template> </template>
<button <button
:aria-label="labels.removeFromQueue" :aria-label="labels.removeFromQueue"
:title="labels.removeFromQueue" :title="labels.removeFromQueue"
:class="['ui', 'really', 'tiny', 'basic', 'circular', 'icon', 'button']" :class="['ui', 'really', 'tiny', 'basic', 'circular', 'icon', 'button']"
@click.stop="cleanTrack(index)" @click.stop="cleanTrack(index)"
> >
<i class="x icon" /> <i class="x icon" />
</button> </button>
</td> </td>
</tr> </tr>
</template>
</draggable> </draggable>
</table> </table>
@ -450,7 +452,8 @@ export default {
this.$store.commit('ui/queueFocused', null) this.$store.commit('ui/queueFocused', null)
} }
}, },
immediate: true immediate: true,
deep: true
}, },
'$route.fullPath' () { '$route.fullPath' () {
this.$store.commit('ui/queueFocused', null) this.$store.commit('ui/queueFocused', null)

View File

@ -163,7 +163,6 @@ import axios from 'axios'
import TrackRow from '~/components/audio/track/Row.vue' import TrackRow from '~/components/audio/track/Row.vue'
import TrackMobileRow from '~/components/audio/track/MobileRow.vue' import TrackMobileRow from '~/components/audio/track/MobileRow.vue'
import Pagination from '~/components/Pagination.vue' import Pagination from '~/components/Pagination.vue'
import { unique } from '~/utils/filters'
export default { export default {
components: { components: {

View File

@ -127,46 +127,46 @@
<div class="table-wrapper"> <div class="table-wrapper">
<table class="ui compact very basic unstackable table"> <table class="ui compact very basic unstackable table">
<draggable <draggable
v-model="plts" v-model:list="plts"
tag="tbody" tag="tbody"
@update="reorder" @update="reorder"
item-key="_id"
> >
<tr <template #item="{ element: plt, index }">
v-for="(plt, index) in plts" <tr>
:key="`${index}-${plt.track.id}`" <td class="left aligned">
> {{ plt.index + 1 }}
<td class="left aligned"> </td>
{{ plt.index + 1 }} <td class="center aligned">
</td> <img
<td class="center aligned"> v-if="plt.track.album && plt.track.album.cover && plt.track.album.cover.urls.original"
<img v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.urls.medium_square_crop)"
v-if="plt.track.album && plt.track.album.cover && plt.track.album.cover.urls.original" alt=""
v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.urls.medium_square_crop)" class="ui mini image"
alt="" >
class="ui mini image" <img
> v-else
<img alt=""
v-else class="ui mini image"
alt="" src="../../assets/audio/default-cover.png"
class="ui mini image" >
src="../../assets/audio/default-cover.png" </td>
> <td colspan="4">
</td> <strong>{{ plt.track.title }}</strong><br>
<td colspan="4"> {{ plt.track.artist.name }}
<strong>{{ plt.track.title }}</strong><br> </td>
{{ plt.track.artist.name }} <td class="right aligned">
</td> <button
<td class="right aligned"> class="ui circular danger basic icon button"
<button @click.stop="removePlt(index)"
class="ui circular danger basic icon button" >
@click.stop="removePlt(index)" <i
> class="trash icon"
<i />
class="trash icon" </button>
/> </td>
</button> </tr>
</td> </template>
</tr>
</draggable> </draggable>
</table> </table>
</div> </div>
@ -177,6 +177,7 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { computed } from 'vue'
import axios from 'axios' import axios from 'axios'
import PlaylistForm from '~/components/playlists/Form.vue' import PlaylistForm from '~/components/playlists/Form.vue'
@ -191,9 +192,15 @@ export default {
playlist: { type: Object, required: true }, playlist: { type: Object, required: true },
playlistTracks: { type: Array, required: true } playlistTracks: { type: Array, required: true }
}, },
setup (props) {
const plts = computed(() => {
return props.playlistTracks.map((plt, index) => ({ ...plt, _id: `${index}-${plt.track.id}` }))
})
return { plts }
},
data () { data () {
return { return {
plts: this.playlistTracks,
isLoading: false, isLoading: false,
errors: [], errors: [],
duplicateTrackAddInfo: {}, duplicateTrackAddInfo: {},

View File

@ -6119,10 +6119,10 @@ slash@^3.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
sortablejs@1.10.2: sortablejs@1.14.0:
version "1.10.2" version "1.14.0"
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290" resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.14.0.tgz#6d2e17ccbdb25f464734df621d4f35d4ab35b3d8"
integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A== integrity sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
version "1.0.2" version "1.0.2"
@ -6809,12 +6809,12 @@ vue@^2.6.12:
"@vue/compiler-sfc" "2.7.10" "@vue/compiler-sfc" "2.7.10"
csstype "^3.1.0" csstype "^3.1.0"
vuedraggable@2.24.3: vuedraggable@^4.1.0:
version "2.24.3" version "4.1.0"
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19" resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-4.1.0.tgz#edece68adb8a4d9e06accff9dfc9040e66852270"
integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g== integrity sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==
dependencies: dependencies:
sortablejs "1.10.2" sortablejs "1.14.0"
vuex-persistedstate@4.1.0: vuex-persistedstate@4.1.0:
version "4.1.0" version "4.1.0"