Prettier playlist edition
This commit is contained in:
parent
71d46e4361
commit
a7e3828f6f
|
@ -1,8 +1,28 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="ui text container">
|
<div class="ui text container">
|
||||||
<h2 class="ui header">Playlist editor</h2>
|
<playlist-form @updated="$emit('playlist-updated', $event)" :title="false" :playlist="playlist"></playlist-form>
|
||||||
<p>Drag and drop rows to reorder tracks in the playlist</p>
|
<h3 class="ui top attached header">
|
||||||
<div>
|
Playlist editor
|
||||||
|
</h3>
|
||||||
|
<div class="ui attached segment">
|
||||||
|
<template v-if="status === 'loading'">
|
||||||
|
<div class="ui active tiny inline loader"></div>
|
||||||
|
Syncing changes to server...
|
||||||
|
</template>
|
||||||
|
<template v-else-if="status === 'errored'">
|
||||||
|
<i class="red close icon"></i>
|
||||||
|
An error occured while saving your changes
|
||||||
|
<div v-if="errors.length > 0" class="ui negative message">
|
||||||
|
<ul class="list">
|
||||||
|
<li v-for="error in errors">{{ error }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="status === 'saved'">
|
||||||
|
<i class="green check icon"></i> Changes synced with server
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="ui bottom attached segment">
|
||||||
<div
|
<div
|
||||||
@click="insertMany(queueTracks)"
|
@click="insertMany(queueTracks)"
|
||||||
:disabled="queueTracks.length === 0"
|
:disabled="queueTracks.length === 0"
|
||||||
|
@ -16,56 +36,43 @@
|
||||||
<p slot="modal-content">This will remove all tracks from this playlist and cannot be undone.</p>
|
<p slot="modal-content">This will remove all tracks from this playlist and cannot be undone.</p>
|
||||||
<p slot="modal-confirm">Clear playlist</p>
|
<p slot="modal-confirm">Clear playlist</p>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
</div>
|
<div class="ui hidden divider"></div>
|
||||||
<h5 class="ui header">Status</h5>
|
<template v-if="plts.length > 0">
|
||||||
<div>
|
<p>Drag and drop rows to reorder tracks in the playlist</p>
|
||||||
<template v-if="status === 'loading'">
|
<table class="ui compact very basic fixed single line unstackable table">
|
||||||
<div class="ui active tiny inline loader"></div>
|
<draggable v-model="plts" element="tbody" @update="reorder">
|
||||||
Syncing changes to server...
|
<tr v-for="(plt, index) in plts" :key="plt.id">
|
||||||
</template>
|
<td class="left aligned">{{ plt.index + 1}}</td>
|
||||||
<template v-else-if="status === 'errored'">
|
<td class="center aligned">
|
||||||
<i class="red x icon"></i>
|
<img class="ui mini image" v-if="plt.track.album.cover" :src="plt.track.album.cover">
|
||||||
An error occured while saving your changes
|
<img class="ui mini image" v-else src="../../assets/audio/default-cover.png">
|
||||||
<div v-if="errors.length > 0" class="ui negative message">
|
</td>
|
||||||
<ul class="list">
|
<td colspan="4">
|
||||||
<li v-for="error in errors">{{ error }}</li>
|
<strong>{{ plt.track.title }}</strong><br />
|
||||||
</ul>
|
{{ plt.track.artist.name }}
|
||||||
</div>
|
</td>
|
||||||
</template>
|
<td class="right aligned">
|
||||||
<template v-else-if="status === 'saved'">
|
<i @click.stop="removePlt(index)" class="circular red trash icon"></i>
|
||||||
<i class="green check icon"></i> Changes synced with server
|
</td>
|
||||||
|
</tr>
|
||||||
|
</draggable>
|
||||||
|
</table>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<table class="ui compact very basic fixed single line unstackable table">
|
|
||||||
<draggable v-model="plts" element="tbody" @update="reorder">
|
|
||||||
<tr v-for="(plt, index) in plts" :key="plt.id">
|
|
||||||
<td class="left aligned">{{ plt.index + 1}}</td>
|
|
||||||
<td class="center aligned">
|
|
||||||
<img class="ui mini image" v-if="plt.track.album.cover" :src="plt.track.album.cover">
|
|
||||||
<img class="ui mini image" v-else src="../../assets/audio/default-cover.png">
|
|
||||||
</td>
|
|
||||||
<td colspan="4">
|
|
||||||
<strong>{{ plt.track.title }}</strong><br />
|
|
||||||
{{ plt.track.artist.name }}
|
|
||||||
</td>
|
|
||||||
<td class="right aligned">
|
|
||||||
<i @click.stop="removePlt(index)" class="circular red trash icon"></i>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</draggable>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapState} from 'vuex'
|
import {mapState} from 'vuex'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import PlaylistForm from '@/components/playlists/Form'
|
||||||
|
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
draggable
|
draggable,
|
||||||
|
PlaylistForm
|
||||||
},
|
},
|
||||||
props: ['playlist', 'playlistTracks'],
|
props: ['playlist', 'playlistTracks'],
|
||||||
data () {
|
data () {
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<form class="ui form" @submit.prevent="submit()">
|
<form class="ui form" @submit.prevent="submit()">
|
||||||
<h4 class="ui header">Create a new playlist</h4>
|
<h4 v-if="title" class="ui header">Create a new playlist</h4>
|
||||||
<div v-if="success" class="ui positive message">
|
<div v-if="success" class="ui positive message">
|
||||||
<div class="header">Playlist created</div>
|
<div class="header">
|
||||||
|
<template v-if="playlist">
|
||||||
|
Playlist updated
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Playlist created
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="errors.length > 0" class="ui negative message">
|
<div v-if="errors.length > 0" class="ui negative message">
|
||||||
<div class="header">We cannot create the playlist</div>
|
<div class="header">We cannot create the playlist</div>
|
||||||
|
@ -10,7 +17,7 @@
|
||||||
<li v-for="error in errors">{{ error }}</li>
|
<li v-for="error in errors">{{ error }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="fields">
|
<div class="three fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Playlist name</label>
|
<label>Playlist name</label>
|
||||||
<input v-model="name" required type="text" placeholder="My awesome playlist" />
|
<input v-model="name" required type="text" placeholder="My awesome playlist" />
|
||||||
|
@ -23,7 +30,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label> </label>
|
<label> </label>
|
||||||
<button :class="['ui', {'loading': isLoading}, 'button']" type="submit">Create playlist</button>
|
<button :class="['ui', 'fluid', {'loading': isLoading}, 'button']" type="submit">
|
||||||
|
<template v-if="playlist">Update playlist</template>
|
||||||
|
<template v-else>Create playlist</template>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -36,13 +46,15 @@ import axios from 'axios'
|
||||||
import logger from '@/logging'
|
import logger from '@/logging'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: {
|
||||||
|
title: {type: Boolean, default: true},
|
||||||
|
playlist: {type: Object, default: null}
|
||||||
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
$(this.$el).find('.dropdown').dropdown()
|
$(this.$el).find('.dropdown').dropdown()
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
let d = {
|
||||||
privacyLevel: this.$store.state.auth.profile.privacy_level,
|
|
||||||
name: '',
|
|
||||||
errors: [],
|
errors: [],
|
||||||
success: false,
|
success: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
@ -61,6 +73,14 @@ export default {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
if (this.playlist) {
|
||||||
|
d.name = this.playlist.name
|
||||||
|
d.privacyLevel = this.playlist.privacy_level
|
||||||
|
} else {
|
||||||
|
d.privacyLevel = this.$store.state.auth.profile.privacy_level
|
||||||
|
d.name = ''
|
||||||
|
}
|
||||||
|
return d
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submit () {
|
submit () {
|
||||||
|
@ -72,12 +92,23 @@ export default {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
privacy_level: this.privacyLevel
|
privacy_level: this.privacyLevel
|
||||||
}
|
}
|
||||||
let url = `playlists/`
|
|
||||||
return axios.post(url, payload).then(response => {
|
let promise
|
||||||
logger.default.info('Successfully created playlist')
|
let url
|
||||||
|
if (this.playlist) {
|
||||||
|
url = `playlists/${this.playlist.id}/`
|
||||||
|
promise = axios.patch(url, payload)
|
||||||
|
} else {
|
||||||
|
url = 'playlists/'
|
||||||
|
promise = axios.post(url, payload)
|
||||||
|
}
|
||||||
|
return promise.then(response => {
|
||||||
self.success = true
|
self.success = true
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
self.name = ''
|
if (!self.playlist) {
|
||||||
|
self.name = ''
|
||||||
|
}
|
||||||
|
self.$emit('updated', response.data)
|
||||||
self.$store.dispatch('playlists/fetchOwn')
|
self.$store.dispatch('playlists/fetchOwn')
|
||||||
}, error => {
|
}, error => {
|
||||||
logger.default.error('Error while creating playlist')
|
logger.default.error('Error while creating playlist')
|
||||||
|
|
|
@ -36,7 +36,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="ui vertical stripe segment">
|
<div class="ui vertical stripe segment">
|
||||||
<template v-if="edit">
|
<template v-if="edit">
|
||||||
<playlist-editor @tracks-updated="updatePlts" :playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor>
|
<playlist-editor
|
||||||
|
@playlist-updated="playlist = $event"
|
||||||
|
@tracks-updated="updatePlts"
|
||||||
|
:playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<h2>Tracks</h2>
|
<h2>Tracks</h2>
|
||||||
|
|
Loading…
Reference in New Issue