2018-03-20 18:58:27 +00:00
|
|
|
<template>
|
2018-11-19 22:33:22 +00:00
|
|
|
<main>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div
|
|
|
|
v-if="isLoading"
|
|
|
|
v-title="labels.playlist"
|
|
|
|
class="ui vertical segment"
|
|
|
|
>
|
|
|
|
<div :class="['ui', 'centered', 'active', 'inline', 'loader']" />
|
2018-03-20 22:41:15 +00:00
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<section
|
|
|
|
v-if="!isLoading && playlist"
|
|
|
|
v-title="playlist.name"
|
|
|
|
class="ui head vertical center aligned stripe segment"
|
|
|
|
>
|
2018-03-20 18:58:27 +00:00
|
|
|
<div class="segment-content">
|
|
|
|
<h2 class="ui center aligned icon header">
|
2021-12-06 10:35:20 +00:00
|
|
|
<i class="circular inverted list warning icon" />
|
2018-03-20 18:58:27 +00:00
|
|
|
<div class="content">
|
|
|
|
{{ playlist.name }}
|
2018-07-17 11:09:13 +00:00
|
|
|
<div class="sub header">
|
|
|
|
<translate
|
|
|
|
translate-plural="Playlist containing %{ count } tracks, by %{ username }"
|
2019-01-05 15:28:53 +00:00
|
|
|
:translate-n="playlist.tracks_count"
|
2019-02-07 16:58:11 +00:00
|
|
|
:translate-params="{count: playlist.tracks_count, username: playlist.user.username}"
|
2021-12-06 10:35:20 +00:00
|
|
|
translate-context="Content/Playlist/Header.Subtitle"
|
|
|
|
>
|
|
|
|
Playlist containing %{ count } track, by %{ username }
|
2018-07-17 11:09:13 +00:00
|
|
|
</translate><br>
|
|
|
|
<duration :seconds="playlist.duration" />
|
|
|
|
</div>
|
2018-03-20 18:58:27 +00:00
|
|
|
</div>
|
|
|
|
</h2>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div class="ui hidden divider" />
|
2021-02-20 21:45:18 +00:00
|
|
|
<div class="header-buttons">
|
|
|
|
<div class="ui buttons">
|
2021-12-06 10:35:20 +00:00
|
|
|
<play-button
|
|
|
|
class="vibrant"
|
|
|
|
:is-playable="playlist.is_playable"
|
|
|
|
:tracks="tracks"
|
|
|
|
>
|
|
|
|
<translate translate-context="Content/Queue/Button.Label/Short, Verb">
|
|
|
|
Play all
|
|
|
|
</translate>
|
|
|
|
</play-button>
|
2021-02-20 21:45:18 +00:00
|
|
|
</div>
|
|
|
|
<div class="ui buttons">
|
|
|
|
<button
|
|
|
|
v-if="$store.state.auth.profile && playlist.user.id === $store.state.auth.profile.id"
|
2021-12-06 10:35:20 +00:00
|
|
|
class="ui icon labeled button"
|
|
|
|
@click="edit = !edit"
|
|
|
|
>
|
|
|
|
<i class="pencil icon" />
|
|
|
|
<template v-if="edit">
|
|
|
|
<translate translate-context="Content/Playlist/Button.Label/Verb">
|
|
|
|
Stop Editing
|
|
|
|
</translate>
|
|
|
|
</template>
|
|
|
|
<template v-else>
|
|
|
|
<translate translate-context="Content/*/Button.Label/Verb">
|
|
|
|
Edit
|
|
|
|
</translate>
|
|
|
|
</template>
|
2021-02-20 21:45:18 +00:00
|
|
|
</button>
|
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div class="ui buttons">
|
2021-02-20 21:45:18 +00:00
|
|
|
<button
|
|
|
|
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
2021-12-06 10:35:20 +00:00
|
|
|
class="ui icon labeled button"
|
|
|
|
@click="showEmbedModal = !showEmbedModal"
|
|
|
|
>
|
|
|
|
<i class="code icon" />
|
|
|
|
<translate translate-context="Content/*/Button.Label/Verb">
|
|
|
|
Embed
|
|
|
|
</translate>
|
2021-02-20 21:45:18 +00:00
|
|
|
</button>
|
2021-12-06 10:35:20 +00:00
|
|
|
<dangerous-button
|
|
|
|
v-if="$store.state.auth.profile && playlist.user.id === $store.state.auth.profile.id"
|
|
|
|
class="ui labeled danger icon button"
|
|
|
|
:action="deletePlaylist"
|
|
|
|
>
|
|
|
|
<i class="trash icon" /> <translate translate-context="*/*/*/Verb">
|
|
|
|
Delete
|
|
|
|
</translate>
|
|
|
|
<p
|
|
|
|
slot="modal-header"
|
|
|
|
v-translate="{playlist: playlist.name}"
|
|
|
|
translate-context="Popup/Playlist/Title/Call to action"
|
|
|
|
:translate-params="{playlist: playlist.name}"
|
|
|
|
>
|
|
|
|
Do you want to delete the playlist "%{ playlist }"?
|
2021-02-20 21:45:18 +00:00
|
|
|
</p>
|
2021-12-06 10:35:20 +00:00
|
|
|
<p slot="modal-content">
|
|
|
|
<translate translate-context="Popup/Playlist/Paragraph">
|
|
|
|
This will completely delete this playlist and cannot be undone.
|
|
|
|
</translate>
|
|
|
|
</p>
|
|
|
|
<div slot="modal-confirm">
|
|
|
|
<translate translate-context="Popup/Playlist/Button.Label/Verb">
|
|
|
|
Delete playlist
|
|
|
|
</translate>
|
|
|
|
</div>
|
2021-02-20 21:45:18 +00:00
|
|
|
</dangerous-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<modal
|
|
|
|
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
2022-05-01 11:45:07 +00:00
|
|
|
v-model:show="showEmbedModal"
|
2021-12-06 10:35:20 +00:00
|
|
|
>
|
|
|
|
<h4 class="header">
|
|
|
|
<translate translate-context="Popup/Album/Title/Verb">
|
|
|
|
Embed this playlist on your website
|
|
|
|
</translate>
|
|
|
|
</h4>
|
|
|
|
<div class="scrolling content">
|
|
|
|
<div class="description">
|
|
|
|
<embed-wizard
|
|
|
|
:id="playlist.id"
|
|
|
|
type="playlist"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="actions">
|
|
|
|
<button class="ui basic deny button">
|
|
|
|
<translate translate-context="*/*/Button.Label/Verb">
|
|
|
|
Cancel
|
|
|
|
</translate>
|
|
|
|
</button>
|
2019-09-12 07:48:28 +00:00
|
|
|
</div>
|
2021-02-20 21:45:18 +00:00
|
|
|
</modal>
|
|
|
|
</div>
|
2018-11-19 22:33:22 +00:00
|
|
|
</section>
|
|
|
|
<section class="ui vertical stripe segment">
|
2018-03-20 18:58:27 +00:00
|
|
|
<template v-if="edit">
|
2018-03-21 18:04:15 +00:00
|
|
|
<playlist-editor
|
2021-12-06 10:35:20 +00:00
|
|
|
:playlist="playlist"
|
|
|
|
:playlist-tracks="playlistTracks"
|
2018-03-21 18:04:15 +00:00
|
|
|
@playlist-updated="playlist = $event"
|
|
|
|
@tracks-updated="updatePlts"
|
2021-12-06 10:35:20 +00:00
|
|
|
/>
|
2018-03-20 18:58:27 +00:00
|
|
|
</template>
|
2019-10-17 12:15:33 +00:00
|
|
|
<template v-else-if="tracks.length > 0">
|
2021-12-06 10:35:20 +00:00
|
|
|
<h2>
|
|
|
|
<translate translate-context="*/*/*">
|
|
|
|
Tracks
|
|
|
|
</translate>
|
|
|
|
</h2>
|
|
|
|
<track-table
|
|
|
|
:display-position="true"
|
|
|
|
:tracks="tracks"
|
|
|
|
/>
|
2018-03-20 18:58:27 +00:00
|
|
|
</template>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div
|
|
|
|
v-else
|
|
|
|
class="ui placeholder segment"
|
|
|
|
>
|
2019-10-17 12:15:33 +00:00
|
|
|
<div class="ui icon header">
|
2021-12-06 10:35:20 +00:00
|
|
|
<i class="list icon" />
|
|
|
|
<translate translate-context="Content/Home/Placeholder">
|
|
|
|
There are no tracks in this playlist yet
|
|
|
|
</translate>
|
2019-10-17 12:15:33 +00:00
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<button
|
|
|
|
class="ui success icon labeled button"
|
|
|
|
@click="edit = !edit"
|
|
|
|
>
|
|
|
|
<i class="pencil icon" />
|
|
|
|
<translate translate-context="Content/Home/CreatePlaylist">
|
|
|
|
Edit
|
|
|
|
</translate>
|
2019-10-17 12:15:33 +00:00
|
|
|
</button>
|
|
|
|
</div>
|
2018-11-19 22:33:22 +00:00
|
|
|
</section>
|
|
|
|
</main>
|
2018-03-20 18:58:27 +00:00
|
|
|
</template>
|
|
|
|
<script>
|
2021-12-06 10:35:20 +00:00
|
|
|
import axios from 'axios'
|
2022-04-23 07:37:43 +00:00
|
|
|
import TrackTable from '~/components/audio/track/Table.vue'
|
|
|
|
import PlayButton from '~/components/audio/PlayButton.vue'
|
|
|
|
import PlaylistEditor from '~/components/playlists/Editor.vue'
|
|
|
|
import EmbedWizard from '~/components/audio/EmbedWizard.vue'
|
|
|
|
import Modal from '~/components/semantic/Modal.vue'
|
2018-03-20 18:58:27 +00:00
|
|
|
|
|
|
|
export default {
|
|
|
|
components: {
|
|
|
|
PlaylistEditor,
|
|
|
|
TrackTable,
|
|
|
|
PlayButton,
|
2019-09-12 07:48:28 +00:00
|
|
|
Modal,
|
2021-12-06 10:35:20 +00:00
|
|
|
EmbedWizard
|
2018-03-20 18:58:27 +00:00
|
|
|
},
|
2021-12-06 10:35:20 +00:00
|
|
|
props: {
|
2021-12-08 18:48:06 +00:00
|
|
|
id: { type: [Number, String], required: true },
|
2021-12-06 10:35:20 +00:00
|
|
|
defaultEdit: { type: Boolean, default: false }
|
|
|
|
},
|
|
|
|
data: function () {
|
2018-03-20 18:58:27 +00:00
|
|
|
return {
|
2018-03-20 22:41:15 +00:00
|
|
|
edit: this.defaultEdit,
|
|
|
|
isLoading: false,
|
2018-03-20 18:58:27 +00:00
|
|
|
playlist: null,
|
|
|
|
tracks: [],
|
2019-09-12 07:48:28 +00:00
|
|
|
playlistTracks: [],
|
2021-12-06 10:35:20 +00:00
|
|
|
showEmbedModal: false
|
2018-03-20 18:58:27 +00:00
|
|
|
}
|
|
|
|
},
|
2018-07-01 19:50:50 +00:00
|
|
|
computed: {
|
2021-12-06 10:35:20 +00:00
|
|
|
labels () {
|
2018-07-01 19:50:50 +00:00
|
|
|
return {
|
2019-10-01 13:19:55 +00:00
|
|
|
playlist: this.$pgettext('*/*/*', 'Playlist')
|
2018-07-01 19:50:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2021-12-06 10:35:20 +00:00
|
|
|
created: function () {
|
|
|
|
this.fetch()
|
|
|
|
},
|
2018-03-20 18:58:27 +00:00
|
|
|
methods: {
|
2021-12-06 10:35:20 +00:00
|
|
|
updatePlts (v) {
|
2018-03-20 18:58:27 +00:00
|
|
|
this.playlistTracks = v
|
|
|
|
this.tracks = v.map((e, i) => {
|
2021-12-06 10:35:20 +00:00
|
|
|
const track = e.track
|
2018-03-20 18:58:27 +00:00
|
|
|
track.position = i + 1
|
|
|
|
return track
|
|
|
|
})
|
|
|
|
},
|
2021-12-06 10:35:20 +00:00
|
|
|
fetch: function () {
|
|
|
|
const self = this
|
2018-03-20 22:41:15 +00:00
|
|
|
self.isLoading = true
|
2021-12-06 10:35:20 +00:00
|
|
|
const url = 'playlists/' + this.id + '/'
|
2018-11-19 22:33:22 +00:00
|
|
|
axios.get(url).then(response => {
|
2018-03-20 18:58:27 +00:00
|
|
|
self.playlist = response.data
|
2018-11-19 22:33:22 +00:00
|
|
|
axios
|
2021-12-06 10:35:20 +00:00
|
|
|
.get(url + 'tracks/')
|
2018-11-19 22:33:22 +00:00
|
|
|
.then(response => {
|
|
|
|
self.updatePlts(response.data.results)
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
self.isLoading = false
|
|
|
|
})
|
2018-03-20 22:41:15 +00:00
|
|
|
})
|
|
|
|
},
|
2021-12-06 10:35:20 +00:00
|
|
|
deletePlaylist () {
|
|
|
|
const self = this
|
|
|
|
const url = 'playlists/' + this.id + '/'
|
2018-11-19 22:33:22 +00:00
|
|
|
axios.delete(url).then(response => {
|
2021-12-06 10:35:20 +00:00
|
|
|
self.$store.dispatch('playlists/fetchOwn')
|
2018-03-20 22:41:15 +00:00
|
|
|
self.$router.push({
|
2021-12-06 10:35:20 +00:00
|
|
|
path: '/library'
|
2018-03-20 18:58:27 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|