mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-03 09:56:00 -05:00
[web-src] Refactor details modal dialogs into separate components
This will allow to open a dialog outside of the ListItem component. Also reduces the size of the generated DOM tree by only including one dialog per page (per object type) and not for each list item.
This commit is contained in:
parent
0cc4699128
commit
5e85e0b024
@ -5,56 +5,15 @@
|
|||||||
<h2 class="subtitle is-7 has-text-grey"><b>{{ album.artist }}</b></h2>
|
<h2 class="subtitle is-7 has-text-grey"><b>{{ album.artist }}</b></h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div class="media-right">
|
||||||
<a @click="show_details_modal = true">
|
<slot name="actions"></slot>
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<modal-dialog :show="show_details_modal" @close="show_details_modal = false">
|
|
||||||
<template slot="modal-content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="title is-4">
|
|
||||||
<a class="has-text-link" @click="open_album">{{ album.name }}</a>
|
|
||||||
</p>
|
|
||||||
<div class="content is-small">
|
|
||||||
<p v-if="album.artist && media_kind !== 'audiobook'">
|
|
||||||
<span class="heading">Album artist</span>
|
|
||||||
<a class="title is-6 has-text-link" @click="open_artist">{{ album.artist }}</a>
|
|
||||||
</p>
|
|
||||||
<p v-if="album.artist && media_kind === 'audiobook'">
|
|
||||||
<span class="heading">Album artist</span>
|
|
||||||
<span class="title is-6">{{ album.artist }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Tracks</span>
|
|
||||||
<span class="title is-6">{{ album.track_count }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="card-footer">
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="play">
|
|
||||||
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</modal-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from '@/components/ModalDialog'
|
|
||||||
import webapi from '@/webapi'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ListItemAlbum',
|
name: 'ListItemAlbum',
|
||||||
components: { ModalDialog },
|
components: {},
|
||||||
|
|
||||||
props: ['album', 'media_kind', 'anchor'],
|
props: ['album', 'media_kind', 'anchor'],
|
||||||
|
|
||||||
@ -65,25 +24,6 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.player_play_uri(this.album.uri, false)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add(this.album.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add_next: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add_next(this.album.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
open_album: function () {
|
open_album: function () {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
if (this.media_kind === 'podcast') {
|
if (this.media_kind === 'podcast') {
|
||||||
@ -93,11 +33,6 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.$router.push({ path: '/music/albums/' + this.album.id })
|
this.$router.push({ path: '/music/albums/' + this.album.id })
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
open_artist: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
this.$router.push({ path: '/music/artists/' + this.album.artist_id })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,83 +4,20 @@
|
|||||||
<h1 class="title is-6">{{ artist.name }}</h1>
|
<h1 class="title is-6">{{ artist.name }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div class="media-right">
|
||||||
<a @click="show_details_modal = true">
|
<slot name="actions"></slot>
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<modal-dialog :show="show_details_modal" @close="show_details_modal = false">
|
|
||||||
<template slot="modal-content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="title is-4">
|
|
||||||
<a class="has-text-link" @click="open_artist">{{ artist.name }}</a>
|
|
||||||
</p>
|
|
||||||
<div class="content is-small">
|
|
||||||
<p>
|
|
||||||
<span class="heading">Albums</span>
|
|
||||||
<span class="title is-6">{{ artist.album_count }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Tracks</span>
|
|
||||||
<span class="title is-6">{{ artist.track_count }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="card-footer">
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="play">
|
|
||||||
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</modal-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from '@/components/ModalDialog'
|
|
||||||
import webapi from '@/webapi'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PartArtist',
|
name: 'ListItemArtist',
|
||||||
components: { ModalDialog },
|
components: {},
|
||||||
|
|
||||||
props: ['artist', 'anchor'],
|
props: ['artist', 'anchor'],
|
||||||
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.player_play_uri(this.artist.uri, false)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add(this.artist.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Artist tracks appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add_next: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add_next(this.artist.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
open_artist: function () {
|
open_artist: function () {
|
||||||
this.show_details_modal = false
|
|
||||||
this.$router.push({ path: '/music/artists/' + this.artist.id })
|
this.$router.push({ path: '/music/artists/' + this.artist.id })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,89 +4,19 @@
|
|||||||
<h1 class="title is-6">{{ genre.name }}</h1>
|
<h1 class="title is-6">{{ genre.name }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div class="media-right">
|
||||||
<a @click="show_details_modal = true">
|
<slot name="actions"></slot>
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<modal-dialog :show="show_details_modal" @close="show_details_modal = false">
|
|
||||||
<template slot="modal-content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="title is-4">
|
|
||||||
<a class="has-text-link" @click="open_genre">{{ genre.name }}</a>
|
|
||||||
</p>
|
|
||||||
<!--
|
|
||||||
<div class="content is-small">
|
|
||||||
<p>
|
|
||||||
<span class="heading">Albums</span>
|
|
||||||
<span class="title is-6">{{ genre.album_count }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Tracks</span>
|
|
||||||
<span class="title is-6">{{ genre.track_count }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
<footer class="card-footer">
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-plus mdi-12px"></i></span> <span>Add</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-play mdi-12px"></i></span> <span>Add Next</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="play">
|
|
||||||
<span class="icon"><i class="mdi mdi-play mdi-12px"></i></span> <span>Play</span>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</modal-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from '@/components/ModalDialog'
|
|
||||||
import webapi from '@/webapi'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PartGenre',
|
name: 'ListItemGenre',
|
||||||
components: { ModalDialog },
|
components: {},
|
||||||
|
|
||||||
props: [ 'genre', 'anchor' ],
|
props: [ 'genre', 'anchor' ],
|
||||||
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.library_genre(this.genre.name).then(({ data }) =>
|
|
||||||
webapi.player_play_uri(data.albums.items.map(a => a.uri).join(','), false)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.library_genre(this.genre.name).then(({ data }) =>
|
|
||||||
webapi.queue_add(data.albums.items.map(a => a.uri).join(',')).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Genre albums appended to queue', type: 'info', timeout: 1500 })
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add_next: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.library_genre(this.genre.name).then(({ data }) =>
|
|
||||||
webapi.queue_add_next(data.albums.items.map(a => a.uri).join(',')).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Genre albums playing next', type: 'info', timeout: 1500 })
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
open_genre: function () {
|
open_genre: function () {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
this.$router.push({ name: 'Genre', params: { genre: this.genre.name } })
|
this.$router.push({ name: 'Genre', params: { genre: this.genre.name } })
|
||||||
|
@ -4,77 +4,19 @@
|
|||||||
<h1 class="title is-6">{{ playlist.name }}</h1>
|
<h1 class="title is-6">{{ playlist.name }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div class="media-right">
|
||||||
<a @click="show_details_modal = true">
|
<slot name="actions"></slot>
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<modal-dialog :show="show_details_modal" @close="show_details_modal = false">
|
|
||||||
<template slot="modal-content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="title is-4">
|
|
||||||
<a class="has-text-link" @click="open_playlist">{{ playlist.name }}</a>
|
|
||||||
</p>
|
|
||||||
<div class="content is-small">
|
|
||||||
<p>
|
|
||||||
<span class="heading">Path</span>
|
|
||||||
<span class="title is-6">{{ playlist.path }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="card-footer">
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="play">
|
|
||||||
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</modal-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from '@/components/ModalDialog'
|
|
||||||
import webapi from '@/webapi'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PartPlaylist',
|
name: 'ListItemPlaylist',
|
||||||
components: { ModalDialog },
|
components: {},
|
||||||
|
|
||||||
props: ['playlist'],
|
props: ['playlist'],
|
||||||
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.player_play_uri(this.playlist.uri, false)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add(this.playlist.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Playlist appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add_next: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add_next(this.playlist.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
open_playlist: function () {
|
open_playlist: function () {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
this.$router.push({ path: '/playlists/' + this.playlist.id })
|
this.$router.push({ path: '/playlists/' + this.playlist.id })
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="media" v-if="is_next || !show_only_next_items">
|
<div class="media" v-if="is_next || !show_only_next_items">
|
||||||
<!---->
|
|
||||||
<div class="media-left" v-if="edit_mode">
|
<div class="media-left" v-if="edit_mode">
|
||||||
<span class="icon has-text-grey fd-is-movable handle"><i class="mdi mdi-drag-horizontal mdi-18px"></i></span>
|
<span class="icon has-text-grey fd-is-movable handle"><i class="mdi mdi-drag-horizontal mdi-18px"></i></span>
|
||||||
</div>
|
</div>
|
||||||
@ -11,75 +10,17 @@
|
|||||||
<h2 class="subtitle is-7" :class="{ 'has-text-primary': item.id === state.item_id, 'has-text-grey-light': !is_next, 'has-text-grey': is_next && item.id !== state.item_id }">{{ item.album }}</h2>
|
<h2 class="subtitle is-7" :class="{ 'has-text-primary': item.id === state.item_id, 'has-text-grey-light': !is_next, 'has-text-grey': is_next && item.id !== state.item_id }">{{ item.album }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div class="media-right">
|
||||||
<a v-on:click="remove" v-if="item.id !== state.item_id && edit_mode">
|
<slot name="actions"></slot>
|
||||||
<span class="icon has-text-grey"><i class="mdi mdi-delete mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<a @click="show_details_modal = true" v-if="!edit_mode">
|
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<modal-dialog v-if="!edit_mode" :show="show_details_modal" @close="show_details_modal = false">
|
|
||||||
<template slot="modal-content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="title is-4">
|
|
||||||
{{ item.title }}
|
|
||||||
</p>
|
|
||||||
<p class="subtitle">
|
|
||||||
{{ item.artist }}
|
|
||||||
</p>
|
|
||||||
<div class="content is-small">
|
|
||||||
<p>
|
|
||||||
<span class="heading">Album</span>
|
|
||||||
<span class="title is-6">{{ item.album }}</span>
|
|
||||||
</p>
|
|
||||||
<p v-if="item.album_artist">
|
|
||||||
<span class="heading">Album artist</span>
|
|
||||||
<span class="title is-6">{{ item.album_artist }}</span>
|
|
||||||
</p>
|
|
||||||
<p v-if="item.year > 0">
|
|
||||||
<span class="heading">Year</span>
|
|
||||||
<span class="title is-6">{{ item.year }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Genre</span>
|
|
||||||
<span class="title is-6">{{ item.genre }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Track / Disc</span>
|
|
||||||
<span class="title is-6">{{ item.track_number }} / {{ item.disc_number }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Length</span>
|
|
||||||
<span class="title is-6">{{ item.length_ms | duration }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Path</span>
|
|
||||||
<span class="title is-6">{{ item.path }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="card-footer">
|
|
||||||
<a class="card-footer-item has-text-dark" @click="remove">
|
|
||||||
<span class="icon"><i class="mdi mdi-delete mdi-18px"></i></span> <span>Remove</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="play">
|
|
||||||
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</modal-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from '@/components/ModalDialog'
|
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PartQueueItem',
|
name: 'ListItemQueueItem',
|
||||||
components: { ModalDialog },
|
components: {},
|
||||||
|
|
||||||
props: ['item', 'position', 'current_position', 'show_only_next_items', 'edit_mode'],
|
props: ['item', 'position', 'current_position', 'show_only_next_items', 'edit_mode'],
|
||||||
|
|
||||||
@ -100,11 +41,6 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
remove: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_remove(this.item.id)
|
|
||||||
},
|
|
||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
webapi.player_play({ 'item_id': this.item.id })
|
webapi.player_play({ 'item_id': this.item.id })
|
||||||
|
@ -6,135 +6,28 @@
|
|||||||
<h2 class="subtitle is-7 has-text-grey">{{ track.album }}</h2>
|
<h2 class="subtitle is-7 has-text-grey">{{ track.album }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div class="media-right">
|
||||||
<a @click="show_details_modal = true">
|
<slot name="actions"></slot>
|
||||||
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
|
||||||
</a>
|
|
||||||
<modal-dialog :show="show_details_modal" @close="show_details_modal = false">
|
|
||||||
<template slot="modal-content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="title is-4">
|
|
||||||
{{ track.title }}
|
|
||||||
</p>
|
|
||||||
<p class="subtitle">
|
|
||||||
{{ track.artist }}
|
|
||||||
</p>
|
|
||||||
<div class="content is-small">
|
|
||||||
<p>
|
|
||||||
<span class="heading">Album</span>
|
|
||||||
<a class="title is-6 has-text-link" @click="open_album">{{ track.album }}</a>
|
|
||||||
</p>
|
|
||||||
<p v-if="track.album_artist && track.media_kind !== 'audiobook'">
|
|
||||||
<span class="heading">Album artist</span>
|
|
||||||
<a class="title is-6 has-text-link" @click="open_artist">{{ track.album_artist }}</a>
|
|
||||||
</p>
|
|
||||||
<p v-if="track.date_released">
|
|
||||||
<span class="heading">Release date</span>
|
|
||||||
<span class="title is-6">{{ track.date_released | time('L')}}</span>
|
|
||||||
</p>
|
|
||||||
<p v-else-if="track.year > 0">
|
|
||||||
<span class="heading">Year</span>
|
|
||||||
<span class="title is-6">{{ track.year }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Genre</span>
|
|
||||||
<span class="title is-6">{{ track.genre }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Track / Disc</span>
|
|
||||||
<span class="title is-6">{{ track.track_number }} / {{ track.disc_number }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Length</span>
|
|
||||||
<span class="title is-6">{{ track.length_ms | duration }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Path</span>
|
|
||||||
<span class="title is-6">{{ track.path }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Type</span>
|
|
||||||
<span class="title is-6">{{ track.media_kind }} - {{ track.data_kind }}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="heading">Added at</span>
|
|
||||||
<span class="title is-6">{{ track.time_added | time('L LT')}}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="card-footer">
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
|
||||||
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
|
||||||
</a>
|
|
||||||
<a class="card-footer-item has-text-dark" @click="play_track">
|
|
||||||
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</modal-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from '@/components/ModalDialog'
|
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PartTrack',
|
name: 'ListItemTrack',
|
||||||
components: { ModalDialog },
|
components: {},
|
||||||
|
|
||||||
props: ['track', 'position', 'context_uri'],
|
props: ['track', 'position', 'context_uri'],
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
show_details_modal: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
play: function () {
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.player_play_uri(this.context_uri, false, this.position)
|
webapi.player_play_uri(this.context_uri, false, this.position)
|
||||||
},
|
|
||||||
|
|
||||||
play_track: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.player_play_uri(this.track.uri, false)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add(this.track.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Track appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
queue_add_next: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
webapi.queue_add_next(this.track.uri).then(() =>
|
|
||||||
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
open_album: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
if (this.track.media_kind === 'podcast') {
|
|
||||||
this.$router.push({ path: '/podcasts/' + this.track.album_id })
|
|
||||||
} else if (this.track.media_kind === 'audiobook') {
|
|
||||||
this.$router.push({ path: '/audiobooks/' + this.track.album_id })
|
|
||||||
} else {
|
|
||||||
this.$router.push({ path: '/music/albums/' + this.track.album_id })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
open_artist: function () {
|
|
||||||
this.show_details_modal = false
|
|
||||||
this.$router.push({ path: '/music/artists/' + this.track.album_artist_id })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
93
web-src/src/components/ModalDialogAlbum.vue
Normal file
93
web-src/src/components/ModalDialogAlbum.vue
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="modal is-active" v-if="show">
|
||||||
|
<div class="modal-background" @click="$emit('close')"></div>
|
||||||
|
<div class="modal-content fd-modal-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title is-4">
|
||||||
|
<a class="has-text-link" @click="open_album">{{ album.name }}</a>
|
||||||
|
</p>
|
||||||
|
<div class="content is-small">
|
||||||
|
<p v-if="album.artist && media_kind !== 'audiobook'">
|
||||||
|
<span class="heading">Album artist</span>
|
||||||
|
<a class="title is-6 has-text-link" @click="open_artist">{{ album.artist }}</a>
|
||||||
|
</p>
|
||||||
|
<p v-if="album.artist && media_kind === 'audiobook'">
|
||||||
|
<span class="heading">Album artist</span>
|
||||||
|
<span class="title is-6">{{ album.artist }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Tracks</span>
|
||||||
|
<span class="title is-6">{{ album.track_count }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="play">
|
||||||
|
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close" @click="$emit('close')"></button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalDialogAlbum',
|
||||||
|
props: [ 'show', 'album', 'media_kind' ],
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
play: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.player_play_uri(this.album.uri, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add(this.album.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add_next: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add_next(this.album.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_album: function () {
|
||||||
|
this.show_details_modal = false
|
||||||
|
if (this.media_kind === 'podcast') {
|
||||||
|
this.$router.push({ path: '/podcasts/' + this.album.id })
|
||||||
|
} else if (this.media_kind === 'audiobook') {
|
||||||
|
this.$router.push({ path: '/audiobooks/' + this.album.id })
|
||||||
|
} else {
|
||||||
|
this.$router.push({ path: '/music/albums/' + this.album.id })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
open_artist: function () {
|
||||||
|
this.show_details_modal = false
|
||||||
|
this.$router.push({ path: '/music/artists/' + this.album.artist_id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
78
web-src/src/components/ModalDialogArtist.vue
Normal file
78
web-src/src/components/ModalDialogArtist.vue
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="modal is-active" v-if="show">
|
||||||
|
<div class="modal-background" @click="$emit('close')"></div>
|
||||||
|
<div class="modal-content fd-modal-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title is-4">
|
||||||
|
<a class="has-text-link" @click="open_artist">{{ artist.name }}</a>
|
||||||
|
</p>
|
||||||
|
<div class="content is-small">
|
||||||
|
<p>
|
||||||
|
<span class="heading">Albums</span>
|
||||||
|
<span class="title is-6">{{ artist.album_count }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Tracks</span>
|
||||||
|
<span class="title is-6">{{ artist.track_count }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="play">
|
||||||
|
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close" @click="$emit('close')"></button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalDialogArtist',
|
||||||
|
props: [ 'show', 'artist' ],
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
play: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.player_play_uri(this.artist.uri, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add(this.artist.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Artist tracks appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add_next: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add_next(this.artist.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_artist: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
this.$router.push({ path: '/music/artists/' + this.artist.id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
74
web-src/src/components/ModalDialogGenre.vue
Normal file
74
web-src/src/components/ModalDialogGenre.vue
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="modal is-active" v-if="show">
|
||||||
|
<div class="modal-background" @click="$emit('close')"></div>
|
||||||
|
<div class="modal-content fd-modal-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title is-4">
|
||||||
|
<a class="has-text-link" @click="open_genre">{{ genre.name }}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-plus mdi-12px"></i></span> <span>Add</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-play mdi-12px"></i></span> <span>Add Next</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="play">
|
||||||
|
<span class="icon"><i class="mdi mdi-play mdi-12px"></i></span> <span>Play</span>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close" @click="$emit('close')"></button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalDialogGenre',
|
||||||
|
props: [ 'show', 'genre' ],
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
play: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.library_genre(this.genre.name).then(({ data }) =>
|
||||||
|
webapi.player_play_uri(data.albums.items.map(a => a.uri).join(','), false)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.library_genre(this.genre.name).then(({ data }) =>
|
||||||
|
webapi.queue_add(data.albums.items.map(a => a.uri).join(',')).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Genre albums appended to queue', type: 'info', timeout: 1500 })
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add_next: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.library_genre(this.genre.name).then(({ data }) =>
|
||||||
|
webapi.queue_add_next(data.albums.items.map(a => a.uri).join(',')).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Genre albums playing next', type: 'info', timeout: 1500 })
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_genre: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
this.$router.push({ name: 'Genre', params: { genre: this.genre.name } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
74
web-src/src/components/ModalDialogPlaylist.vue
Normal file
74
web-src/src/components/ModalDialogPlaylist.vue
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="modal is-active" v-if="show">
|
||||||
|
<div class="modal-background" @click="$emit('close')"></div>
|
||||||
|
<div class="modal-content fd-modal-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title is-4">
|
||||||
|
<a class="has-text-link" @click="open_playlist">{{ playlist.name }}</a>
|
||||||
|
</p>
|
||||||
|
<div class="content is-small">
|
||||||
|
<p>
|
||||||
|
<span class="heading">Path</span>
|
||||||
|
<span class="title is-6">{{ playlist.path }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="play">
|
||||||
|
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close" @click="$emit('close')"></button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalDialogPlaylist',
|
||||||
|
props: [ 'show', 'playlist' ],
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
play: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.player_play_uri(this.playlist.uri, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add(this.playlist.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Playlist appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add_next: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add_next(this.playlist.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_playlist: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
this.$router.push({ path: '/playlists/' + this.playlist.id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
84
web-src/src/components/ModalDialogQueueItem.vue
Normal file
84
web-src/src/components/ModalDialogQueueItem.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="modal is-active" v-if="show">
|
||||||
|
<div class="modal-background" @click="$emit('close')"></div>
|
||||||
|
<div class="modal-content fd-modal-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title is-4">
|
||||||
|
{{ item.title }}
|
||||||
|
</p>
|
||||||
|
<p class="subtitle">
|
||||||
|
{{ item.artist }}
|
||||||
|
</p>
|
||||||
|
<div class="content is-small">
|
||||||
|
<p>
|
||||||
|
<span class="heading">Album</span>
|
||||||
|
<span class="title is-6">{{ item.album }}</span>
|
||||||
|
</p>
|
||||||
|
<p v-if="item.album_artist">
|
||||||
|
<span class="heading">Album artist</span>
|
||||||
|
<span class="title is-6">{{ item.album_artist }}</span>
|
||||||
|
</p>
|
||||||
|
<p v-if="item.year > 0">
|
||||||
|
<span class="heading">Year</span>
|
||||||
|
<span class="title is-6">{{ item.year }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Genre</span>
|
||||||
|
<span class="title is-6">{{ item.genre }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Track / Disc</span>
|
||||||
|
<span class="title is-6">{{ item.track_number }} / {{ item.disc_number }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Length</span>
|
||||||
|
<span class="title is-6">{{ item.length_ms | duration }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Path</span>
|
||||||
|
<span class="title is-6">{{ item.path }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item has-text-dark" @click="remove">
|
||||||
|
<span class="icon"><i class="mdi mdi-delete mdi-18px"></i></span> <span>Remove</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="play">
|
||||||
|
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close" @click="$emit('close')"></button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalDialogQueueItem',
|
||||||
|
props: [ 'show', 'item' ],
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
remove: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_remove(this.item.id)
|
||||||
|
},
|
||||||
|
|
||||||
|
play: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.player_play({ 'item_id': this.item.id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
130
web-src/src/components/ModalDialogTrack.vue
Normal file
130
web-src/src/components/ModalDialogTrack.vue
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="modal is-active" v-if="show">
|
||||||
|
<div class="modal-background" @click="$emit('close')"></div>
|
||||||
|
<div class="modal-content fd-modal-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<p class="title is-4">
|
||||||
|
{{ track.title }}
|
||||||
|
</p>
|
||||||
|
<p class="subtitle">
|
||||||
|
{{ track.artist }}
|
||||||
|
</p>
|
||||||
|
<div class="content is-small">
|
||||||
|
<p>
|
||||||
|
<span class="heading">Album</span>
|
||||||
|
<a class="title is-6 has-text-link" @click="open_album">{{ track.album }}</a>
|
||||||
|
</p>
|
||||||
|
<p v-if="track.album_artist && track.media_kind !== 'audiobook'">
|
||||||
|
<span class="heading">Album artist</span>
|
||||||
|
<a class="title is-6 has-text-link" @click="open_artist">{{ track.album_artist }}</a>
|
||||||
|
</p>
|
||||||
|
<p v-if="track.date_released">
|
||||||
|
<span class="heading">Release date</span>
|
||||||
|
<span class="title is-6">{{ track.date_released | time('L')}}</span>
|
||||||
|
</p>
|
||||||
|
<p v-else-if="track.year > 0">
|
||||||
|
<span class="heading">Year</span>
|
||||||
|
<span class="title is-6">{{ track.year }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Genre</span>
|
||||||
|
<span class="title is-6">{{ track.genre }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Track / Disc</span>
|
||||||
|
<span class="title is-6">{{ track.track_number }} / {{ track.disc_number }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Length</span>
|
||||||
|
<span class="title is-6">{{ track.length_ms | duration }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Path</span>
|
||||||
|
<span class="title is-6">{{ track.path }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Type</span>
|
||||||
|
<span class="title is-6">{{ track.media_kind }} - {{ track.data_kind }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="heading">Added at</span>
|
||||||
|
<span class="title is-6">{{ track.time_added | time('L LT')}}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-plus mdi-18px"></i></span> <span>Add</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="queue_add_next">
|
||||||
|
<span class="icon"><i class="mdi mdi-playlist-play mdi-18px"></i></span> <span>Add Next</span>
|
||||||
|
</a>
|
||||||
|
<a class="card-footer-item has-text-dark" @click="play_track">
|
||||||
|
<span class="icon"><i class="mdi mdi-play mdi-18px"></i></span> <span>Play</span>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close" @click="$emit('close')"></button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalDialogTrack',
|
||||||
|
|
||||||
|
props: ['show', 'track'],
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
play_track: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.player_play_uri(this.track.uri, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add(this.track.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Track appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
queue_add_next: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
webapi.queue_add_next(this.track.uri).then(() =>
|
||||||
|
this.$store.dispatch('add_notification', { text: 'Album tracks appended to queue', type: 'info', timeout: 2000 })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_album: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
if (this.track.media_kind === 'podcast') {
|
||||||
|
this.$router.push({ path: '/podcasts/' + this.track.album_id })
|
||||||
|
} else if (this.track.media_kind === 'audiobook') {
|
||||||
|
this.$router.push({ path: '/audiobooks/' + this.track.album_id })
|
||||||
|
} else {
|
||||||
|
this.$router.push({ path: '/music/albums/' + this.track.album_id })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
open_artist: function () {
|
||||||
|
this.$emit('close')
|
||||||
|
this.$router.push({ path: '/music/artists/' + this.track.album_artist_id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
@ -18,7 +18,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile">{{ album.track_count }} tracks</p>
|
<p class="heading has-text-centered-mobile">{{ album.track_count }} tracks</p>
|
||||||
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="album.uri"></list-item-track>
|
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="album.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -27,6 +34,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const albumData = {
|
const albumData = {
|
||||||
@ -46,12 +54,15 @@ const albumData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageAlbum',
|
name: 'PageAlbum',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(albumData) ],
|
mixins: [ LoadDataBeforeEnterMixin(albumData) ],
|
||||||
components: { ContentWithHeading, ListItemTrack },
|
components: { ContentWithHeading, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
album: {},
|
album: {},
|
||||||
tracks: []
|
tracks: [],
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -63,6 +74,11 @@ export default {
|
|||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.album.uri, true)
|
webapi.player_play_uri(this.album.uri, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,14 @@
|
|||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-album v-for="(album, index) in albums.items" :key="album.id" :album="album" :anchor="anchor(album, index)" v-if="!hide_singles || album.track_count > 2"></list-item-album>
|
<list-item-album v-for="(album, index) in albums.items" :key="album.id" :album="album" :anchor="anchor(album, index)" v-if="!hide_singles || album.track_count > 2">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_details_modal" :album="selected_album" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -31,6 +38,7 @@ import ContentWithHeading from '@/templates/ContentWithHeading'
|
|||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import IndexButtonList from '@/components/IndexButtonList'
|
import IndexButtonList from '@/components/IndexButtonList'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
import * as types from '@/store/mutation_types'
|
import * as types from '@/store/mutation_types'
|
||||||
|
|
||||||
@ -47,11 +55,14 @@ const albumsData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageAlbums',
|
name: 'PageAlbums',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(albumsData) ],
|
mixins: [ LoadDataBeforeEnterMixin(albumsData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemAlbum },
|
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemAlbum, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
albums: { items: [] }
|
albums: { items: [] },
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -74,6 +85,11 @@ export default {
|
|||||||
|
|
||||||
anchor: function (album, index) {
|
anchor: function (album, index) {
|
||||||
return album.name_sort.charAt(0).toUpperCase()
|
return album.name_sort.charAt(0).toUpperCase()
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile">{{ artist.album_count }} albums | <a class="has-text-link" @click="open_tracks">{{ artist.track_count }} tracks</a></p>
|
<p class="heading has-text-centered-mobile">{{ artist.album_count }} albums | <a class="has-text-link" @click="open_tracks">{{ artist.track_count }} tracks</a></p>
|
||||||
<list-item-album v-for="album in albums.items" :key="album.id" :album="album"></list-item-album>
|
<list-item-album v-for="album in albums.items" :key="album.id" :album="album">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_details_modal" :album="selected_album" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -19,6 +26,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const artistData = {
|
const artistData = {
|
||||||
@ -38,12 +46,15 @@ const artistData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageArtist',
|
name: 'PageArtist',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(artistData) ],
|
mixins: [ LoadDataBeforeEnterMixin(artistData) ],
|
||||||
components: { ContentWithHeading, ListItemAlbum },
|
components: { ContentWithHeading, ListItemAlbum, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
artist: {},
|
artist: {},
|
||||||
albums: {}
|
albums: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -54,6 +65,11 @@ export default {
|
|||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.albums.items.map(a => a.uri).join(','), true)
|
webapi.player_play_uri(this.albums.items.map(a => a.uri).join(','), true)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,14 @@
|
|||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-artist v-for="(artist, index) in artists.items" :key="artist.id" :artist="artist" :anchor="anchor(artist, index)" v-if="!hide_singles || artist.track_count > (artist.album_count * 2)"></list-item-artist>
|
<list-item-artist v-for="(artist, index) in artists.items" :key="artist.id" :artist="artist" :anchor="anchor(artist, index)" v-if="!hide_singles || artist.track_count > (artist.album_count * 2)">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(artist)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-artist>
|
||||||
|
<modal-dialog-artist :show="show_details_modal" :artist="selected_artist" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -31,6 +38,7 @@ import ContentWithHeading from '@/templates/ContentWithHeading'
|
|||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import IndexButtonList from '@/components/IndexButtonList'
|
import IndexButtonList from '@/components/IndexButtonList'
|
||||||
import ListItemArtist from '@/components/ListItemArtist'
|
import ListItemArtist from '@/components/ListItemArtist'
|
||||||
|
import ModalDialogArtist from '@/components/ModalDialogArtist'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
import * as types from '@/store/mutation_types'
|
import * as types from '@/store/mutation_types'
|
||||||
|
|
||||||
@ -47,11 +55,14 @@ const artistsData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageArtists',
|
name: 'PageArtists',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(artistsData) ],
|
mixins: [ LoadDataBeforeEnterMixin(artistsData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemArtist },
|
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemArtist, ModalDialogArtist },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
artists: { items: [] }
|
artists: { items: [] },
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_artist: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -74,6 +85,11 @@ export default {
|
|||||||
|
|
||||||
anchor: function (artist, index) {
|
anchor: function (artist, index) {
|
||||||
return artist.name_sort.charAt(0).toUpperCase()
|
return artist.name_sort.charAt(0).toUpperCase()
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (artist) {
|
||||||
|
this.selected_artist = artist
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile">{{ album.track_count }} tracks</p>
|
<p class="heading has-text-centered-mobile">{{ album.track_count }} tracks</p>
|
||||||
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="album.uri"></list-item-track>
|
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="album.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -23,6 +30,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const albumData = {
|
const albumData = {
|
||||||
@ -42,18 +50,26 @@ const albumData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageAudiobook',
|
name: 'PageAudiobook',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(albumData) ],
|
mixins: [ LoadDataBeforeEnterMixin(albumData) ],
|
||||||
components: { ContentWithHeading, ListItemTrack },
|
components: { ContentWithHeading, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
album: {},
|
album: {},
|
||||||
tracks: []
|
tracks: [],
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.album.uri, false)
|
webapi.player_play_uri(this.album.uri, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,14 @@
|
|||||||
<p class="heading">{{ albums.total }} audiobooks</p>
|
<p class="heading">{{ albums.total }} audiobooks</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'audiobook'"></list-item-album>
|
<list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'audiobook'">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_details_modal" :album="selected_album" :media_kind="'audiobook'" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -16,6 +23,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const albumsData = {
|
const albumsData = {
|
||||||
@ -31,11 +39,21 @@ const albumsData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageAudiobooks',
|
name: 'PageAudiobooks',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(albumsData) ],
|
mixins: [ LoadDataBeforeEnterMixin(albumsData) ],
|
||||||
components: { ContentWithHeading, ListItemAlbum },
|
components: { ContentWithHeading, ListItemAlbum, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
albums: {}
|
albums: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
open_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,14 @@
|
|||||||
<p class="heading">albums</p>
|
<p class="heading">albums</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-album v-for="album in recently_added.items" :key="album.id" :album="album"></list-item-album>
|
<list-item-album v-for="album in recently_added.items" :key="album.id" :album="album">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_album_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_album_details_modal" :album="selected_album" @close="show_album_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<nav class="level">
|
<nav class="level">
|
||||||
@ -27,7 +34,14 @@
|
|||||||
<p class="heading">tracks</p>
|
<p class="heading">tracks</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-track v-for="track in recently_played.items" :key="track.id" :track="track" :position="0" :context_uri="track.uri"></list-item-track>
|
<list-item-track v-for="track in recently_played.items" :key="track.id" :track="track" :position="0" :context_uri="track.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_track_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_track_details_modal" :track="selected_track" @close="show_track_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<nav class="level">
|
<nav class="level">
|
||||||
@ -46,6 +60,8 @@ import ContentWithHeading from '@/templates/ContentWithHeading'
|
|||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const browseData = {
|
const browseData = {
|
||||||
@ -65,18 +81,34 @@ const browseData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageBrowse',
|
name: 'PageBrowse',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(browseData) ],
|
mixins: [ LoadDataBeforeEnterMixin(browseData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, ListItemAlbum, ListItemTrack },
|
components: { ContentWithHeading, TabsMusic, ListItemAlbum, ListItemTrack, ModalDialogTrack, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
recently_added: {},
|
recently_added: {},
|
||||||
recently_played: {}
|
recently_played: {},
|
||||||
|
|
||||||
|
show_track_details_modal: false,
|
||||||
|
selected_track: {},
|
||||||
|
|
||||||
|
show_album_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
open_browse: function (type) {
|
open_browse: function (type) {
|
||||||
this.$router.push({ path: '/music/browse/' + type })
|
this.$router.push({ path: '/music/browse/' + type })
|
||||||
|
},
|
||||||
|
|
||||||
|
open_track_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_track_details_modal = true
|
||||||
|
},
|
||||||
|
|
||||||
|
open_album_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_album_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,14 @@
|
|||||||
<p class="heading">albums</p>
|
<p class="heading">albums</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-album v-for="album in recently_added.items" :key="album.id" :album="album"></list-item-album>
|
<list-item-album v-for="album in recently_added.items" :key="album.id" :album="album">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_details_modal" :album="selected_album" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -19,6 +26,7 @@ import { LoadDataBeforeEnterMixin } from './mixin'
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const browseData = {
|
const browseData = {
|
||||||
@ -38,11 +46,21 @@ const browseData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageBrowseType',
|
name: 'PageBrowseType',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(browseData) ],
|
mixins: [ LoadDataBeforeEnterMixin(browseData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, ListItemAlbum },
|
components: { ContentWithHeading, TabsMusic, ListItemAlbum, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
recently_added: {}
|
recently_added: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
open_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,14 @@
|
|||||||
<p class="heading">tracks</p>
|
<p class="heading">tracks</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-track v-for="track in recently_played.items" :key="track.id" :track="track" :position="0" :context_uri="track.uri"></list-item-track>
|
<list-item-track v-for="track in recently_played.items" :key="track.id" :track="track" :position="0" :context_uri="track.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -19,6 +26,7 @@ import { LoadDataBeforeEnterMixin } from './mixin'
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const browseData = {
|
const browseData = {
|
||||||
@ -38,11 +46,21 @@ const browseData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageBrowseType',
|
name: 'PageBrowseType',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(browseData) ],
|
mixins: [ LoadDataBeforeEnterMixin(browseData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, ListItemTrack },
|
components: { ContentWithHeading, TabsMusic, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
recently_played: {}
|
recently_played: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,15 @@
|
|||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile">{{ genreAlbums.total }} albums | <a class="has-text-link" @click="open_tracks">{{ tracks }} tracks</a></p>
|
<p class="heading has-text-centered-mobile">{{ genreAlbums.total }} albums | <a class="has-text-link" @click="open_tracks">tracks</a></p>
|
||||||
<list-item-albums v-for="album in genreAlbums.items" :key="album.id" :album="album" :links="links"></list-item-albums>
|
<list-item-albums v-for="album in genreAlbums.items" :key="album.id" :album="album" :links="links">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-albums>
|
||||||
|
<modal-dialog-album :show="show_details_modal" :album="selected_album" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -22,6 +29,7 @@ import { LoadDataBeforeEnterMixin } from './mixin'
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import ListItemAlbums from '@/components/ListItemAlbum'
|
import ListItemAlbums from '@/components/ListItemAlbum'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const genreData = {
|
const genreData = {
|
||||||
@ -52,13 +60,16 @@ const genreData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageGenre',
|
name: 'PageGenre',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(genreData) ],
|
mixins: [ LoadDataBeforeEnterMixin(genreData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, ListItemAlbums },
|
components: { ContentWithHeading, TabsMusic, ListItemAlbums, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
name: '',
|
name: '',
|
||||||
genreAlbums: {},
|
genreAlbums: {},
|
||||||
links: []
|
links: [],
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -70,6 +81,11 @@ export default {
|
|||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.genreAlbums.items.map(a => a.uri).join(','), true)
|
webapi.player_play_uri(this.genreAlbums.items.map(a => a.uri).join(','), true)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile"><a class="has-text-link" @click="open_genre">albums</a> | {{ tracks.total }} tracks</p>
|
<p class="heading has-text-centered-mobile"><a class="has-text-link" @click="open_genre">albums</a> | {{ tracks.total }} tracks</p>
|
||||||
<list-item-track v-for="(track, index) in tracks.items" :key="track.id" :track="track" :position="index" :context_uri="tracks.items.map(a => a.uri).join(',')" :links="links"></list-item-track>
|
<list-item-track v-for="(track, index) in tracks.items" :key="track.id" :track="track" :position="index" :context_uri="tracks.items.map(a => a.uri).join(',')" :links="links">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -21,6 +28,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const tracksData = {
|
const tracksData = {
|
||||||
@ -37,13 +45,16 @@ const tracksData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageGenreTracks',
|
name: 'PageGenreTracks',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(tracksData) ],
|
mixins: [ LoadDataBeforeEnterMixin(tracksData) ],
|
||||||
components: { ContentWithHeading, ListItemTrack },
|
components: { ContentWithHeading, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
tracks: {},
|
tracks: {},
|
||||||
genre: '',
|
genre: '',
|
||||||
links: []
|
links: [],
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -55,6 +66,11 @@ export default {
|
|||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.tracks.items.map(a => a.uri).join(','), true)
|
webapi.player_play_uri(this.tracks.items.map(a => a.uri).join(','), true)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,14 @@
|
|||||||
<p class="heading">{{ genres.total }} genres</p>
|
<p class="heading">{{ genres.total }} genres</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-genre v-for="(genre, index) in genres.items" :key="genre.name" :genre="genre" :anchor="anchor(genre, index)"></list-item-genre>
|
<list-item-genre v-for="(genre, index) in genres.items" :key="genre.name" :genre="genre" :anchor="anchor(genre, index)">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(genre)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-genre>
|
||||||
|
<modal-dialog-genre :show="show_details_modal" :genre="selected_genre" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -23,6 +30,7 @@ import ContentWithHeading from '@/templates/ContentWithHeading'
|
|||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import IndexButtonList from '@/components/IndexButtonList'
|
import IndexButtonList from '@/components/IndexButtonList'
|
||||||
import ListItemGenre from '@/components/ListItemGenre'
|
import ListItemGenre from '@/components/ListItemGenre'
|
||||||
|
import ModalDialogGenre from '@/components/ModalDialogGenre'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const genresData = {
|
const genresData = {
|
||||||
@ -38,11 +46,14 @@ const genresData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageGenres',
|
name: 'PageGenres',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(genresData) ],
|
mixins: [ LoadDataBeforeEnterMixin(genresData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemGenre },
|
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemGenre, ModalDialogGenre },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
genres: { items: [] }
|
genres: { items: [] },
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_genre: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -56,6 +67,11 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
anchor: function (genre, index) {
|
anchor: function (genre, index) {
|
||||||
return genre.name.charAt(0).toUpperCase()
|
return genre.name.charAt(0).toUpperCase()
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (genre) {
|
||||||
|
this.selected_genre = genre
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile">{{ tracks.length }} tracks</p>
|
<p class="heading has-text-centered-mobile">{{ tracks.length }} tracks</p>
|
||||||
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="playlist.uri"></list-item-track>
|
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="playlist.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -19,6 +26,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const playlistData = {
|
const playlistData = {
|
||||||
@ -38,18 +46,26 @@ const playlistData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PagePlaylist',
|
name: 'PagePlaylist',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(playlistData) ],
|
mixins: [ LoadDataBeforeEnterMixin(playlistData) ],
|
||||||
components: { ContentWithHeading, ListItemTrack },
|
components: { ContentWithHeading, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
playlist: {},
|
playlist: {},
|
||||||
tracks: []
|
tracks: [],
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.playlist.uri, true)
|
webapi.player_play_uri(this.playlist.uri, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,14 @@
|
|||||||
<p class="heading">{{ playlists.total }} playlists</p>
|
<p class="heading">{{ playlists.total }} playlists</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-playlist v-for="playlist in playlists.items" :key="playlist.id" :playlist="playlist"></list-item-playlist>
|
<list-item-playlist v-for="playlist in playlists.items" :key="playlist.id" :playlist="playlist">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(playlist)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-playlist>
|
||||||
|
<modal-dialog-playlist :show="show_details_modal" :playlist="selected_playlist" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -15,6 +22,7 @@ import { LoadDataBeforeEnterMixin } from './mixin'
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import TabsMusic from '@/components/TabsMusic'
|
import TabsMusic from '@/components/TabsMusic'
|
||||||
import ListItemPlaylist from '@/components/ListItemPlaylist'
|
import ListItemPlaylist from '@/components/ListItemPlaylist'
|
||||||
|
import ModalDialogPlaylist from '@/components/ModalDialogPlaylist'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const playlistsData = {
|
const playlistsData = {
|
||||||
@ -30,11 +38,21 @@ const playlistsData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PagePlaylists',
|
name: 'PagePlaylists',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(playlistsData) ],
|
mixins: [ LoadDataBeforeEnterMixin(playlistsData) ],
|
||||||
components: { ContentWithHeading, TabsMusic, ListItemPlaylist },
|
components: { ContentWithHeading, TabsMusic, ListItemPlaylist, ModalDialogPlaylist },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
playlists: {}
|
playlists: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_playlist: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
open_dialog: function (playlist) {
|
||||||
|
this.selected_playlist = playlist
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile">{{ album.track_count }} tracks</p>
|
<p class="heading has-text-centered-mobile">{{ album.track_count }} tracks</p>
|
||||||
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="album.uri"></list-item-track>
|
<list-item-track v-for="(track, index) in tracks" :key="track.id" :track="track" :position="index" :context_uri="album.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -22,6 +29,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const albumData = {
|
const albumData = {
|
||||||
@ -41,18 +49,26 @@ const albumData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PagePodcast',
|
name: 'PagePodcast',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(albumData) ],
|
mixins: [ LoadDataBeforeEnterMixin(albumData) ],
|
||||||
components: { ContentWithHeading, ListItemTrack },
|
components: { ContentWithHeading, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
album: {},
|
album: {},
|
||||||
tracks: []
|
tracks: [],
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.album.uri, false)
|
webapi.player_play_uri(this.album.uri, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,14 @@
|
|||||||
<p class="heading">{{ albums.total }} podcasts</p>
|
<p class="heading">{{ albums.total }} podcasts</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'podcast'"></list-item-album>
|
<list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'podcast'">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_details_modal" :album="selected_album" :media_kind="'podcast'" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -16,6 +23,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const albumsData = {
|
const albumsData = {
|
||||||
@ -31,11 +39,21 @@ const albumsData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PagePodcasts',
|
name: 'PagePodcasts',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(albumsData) ],
|
mixins: [ LoadDataBeforeEnterMixin(albumsData) ],
|
||||||
components: { ContentWithHeading, ListItemAlbum },
|
components: { ContentWithHeading, ListItemAlbum, ModalDialogAlbum },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
albums: {}
|
albums: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_album: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
open_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,18 @@
|
|||||||
:key="item.id" :item="item" :position="index"
|
:key="item.id" :item="item" :position="index"
|
||||||
:current_position="current_position"
|
:current_position="current_position"
|
||||||
:show_only_next_items="show_only_next_items"
|
:show_only_next_items="show_only_next_items"
|
||||||
:edit_mode="edit_mode"></list-item-queue-item>
|
:edit_mode="edit_mode">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(item)" v-if="!edit_mode">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
<a @click="remove(item)" v-if="item.id !== state.item_id && edit_mode">
|
||||||
|
<span class="icon has-text-grey"><i class="mdi mdi-delete mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-queue-item>
|
||||||
</draggable>
|
</draggable>
|
||||||
|
<modal-dialog-queue-item :show="show_details_modal" :item="selected_item" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</template>
|
</template>
|
||||||
@ -49,17 +59,21 @@
|
|||||||
<script>
|
<script>
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemQueueItem from '@/components/ListItemQueueItem'
|
import ListItemQueueItem from '@/components/ListItemQueueItem'
|
||||||
|
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
import * as types from '@/store/mutation_types'
|
import * as types from '@/store/mutation_types'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageQueue',
|
name: 'PageQueue',
|
||||||
components: { ContentWithHeading, ListItemQueueItem, draggable },
|
components: { ContentWithHeading, ListItemQueueItem, draggable, ModalDialogQueueItem },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
edit_mode: false
|
edit_mode: false,
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_item: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -92,6 +106,10 @@ export default {
|
|||||||
this.$store.commit(types.SHOW_ONLY_NEXT_ITEMS, !this.show_only_next_items)
|
this.$store.commit(types.SHOW_ONLY_NEXT_ITEMS, !this.show_only_next_items)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
remove: function (item) {
|
||||||
|
webapi.queue_remove(item.id)
|
||||||
|
},
|
||||||
|
|
||||||
move_item: function (e) {
|
move_item: function (e) {
|
||||||
var oldPosition = !this.show_only_next_items ? e.oldIndex : e.oldIndex + this.current_position
|
var oldPosition = !this.show_only_next_items ? e.oldIndex : e.oldIndex + this.current_position
|
||||||
var item = this.queue_items[oldPosition]
|
var item = this.queue_items[oldPosition]
|
||||||
@ -99,6 +117,11 @@ export default {
|
|||||||
if (newPosition !== oldPosition) {
|
if (newPosition !== oldPosition) {
|
||||||
webapi.queue_move(item.id, newPosition)
|
webapi.queue_move(item.id, newPosition)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (item) {
|
||||||
|
this.selected_item = item
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,14 @@
|
|||||||
<p class="title is-4">Tracks</p>
|
<p class="title is-4">Tracks</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-track v-for="track in tracks.items" :key="track.id" :track="track" :position="0" :context_uri="track.uri"></list-item-track>
|
<list-item-track v-for="track in tracks.items" :key="track.id" :track="track" :position="0" :context_uri="track.uri">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_track_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_track_details_modal" :track="selected_track" @close="show_track_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<nav v-if="show_all_tracks_button" class="level">
|
<nav v-if="show_all_tracks_button" class="level">
|
||||||
@ -49,7 +56,14 @@
|
|||||||
<p class="title is-4">Artists</p>
|
<p class="title is-4">Artists</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-artist v-for="artist in artists.items" :key="artist.id" :artist="artist"></list-item-artist>
|
<list-item-artist v-for="artist in artists.items" :key="artist.id" :artist="artist">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_artist_dialog(artist)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-artist>
|
||||||
|
<modal-dialog-artist :show="show_artist_details_modal" :artist="selected_artist" @close="show_artist_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<nav v-if="show_all_artists_button" class="level">
|
<nav v-if="show_all_artists_button" class="level">
|
||||||
@ -67,7 +81,14 @@
|
|||||||
<p class="title is-4">Albums</p>
|
<p class="title is-4">Albums</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-album v-for="album in albums.items" :key="album.id" :album="album"></list-item-album>
|
<list-item-album v-for="album in albums.items" :key="album.id" :album="album">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_album_dialog(album)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-album>
|
||||||
|
<modal-dialog-album :show="show_album_details_modal" :album="selected_album" @close="show_album_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<nav v-if="show_all_albums_button" class="level">
|
<nav v-if="show_all_albums_button" class="level">
|
||||||
@ -85,7 +106,14 @@
|
|||||||
<p class="title is-4">Playlists</p>
|
<p class="title is-4">Playlists</p>
|
||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<list-item-playlist v-for="playlist in playlists.items" :key="playlist.id" :playlist="playlist"></list-item-playlist>
|
<list-item-playlist v-for="playlist in playlists.items" :key="playlist.id" :playlist="playlist">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_playlist_dialog(playlist)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-playlist>
|
||||||
|
<modal-dialog-playlist :show="show_playlist_details_modal" :playlist="selected_playlist" @close="show_playlist_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<nav v-if="show_all_playlists_button" class="level">
|
<nav v-if="show_all_playlists_button" class="level">
|
||||||
@ -106,12 +134,16 @@ import ListItemTrack from '@/components/ListItemTrack'
|
|||||||
import ListItemArtist from '@/components/ListItemArtist'
|
import ListItemArtist from '@/components/ListItemArtist'
|
||||||
import ListItemAlbum from '@/components/ListItemAlbum'
|
import ListItemAlbum from '@/components/ListItemAlbum'
|
||||||
import ListItemPlaylist from '@/components/ListItemPlaylist'
|
import ListItemPlaylist from '@/components/ListItemPlaylist'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum'
|
||||||
|
import ModalDialogArtist from '@/components/ModalDialogArtist'
|
||||||
|
import ModalDialogPlaylist from '@/components/ModalDialogPlaylist'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
import * as types from '@/store/mutation_types'
|
import * as types from '@/store/mutation_types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageSearch',
|
name: 'PageSearch',
|
||||||
components: { ContentWithHeading, TabsSearch, ListItemTrack, ListItemArtist, ListItemAlbum, ListItemPlaylist },
|
components: { ContentWithHeading, TabsSearch, ListItemTrack, ListItemArtist, ListItemAlbum, ListItemPlaylist, ModalDialogTrack, ModalDialogAlbum, ModalDialogArtist, ModalDialogPlaylist },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@ -119,7 +151,19 @@ export default {
|
|||||||
tracks: { items: [], total: 0 },
|
tracks: { items: [], total: 0 },
|
||||||
artists: { items: [], total: 0 },
|
artists: { items: [], total: 0 },
|
||||||
albums: { items: [], total: 0 },
|
albums: { items: [], total: 0 },
|
||||||
playlists: { items: [], total: 0 }
|
playlists: { items: [], total: 0 },
|
||||||
|
|
||||||
|
show_track_details_modal: false,
|
||||||
|
selected_track: {},
|
||||||
|
|
||||||
|
show_album_details_modal: false,
|
||||||
|
selected_album: {},
|
||||||
|
|
||||||
|
show_artist_details_modal: false,
|
||||||
|
selected_artist: {},
|
||||||
|
|
||||||
|
show_playlist_details_modal: false,
|
||||||
|
selected_playlist: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -241,6 +285,26 @@ export default {
|
|||||||
open_recent_search: function (query) {
|
open_recent_search: function (query) {
|
||||||
this.search_query = query
|
this.search_query = query
|
||||||
this.new_search()
|
this.new_search()
|
||||||
|
},
|
||||||
|
|
||||||
|
open_track_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_track_details_modal = true
|
||||||
|
},
|
||||||
|
|
||||||
|
open_album_dialog: function (album) {
|
||||||
|
this.selected_album = album
|
||||||
|
this.show_album_details_modal = true
|
||||||
|
},
|
||||||
|
|
||||||
|
open_artist_dialog: function (artist) {
|
||||||
|
this.selected_artist = artist
|
||||||
|
this.show_artist_details_modal = true
|
||||||
|
},
|
||||||
|
|
||||||
|
open_playlist_dialog: function (playlist) {
|
||||||
|
this.selected_playlist = playlist
|
||||||
|
this.show_playlist_details_modal = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -11,7 +11,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template slot="content">
|
<template slot="content">
|
||||||
<p class="heading has-text-centered-mobile"><a class="has-text-link" @click="open_artist">{{ artist.album_count }} albums</a> | {{ artist.track_count }} tracks</p>
|
<p class="heading has-text-centered-mobile"><a class="has-text-link" @click="open_artist">{{ artist.album_count }} albums</a> | {{ artist.track_count }} tracks</p>
|
||||||
<list-item-track v-for="(track, index) in tracks.items" :key="track.id" :track="track" :position="index" :context_uri="tracks.items.map(a => a.uri).join(',')"></list-item-track>
|
<list-item-track v-for="(track, index) in tracks.items" :key="track.id" :track="track" :position="index" :context_uri="tracks.items.map(a => a.uri).join(',')">
|
||||||
|
<template slot="actions">
|
||||||
|
<a @click="open_dialog(track)">
|
||||||
|
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
</list-item-track>
|
||||||
|
<modal-dialog-track :show="show_details_modal" :track="selected_track" @close="show_details_modal = false" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -21,6 +28,7 @@
|
|||||||
import { LoadDataBeforeEnterMixin } from './mixin'
|
import { LoadDataBeforeEnterMixin } from './mixin'
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||||
import ListItemTrack from '@/components/ListItemTrack'
|
import ListItemTrack from '@/components/ListItemTrack'
|
||||||
|
import ModalDialogTrack from '@/components/ModalDialogTrack'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const tracksData = {
|
const tracksData = {
|
||||||
@ -40,12 +48,15 @@ const tracksData = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageTracks',
|
name: 'PageTracks',
|
||||||
mixins: [ LoadDataBeforeEnterMixin(tracksData) ],
|
mixins: [ LoadDataBeforeEnterMixin(tracksData) ],
|
||||||
components: { ContentWithHeading, ListItemTrack },
|
components: { ContentWithHeading, ListItemTrack, ModalDialogTrack },
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
artist: {},
|
artist: {},
|
||||||
tracks: {}
|
tracks: {},
|
||||||
|
|
||||||
|
show_details_modal: false,
|
||||||
|
selected_track: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -57,6 +68,11 @@ export default {
|
|||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(this.tracks.items.map(a => a.uri).join(','), true)
|
webapi.player_play_uri(this.tracks.items.map(a => a.uri).join(','), true)
|
||||||
|
},
|
||||||
|
|
||||||
|
open_dialog: function (track) {
|
||||||
|
this.selected_track = track
|
||||||
|
this.show_details_modal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user