mirror of
https://github.com/owntone/owntone-server.git
synced 2025-03-03 23:30:09 -05:00
[web] Fix bug when adding playable items to queue
This commit is contained in:
parent
d6d5912de1
commit
a93777aeec
@ -4,17 +4,13 @@
|
|||||||
class="media is-align-items-center is-clickable mb-0"
|
class="media is-align-items-center is-clickable mb-0"
|
||||||
@click="open(item)"
|
@click="open(item)"
|
||||||
>
|
>
|
||||||
<div
|
<cover-artwork
|
||||||
v-if="settingsStore.show_cover_artwork_in_album_lists"
|
v-if="settingsStore.show_cover_artwork_in_album_lists"
|
||||||
class="media-left"
|
:url="item.images?.[0]?.url ?? ''"
|
||||||
>
|
:artist="item.artist"
|
||||||
<cover-artwork
|
:album="item.name"
|
||||||
:url="artwork_url(item)"
|
class="media-left is-small"
|
||||||
:artist="item.artist"
|
/>
|
||||||
:album="item.name"
|
|
||||||
class="is-small"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="media-content">
|
<div class="media-content">
|
||||||
<div class="is-size-6 has-text-weight-bold" v-text="item.name" />
|
<div class="is-size-6 has-text-weight-bold" v-text="item.name" />
|
||||||
<div
|
<div
|
||||||
@ -51,19 +47,13 @@ export default {
|
|||||||
name: 'ListAlbumsSpotify',
|
name: 'ListAlbumsSpotify',
|
||||||
components: { CoverArtwork, ModalDialogAlbumSpotify },
|
components: { CoverArtwork, ModalDialogAlbumSpotify },
|
||||||
props: { items: { required: true, type: Object } },
|
props: { items: { required: true, type: Object } },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return { settingsStore: useSettingsStore() }
|
return { settingsStore: useSettingsStore() }
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return { selected_item: {}, show_details_modal: false }
|
return { selected_item: {}, show_details_modal: false }
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
artwork_url(item) {
|
|
||||||
return item.images?.[0]?.url ?? ''
|
|
||||||
},
|
|
||||||
open(item) {
|
open(item) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'music-spotify-album',
|
name: 'music-spotify-album',
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<template v-for="item in items" :key="item.itemId">
|
<template v-for="item in items" :key="item.itemId">
|
||||||
<div v-if="!item.isItem" class="py-5">
|
<div v-if="!item.isItem" class="py-5">
|
||||||
<div class="media-content">
|
<span
|
||||||
<span
|
:id="`index_${item.index}`"
|
||||||
:id="`index_${item.index}`"
|
class="tag is-small has-text-weight-bold"
|
||||||
class="tag is-small has-text-weight-bold"
|
v-text="item.index"
|
||||||
v-text="item.index"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
@ -39,15 +37,10 @@ import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
|||||||
export default {
|
export default {
|
||||||
name: 'ListArtists',
|
name: 'ListArtists',
|
||||||
components: { ModalDialogArtist },
|
components: { ModalDialogArtist },
|
||||||
props: {
|
props: { items: { required: true, type: Object } },
|
||||||
items: { required: true, type: Object }
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { selected_item: {}, show_details_modal: false }
|
||||||
selected_item: {},
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -39,15 +39,10 @@ import ModalDialogComposer from '@/components/ModalDialogComposer.vue'
|
|||||||
export default {
|
export default {
|
||||||
name: 'ListComposers',
|
name: 'ListComposers',
|
||||||
components: { ModalDialogComposer },
|
components: { ModalDialogComposer },
|
||||||
props: {
|
props: { items: { required: true, type: Object } },
|
||||||
items: { required: true, type: Object }
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { selected_item: {}, show_details_modal: false }
|
||||||
selected_item: {},
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -54,10 +54,7 @@ export default {
|
|||||||
props: { items: { required: true, type: Array } },
|
props: { items: { required: true, type: Array } },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { selected_item: '', show_details_modal: false }
|
||||||
selected_item: '',
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -45,10 +45,7 @@ export default {
|
|||||||
media_kind: { required: true, type: String }
|
media_kind: { required: true, type: String }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { selected_item: {}, show_details_modal: false }
|
||||||
selected_item: {},
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open(item) {
|
open(item) {
|
||||||
|
@ -60,9 +60,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return { playerStore: usePlayerStore() }
|
||||||
playerStore: usePlayerStore()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -33,10 +33,7 @@ export default {
|
|||||||
props: { items: { required: true, type: Object } },
|
props: { items: { required: true, type: Object } },
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { selected_item: {}, show_details_modal: false }
|
||||||
selected_item: {},
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -69,10 +69,7 @@ export default {
|
|||||||
emits: ['play-count-changed'],
|
emits: ['play-count-changed'],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { selected_item: {}, show_details_modal: false }
|
||||||
selected_item: {},
|
|
||||||
show_details_modal: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -46,8 +46,7 @@ export default {
|
|||||||
name: this.item.name,
|
name: this.item.name,
|
||||||
handler: this.open,
|
handler: this.open,
|
||||||
image: this.item.artwork_url,
|
image: this.item.artwork_url,
|
||||||
artist: this.item.artist,
|
uri: this.item.uri,
|
||||||
album: this.item.name,
|
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
label: 'property.artist',
|
label: 'property.artist',
|
||||||
|
@ -19,12 +19,11 @@ export default {
|
|||||||
return {
|
return {
|
||||||
name: this.item.name || '',
|
name: this.item.name || '',
|
||||||
image: this.item?.images?.[0]?.url || '',
|
image: this.item?.images?.[0]?.url || '',
|
||||||
artist: this.item.artist || '',
|
|
||||||
album: this.item.name || '',
|
|
||||||
handler: this.open,
|
handler: this.open,
|
||||||
|
uri: this.item.uri,
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
label: 'property.album-artist',
|
label: 'property.artist',
|
||||||
value: this.item?.artists?.[0]?.name,
|
value: this.item?.artists?.[0]?.name,
|
||||||
handler: this.open_artist
|
handler: this.open_artist
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
name: this.item.name,
|
name: this.item.name,
|
||||||
handler: this.open,
|
handler: this.open,
|
||||||
|
uri: this.item.uri,
|
||||||
uris: this.uris,
|
uris: this.uris,
|
||||||
properties: [
|
properties: [
|
||||||
{ label: 'property.tracks', value: this.item.item_count },
|
{ label: 'property.tracks', value: this.item.item_count },
|
||||||
|
@ -19,6 +19,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
name: this.item.name,
|
name: this.item.name,
|
||||||
handler: this.open,
|
handler: this.open,
|
||||||
|
uri: this.item.uri,
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
label: 'property.owner',
|
label: 'property.owner',
|
||||||
|
@ -44,6 +44,7 @@ export default {
|
|||||||
playable() {
|
playable() {
|
||||||
return {
|
return {
|
||||||
name: this.item.title,
|
name: this.item.title,
|
||||||
|
uri: this.item.uri,
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
label: 'property.album',
|
label: 'property.album',
|
||||||
|
@ -43,6 +43,7 @@ export default {
|
|||||||
playable() {
|
playable() {
|
||||||
return {
|
return {
|
||||||
name: this.item.title,
|
name: this.item.title,
|
||||||
|
uri: this.item.uri,
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
label: 'property.album',
|
label: 'property.album',
|
||||||
|
@ -16,9 +16,12 @@ export default {
|
|||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
computed: {
|
computed: {
|
||||||
playable() {
|
playable() {
|
||||||
|
if (!this.item.artists) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
name: this.item.name,
|
name: this.item.name,
|
||||||
subtitle: this.item.artists[0].name,
|
uri: this.item.uri,
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
label: 'property.album',
|
label: 'property.album',
|
||||||
@ -27,20 +30,20 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'property.album-artist',
|
label: 'property.album-artist',
|
||||||
value: this.item.artists[0].name,
|
value: this.item.artists[0]?.name,
|
||||||
handler: this.open_artist
|
handler: this.open_artist
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'property.release-date',
|
label: 'property.release-date',
|
||||||
value: this.$filters.date(item.album.release_date)
|
value: this.$filters.date(this.item.album.release_date)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'property.position',
|
label: 'property.position',
|
||||||
value: [item.disc_number, item.track_number].join(' / ')
|
value: [this.item.disc_number, this.item.track_number].join(' / ')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'property.duration',
|
label: 'property.duration',
|
||||||
value: this.$filters.durationInHours(item.duration_ms)
|
value: this.$filters.durationInHours(this.item.duration_ms)
|
||||||
},
|
},
|
||||||
{ label: 'property.path', value: this.item.uri }
|
{ label: 'property.path', value: this.item.uri }
|
||||||
]
|
]
|
||||||
|
@ -23,9 +23,7 @@ export default {
|
|||||||
name: 'NotificationList',
|
name: 'NotificationList',
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return { notificationsStore: useNotificationsStore() }
|
||||||
notificationsStore: useNotificationsStore()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -41,9 +41,7 @@ export default {
|
|||||||
emits: ['search-library', 'search-spotify'],
|
emits: ['search-library', 'search-spotify'],
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return { servicesStore: useServicesStore() }
|
||||||
servicesStore: useServicesStore()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<a @click="open_artist" v-text="album.artists[0].name" />
|
<a @click="open_artist" v-text="album.artists[0].name" />
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons is-centered-mobile mt-5">
|
<div class="buttons is-centered-mobile mt-5">
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.spotify.album.shuffle')" />
|
<span v-text="$t('page.spotify.album.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
@ -21,7 +21,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<cover-artwork
|
<cover-artwork
|
||||||
:url="artwork_url(album)"
|
:url="album.images?.[0]?.url ?? ''"
|
||||||
:artist="album.artists[0].name"
|
:artist="album.artists[0].name"
|
||||||
:album="album.name"
|
:album="album.name"
|
||||||
class="is-clickable is-medium"
|
class="is-clickable is-medium"
|
||||||
@ -63,7 +63,6 @@ const dataObject = {
|
|||||||
market: useServicesStore().spotify.webapi_country
|
market: useServicesStore().spotify.webapi_country
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
set(vm, response) {
|
set(vm, response) {
|
||||||
vm.album = response
|
vm.album = response
|
||||||
}
|
}
|
||||||
@ -77,26 +76,20 @@ export default {
|
|||||||
ListTracksSpotify,
|
ListTracksSpotify,
|
||||||
ModalDialogAlbumSpotify
|
ModalDialogAlbumSpotify
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return { servicesStore: useServicesStore() }
|
||||||
servicesStore: useServicesStore()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
album: { artists: [{}], tracks: {} },
|
album: { artists: [{}], tracks: {} },
|
||||||
show_details_modal: false
|
show_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
tracks() {
|
tracks() {
|
||||||
const { album } = this
|
const { album } = this
|
||||||
@ -107,9 +100,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
artwork_url(album) {
|
|
||||||
return album.images?.[0]?.url ?? ''
|
|
||||||
},
|
|
||||||
open_artist() {
|
open_artist() {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'music-spotify-artist',
|
name: 'music-spotify-artist',
|
||||||
|
@ -48,12 +48,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.artist.shuffle')" />
|
<span v-text="$t('page.artist.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.spotify.artist.shuffle')" />
|
<span v-text="$t('page.spotify.artist.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -49,12 +49,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.artist.shuffle')" />
|
<span v-text="$t('page.artist.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<a @click="open_artist" v-text="album.artist" />
|
<a @click="open_artist" v-text="album.artist" />
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons is-centered-mobile mt-5">
|
<div class="buttons is-centered-mobile mt-5">
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="play" size="16" />
|
<mdicon class="icon" name="play" size="16" />
|
||||||
<span v-text="$t('page.audiobooks.album.play')" />
|
<span v-text="$t('page.audiobooks.album.play')" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="play" size="16" />
|
<mdicon class="icon" name="play" size="16" />
|
||||||
<span v-text="$t('page.audiobooks.artist.play')" />
|
<span v-text="$t('page.audiobooks.artist.play')" />
|
||||||
</a>
|
</a>
|
||||||
@ -52,7 +52,6 @@ const dataObject = {
|
|||||||
webapi.library_artist_albums(to.params.id)
|
webapi.library_artist_albums(to.params.id)
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
|
|
||||||
set(vm, response) {
|
set(vm, response) {
|
||||||
vm.artist = response[0].data
|
vm.artist = response[0].data
|
||||||
vm.albums = new GroupedList(response[1].data)
|
vm.albums = new GroupedList(response[1].data)
|
||||||
@ -62,13 +61,11 @@ const dataObject = {
|
|||||||
export default {
|
export default {
|
||||||
name: 'PageAudiobooksArtist',
|
name: 'PageAudiobooksArtist',
|
||||||
components: { ContentWithHeading, ListAlbums, ModalDialogArtist },
|
components: { ContentWithHeading, ListAlbums, ModalDialogArtist },
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: new GroupedList(),
|
albums: new GroupedList(),
|
||||||
@ -76,7 +73,6 @@ export default {
|
|||||||
show_details_modal: false
|
show_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play() {
|
play() {
|
||||||
webapi.player_play_uri(
|
webapi.player_play_uri(
|
||||||
|
@ -21,12 +21,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.composer.shuffle')" />
|
<span v-text="$t('page.composer.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
@ -72,13 +72,11 @@ export default {
|
|||||||
ListAlbums,
|
ListAlbums,
|
||||||
ModalDialogComposer
|
ModalDialogComposer
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: new GroupedList(),
|
albums: new GroupedList(),
|
||||||
@ -86,7 +84,11 @@ export default {
|
|||||||
show_details_modal: false
|
show_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
expression() {
|
||||||
|
return `composer is "${this.composer.name}" and media_kind is music`
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open_tracks() {
|
open_tracks() {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
@ -95,10 +97,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
play() {
|
play() {
|
||||||
webapi.player_play_expression(
|
webapi.player_play_expression(this.expression, true)
|
||||||
`composer is "${this.composer.name}" and media_kind is music`,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.composer.shuffle')" />
|
<span v-text="$t('page.composer.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
@ -94,17 +94,14 @@ export default {
|
|||||||
ListTracks,
|
ListTracks,
|
||||||
ModalDialogComposer
|
ModalDialogComposer
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return { uiStore: useUIStore() }
|
return { uiStore: useUIStore() }
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
composer: {},
|
composer: {},
|
||||||
@ -127,7 +124,6 @@ export default {
|
|||||||
tracks_list: new GroupedList()
|
tracks_list: new GroupedList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
expression() {
|
expression() {
|
||||||
return `composer is "${this.composer.name}" and media_kind is music`
|
return `composer is "${this.composer.name}" and media_kind is music`
|
||||||
@ -139,10 +135,8 @@ export default {
|
|||||||
return this.tracks_list.group(options)
|
return this.tracks_list.group(options)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
open_albums() {
|
open_albums() {
|
||||||
this.show_details_modal = false
|
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'music-composer-albums',
|
name: 'music-composer-albums',
|
||||||
params: { name: this.composer.name }
|
params: { name: this.composer.name }
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="play" size="16" />
|
<mdicon class="icon" name="play" size="16" />
|
||||||
<span v-text="$t('page.files.play')" />
|
<span v-text="$t('page.files.play')" />
|
||||||
</a>
|
</a>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<list-directories :items="directories" />
|
<list-directories :items="directories" />
|
||||||
<list-playlists :items="playlists" />
|
<list-playlists :items="playlists" />
|
||||||
<list-tracks
|
<list-tracks
|
||||||
:expression="play_expression"
|
:expression="expression"
|
||||||
:items="tracks"
|
:items="tracks"
|
||||||
:show_icon="true"
|
:show_icon="true"
|
||||||
/>
|
/>
|
||||||
@ -83,26 +83,22 @@ export default {
|
|||||||
ListTracks,
|
ListTracks,
|
||||||
ModalDialogDirectory
|
ModalDialogDirectory
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteUpdate(to, from, next) {
|
beforeRouteUpdate(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
dataObject.set(this, response)
|
dataObject.set(this, response)
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
configurationStore: useConfigurationStore()
|
configurationStore: useConfigurationStore()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
directories: [],
|
directories: [],
|
||||||
@ -111,7 +107,6 @@ export default {
|
|||||||
tracks: new GroupedList()
|
tracks: new GroupedList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
current() {
|
current() {
|
||||||
return this.$route.query?.directory || '/'
|
return this.$route.query?.directory || '/'
|
||||||
@ -122,14 +117,13 @@ export default {
|
|||||||
}
|
}
|
||||||
return this.$t('page.files.title')
|
return this.$t('page.files.title')
|
||||||
},
|
},
|
||||||
play_expression() {
|
expression() {
|
||||||
return `path starts with "${this.current}" order by path asc`
|
return `path starts with "${this.current}" order by path asc`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
play() {
|
play() {
|
||||||
webapi.player_play_expression(this.play_expression, false)
|
webapi.player_play_expression(this.expression, false)
|
||||||
},
|
},
|
||||||
transform(path) {
|
transform(path) {
|
||||||
return { name: path.slice(path.lastIndexOf('/') + 1), path }
|
return { name: path.slice(path.lastIndexOf('/') + 1), path }
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.genre.shuffle')" />
|
<span v-text="$t('page.genre.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
@ -59,7 +59,6 @@ const dataObject = {
|
|||||||
webapi.library_genre_albums(to.params.name, to.query.media_kind)
|
webapi.library_genre_albums(to.params.name, to.query.media_kind)
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
|
|
||||||
set(vm, response) {
|
set(vm, response) {
|
||||||
vm.genre = response[0].data.genres.items.shift()
|
vm.genre = response[0].data.genres.items.shift()
|
||||||
vm.albums = new GroupedList(response[1].data.albums, {
|
vm.albums = new GroupedList(response[1].data.albums, {
|
||||||
@ -81,7 +80,6 @@ export default {
|
|||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: new GroupedList(),
|
albums: new GroupedList(),
|
||||||
|
@ -32,12 +32,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.genre.shuffle')" />
|
<span v-text="$t('page.genre.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
@ -89,17 +89,14 @@ export default {
|
|||||||
ListTracks,
|
ListTracks,
|
||||||
ModalDialogGenre
|
ModalDialogGenre
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
dataObject.load(to).then((response) => {
|
dataObject.load(to).then((response) => {
|
||||||
next((vm) => dataObject.set(vm, response))
|
next((vm) => dataObject.set(vm, response))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return { uiStore: useUIStore() }
|
return { uiStore: useUIStore() }
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
genre: {},
|
genre: {},
|
||||||
@ -123,7 +120,6 @@ export default {
|
|||||||
tracks_list: new GroupedList()
|
tracks_list: new GroupedList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
expression() {
|
expression() {
|
||||||
return `genre is "${this.genre.name}" and media_kind is ${this.media_kind}`
|
return `genre is "${this.genre.name}" and media_kind is ${this.media_kind}`
|
||||||
@ -135,7 +131,6 @@ export default {
|
|||||||
return this.tracks_list.group(options)
|
return this.tracks_list.group(options)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
open_genre() {
|
open_genre() {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.playlist.shuffle')" />
|
<span v-text="$t('page.playlist.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
<template #heading-right>
|
<template #heading-right>
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_playlist_details_modal = true"
|
@click="show_playlist_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
</a>
|
</a>
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="shuffle" size="16" />
|
<mdicon class="icon" name="shuffle" size="16" />
|
||||||
<span v-text="$t('page.spotify.playlist.shuffle')" />
|
<span v-text="$t('page.spotify.playlist.shuffle')" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons is-centered-mobile mt-5">
|
<div class="buttons is-centered-mobile mt-5">
|
||||||
<a class="button is-small is-dark is-rounded" @click="play">
|
<a class="button is-small is-rounded" @click="play">
|
||||||
<mdicon class="icon" name="play" size="16" />
|
<mdicon class="icon" name="play" size="16" />
|
||||||
<span v-text="$t('page.podcast.play')" />
|
<span v-text="$t('page.podcast.play')" />
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
class="button is-small is-light is-rounded"
|
class="button is-small is-rounded"
|
||||||
@click="show_details_modal = true"
|
@click="show_details_modal = true"
|
||||||
>
|
>
|
||||||
<mdicon class="icon" name="dots-horizontal" size="16" />
|
<mdicon class="icon" name="dots-horizontal" size="16" />
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<p v-text="$t('page.settings.services.spotify.requirements')" />
|
<p v-text="$t('page.settings.services.spotify.requirements')" />
|
||||||
<p v-text="spotify_required_scope.join(', ')" />
|
<p v-text="spotify_required_scope.join(', ')" />
|
||||||
</div>
|
</div>
|
||||||
<p v-if="spotify.webapi_token_valid">
|
<p v-if="spotify.webapi_token_valid" class="content">
|
||||||
<span v-text="$t('page.settings.services.spotify.user')" />
|
<span v-text="$t('page.settings.services.spotify.user')" />
|
||||||
<code v-text="spotify.webapi_user" />
|
<code v-text="spotify.webapi_user" />
|
||||||
</p>
|
</p>
|
||||||
|
@ -315,53 +315,50 @@ export default {
|
|||||||
return axios.get('./api/queue')
|
return axios.get('./api/queue')
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_add(uri) {
|
async queue_add(uri) {
|
||||||
return axios.post(`./api/queue/items/add?uris=${uri}`).then((response) => {
|
const response = await axios.post(`./api/queue/items/add?uris=${uri}`)
|
||||||
useNotificationsStore().add({
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', { count: response.data.count }),
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
|
||||||
return Promise.resolve(response)
|
|
||||||
})
|
})
|
||||||
|
return await Promise.resolve(response)
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_add_next(uri) {
|
async queue_add_next(uri) {
|
||||||
let position = 0
|
let position = 0
|
||||||
const { current } = useQueueStore()
|
const { current } = useQueueStore()
|
||||||
if (current?.id) {
|
if (current?.id) {
|
||||||
position = current.position + 1
|
position = current.position + 1
|
||||||
}
|
}
|
||||||
return axios
|
const response = await axios.post(
|
||||||
.post(`./api/queue/items/add?uris=${uri}&position=${position}`)
|
`./api/queue/items/add?uris=${uri}&position=${position}`
|
||||||
.then((response) => {
|
)
|
||||||
useNotificationsStore().add({
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', { count: response.data.count }),
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
})
|
||||||
return Promise.resolve(response)
|
return await Promise.resolve(response)
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_clear() {
|
queue_clear() {
|
||||||
return axios.put('./api/queue/clear')
|
return axios.put('./api/queue/clear')
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_expression_add(expression) {
|
async queue_expression_add(expression) {
|
||||||
return axios
|
const response = await axios.post('./api/queue/items/add', null, {
|
||||||
.post('./api/queue/items/add', null, { params: { expression } })
|
params: { expression }
|
||||||
.then((response) => {
|
})
|
||||||
useNotificationsStore().add({
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', { count: response.data.count }),
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
})
|
||||||
return Promise.resolve(response)
|
return await Promise.resolve(response)
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_expression_add_next(expression) {
|
async queue_expression_add_next(expression) {
|
||||||
const params = {}
|
const params = {}
|
||||||
params.expression = expression
|
params.expression = expression
|
||||||
params.position = 0
|
params.position = 0
|
||||||
@ -369,16 +366,13 @@ export default {
|
|||||||
if (current?.id) {
|
if (current?.id) {
|
||||||
params.position = current.position + 1
|
params.position = current.position + 1
|
||||||
}
|
}
|
||||||
return axios
|
const response = await axios.post('./api/queue/items/add', null, { params })
|
||||||
.post('./api/queue/items/add', null, { params })
|
useNotificationsStore().add({
|
||||||
.then((response) => {
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
useNotificationsStore().add({
|
timeout: 2000,
|
||||||
text: t('server.appended-tracks', { count: response.data.count }),
|
type: 'info'
|
||||||
timeout: 2000,
|
})
|
||||||
type: 'info'
|
return await Promise.resolve(response)
|
||||||
})
|
|
||||||
return Promise.resolve(response)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_move(itemId, position) {
|
queue_move(itemId, position) {
|
||||||
@ -389,17 +383,16 @@ export default {
|
|||||||
return axios.delete(`./api/queue/items/${itemId}`)
|
return axios.delete(`./api/queue/items/${itemId}`)
|
||||||
},
|
},
|
||||||
|
|
||||||
queue_save_playlist(name) {
|
async queue_save_playlist(name) {
|
||||||
return axios
|
const response = await axios.post('./api/queue/save', null, {
|
||||||
.post('./api/queue/save', null, { params: { name } })
|
params: { name }
|
||||||
.then((response) => {
|
})
|
||||||
useNotificationsStore().add({
|
useNotificationsStore().add({
|
||||||
text: t('server.queue-saved', { name }),
|
text: t('server.queue-saved', { name }),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
})
|
||||||
return Promise.resolve(response)
|
return await Promise.resolve(response)
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
search(params) {
|
search(params) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user