[web] Refactor modal dialogs

This commit is contained in:
Alain Nussbaumer
2025-02-09 17:52:45 +01:00
parent b9b36855f4
commit e3c8d1fab9
25 changed files with 453 additions and 639 deletions

View File

@@ -44,14 +44,12 @@ export default {
items: { required: true, type: Object },
media_kind: { required: true, type: String }
},
data() {
return {
selected_item: {},
show_details_modal: false
}
},
methods: {
open(item) {
this.$router.push({

View File

@@ -11,7 +11,7 @@
<footer v-if="actions.length" class="card-footer">
<a
v-for="action in actions"
:key="action.event"
:key="action.label"
class="card-footer-item"
:class="{ 'is-disabled': action.disabled }"
@click="action.handler"

View File

@@ -1,7 +1,11 @@
<template>
<modal-dialog :actions="actions" :show="show" @close="$emit('close')">
<modal-dialog
:actions="actions"
:show="show"
:title="$t('dialog.add.rss.title')"
@close="$emit('close')"
>
<template #content>
<p class="title is-4" v-text="$t('dialog.add.rss.title')" />
<div class="field">
<p class="control has-icons-left">
<input

View File

@@ -1,8 +1,12 @@
<template>
<modal-dialog :actions="actions" :show="show" @close="$emit('close')">
<modal-dialog
:actions="actions"
:show="show"
:title="$t('dialog.add.stream.title')"
@close="$emit('close')"
>
<template #content>
<form @submit.prevent="play">
<p class="title is-4" v-text="$t('dialog.add.stream.title')" />
<div class="field">
<p class="control has-icons-left">
<input

View File

@@ -1,107 +1,78 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<cover-artwork
:url="item.artwork_url"
:artist="item.artist"
:album="item.name"
class="is-normal mb-3"
/>
<div v-if="media_kind_resolved === 'podcast'" class="buttons">
<a
class="button is-small"
@click="mark_played"
v-text="$t('dialog.album.mark-as-played')"
/>
<a
v-if="item.data_kind === 'url'"
class="button is-small"
@click="$emit('remove-podcast')"
v-text="$t('dialog.album.remove-podcast')"
/>
</div>
<div v-if="item.artist" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.album.artist')"
/>
<div class="title is-6">
<a @click="open_artist" v-text="item.artist" />
</div>
</div>
<div v-if="item.date_released" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.album.release-date')"
/>
<div class="title is-6" v-text="$filters.date(item.date_released)" />
</div>
<div v-else-if="item.year" class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.album.year')" />
<div class="title is-6" v-text="item.year" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.album.tracks')"
/>
<div class="title is-6" v-text="item.track_count" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.album.duration')"
/>
<div
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</div>
<div class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.album.type')" />
<div
class="title is-6"
v-text="
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
"
/>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.album.added-on')"
/>
<div class="title is-6" v-text="$filters.datetime(item.time_added)" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
import CoverArtwork from '@/components/CoverArtwork.vue'
import ModalDialogPlayable from '@/components/ModalDialogPlayable.vue'
import webapi from '@/webapi'
export default {
name: 'ModalDialogAlbum',
components: { ModalDialogPlayable, CoverArtwork },
components: { ModalDialogPlayable },
props: {
item: { required: true, type: Object },
media_kind: { default: '', type: String },
show: Boolean
},
emits: ['close', 'remove-podcast', 'play-count-changed'],
data() {
return {
artwork_visible: false
}
},
computed: {
buttons() {
if (this.media_kind_resolved === 'podcast') {
if (item.data_kind === 'url') {
return [
{ label: 'dialog.album.mark-as-played', action: this.mark_played },
{
label: 'dialog.album.remove-podcast',
action: this.remove_podcast
}
]
}
return [
{ label: 'dialog.album.mark-as-played', action: this.mark_played }
]
}
return []
},
media_kind_resolved() {
return this.media_kind || this.item.media_kind
},
playable() {
return {
name: this.item.name,
action: this.open,
image: this.item.artwork_url,
artist: this.item.artist,
album: this.item.name,
properties: [
{
label: 'dialog.album.artist',
value: this.item.artist,
action: this.open_artist
},
{
label: 'dialog.album.release-date',
value: this.$filters.date(this.item.date_released)
},
{ label: 'dialog.album.year', value: this.item.year },
{ label: 'dialog.album.tracks', value: this.item.track_count },
{
label: 'dialog.album.duration',
value: this.$filters.durationInHours(this.item.length_ms)
},
{
label: 'dialog.album.type',
value: `${this.$t(`media.kind.${this.item.media_kind}`)} - ${this.$t(`data.kind.${this.item.data_kind}`)}`
},
{
label: 'dialog.album.added-on',
value: this.$filters.datetime(this.item.time_added)
}
]
}
}
},
methods: {
@@ -142,6 +113,9 @@ export default {
params: { id: this.item.artist_id }
})
}
},
remove_podcast() {
this.$emit('remove-podcast')
}
}
}

View File

@@ -1,55 +1,46 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<cover-artwork
:url="artwork_url(item)"
:artist="item.artist"
:album="item.name"
class="is-normal mb-3"
/>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.album.album-artist')"
/>
<div class="title is-6">
<a @click="open_artist" v-text="item.artists[0].name" />
</div>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.album.release-date')"
/>
<div class="title is-6" v-text="$filters.date(item.release_date)" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.album.type')"
/>
<div class="title is-6" v-text="item.album_type" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
import CoverArtwork from '@/components/CoverArtwork.vue'
import ModalDialogPlayable from '@/components/ModalDialogPlayable.vue'
export default {
name: 'ModalDialogAlbumSpotify',
components: { ModalDialogPlayable, CoverArtwork },
components: { ModalDialogPlayable },
props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'],
computed: {
playable() {
return {
name: this.item.name || '',
image: this.item?.images?.[0]?.url || '',
artist: this.item.artist || '',
album: this.item.name || '',
action: this.open,
properties: [
{
label: 'dialog.spotify.album.album-artist',
value: this.item?.artists?.[0]?.name,
action: this.open_artist
},
{
label: 'dialog.spotify.album.release-date',
value: this.$filters.date(this.item.release_date)
},
{
label: 'dialog.spotify.album.type',
value: this.item.album_type
}
]
}
}
},
methods: {
artwork_url(item) {
return item.images?.[0]?.url || ''
},
open() {
this.$emit('close')
this.$router.push({

View File

@@ -1,36 +1,9 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.artist.albums')"
/>
<div class="title is-6" v-text="item.album_count" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.artist.tracks')"
/>
<div class="title is-6" v-text="item.track_count" />
</div>
<div class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.artist.type')" />
<div class="title is-6" v-text="$t(`data.kind.${item.data_kind}`)" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.artist.added-on')"
/>
<div class="title is-6" v-text="$filters.datetime(item.time_added)" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
@@ -41,6 +14,26 @@ export default {
components: { ModalDialogPlayable },
props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'],
computed: {
playable() {
return {
name: this.item.name,
action: this.open,
properties: [
{ label: 'dialog.artist.albums', value: this.item.album_count },
{ label: 'dialog.artist.tracks', value: this.item.track_count },
{
label: 'dialog.artist.type',
value: this.$t(`data.kind.${this.item.data_kind}`)
},
{
label: 'dialog.artist.added-on',
value: this.$filters.datetime(this.item.time_added)
}
]
}
}
},
methods: {
open() {
this.$emit('close')

View File

@@ -1,28 +1,9 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.artist.popularity')"
/>
<div
class="title is-6"
v-text="[item.popularity, item.followers.total].join(' / ')"
/>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.artist.genres')"
/>
<div class="title is-6" v-text="item.genres.join(', ')" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
@@ -33,6 +14,26 @@ export default {
components: { ModalDialogPlayable },
props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'],
computed: {
playable() {
return {
name: this.item.name,
action: this.open,
properties: [
{
label: 'dialog.spotify.artist.popularity',
value: [this.item.popularity, this.item.followers?.total].join(
' / '
)
},
{
label: 'dialog.spotify.artist.genres',
value: this.item.genres?.join(', ')
}
]
}
}
},
methods: {
open() {
this.$emit('close')

View File

@@ -1,43 +1,9 @@
<template>
<modal-dialog-playable
:expression="expression"
:item="playable"
:show="show"
@close="$emit('close')"
>
<template #content>
<div class="title is-4">
<a @click="open_albums" v-text="item.name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.composer.albums')"
/>
<div class="title is-6">
<a @click="open_albums" v-text="item.album_count" />
</div>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.composer.tracks')"
/>
<div class="title is-6">
<a @click="open_tracks" v-text="item.track_count" />
</div>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.composer.duration')"
/>
<div
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</div>
</template>
</modal-dialog-playable>
/>
</template>
<script>
@@ -49,8 +15,28 @@ export default {
props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'],
computed: {
expression() {
return `composer is "${this.item.name}" and media_kind is music`
playable() {
return {
action: this.open_albums,
name: this.item.name,
expression: `composer is "${this.item.name}" and media_kind is music`,
properties: [
{
label: 'dialog.composer.albums',
value: this.item.album_count,
action: this.open_albums
},
{
label: 'dialog.composer.tracks',
value: this.item.track_count,
action: this.open_tracks
},
{
label: 'dialog.composer.duration',
value: this.$filters.durationInHours(this.item.length_ms)
}
]
}
}
},
methods: {

View File

@@ -1,8 +1,7 @@
<template>
<modal-dialog-playable
:expression="expression"
:item="playable"
:show="show"
:title="item"
@close="$emit('close')"
/>
</template>
@@ -16,8 +15,11 @@ export default {
props: { item: { required: true, type: String }, show: Boolean },
emits: ['close'],
computed: {
expression() {
return `path starts with "${this.item}" order by path asc`
playable() {
return {
name: this.item,
expression: `path starts with "${this.item}" order by path asc`
}
}
}
}

View File

@@ -1,39 +1,9 @@
<template>
<modal-dialog-playable
:expression="expression"
:item="playable"
:show="show"
@close="$emit('close')"
>
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.genre.albums')"
/>
<div class="title is-6" v-text="item.album_count" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.genre.tracks')"
/>
<div class="title is-6" v-text="item.track_count" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.genre.duration')"
/>
<div
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</div>
</template>
</modal-dialog-playable>
/>
</template>
<script>
@@ -49,8 +19,26 @@ export default {
},
emits: ['close'],
computed: {
expression() {
return `genre is "${this.item.name}" and media_kind is ${this.media_kind}`
playable() {
return {
name: this.item.name,
action: this.open,
expression: `genre is "${this.item.name}" and media_kind is ${this.media_kind}`,
properties: [
{
label: 'dialog.genre.albums',
value: this.item.album_count
},
{
label: 'dialog.genre.tracks',
value: this.item.track_count
},
{
label: 'dialog.genre.duration',
value: this.$filters.durationInHours(this.item.length_ms)
}
]
}
}
},
methods: {

View File

@@ -1,26 +1,50 @@
<template>
<modal-dialog :actions="actions" :show="show" @close="$emit('close')">
<template #content>
<slot name="content" />
<div class="title is-4">
<a v-if="item.action" @click="item.action" v-text="item.name"></a>
<span v-else v-text="item.name" />
</div>
<cover-artwork
v-if="item.image"
:url="item.image"
:artist="item.artist"
:album="item.name"
class="is-normal mb-3"
/>
<div v-for="button in buttons" :key="button.label" class="buttons">
<a v-t="button.label" class="button is-small" @click="button.action" />
</div>
<div
v-for="property in item.properties?.filter((p) => p.value)"
:key="property.label"
class="mb-3"
>
<div v-t="property.label" class="is-size-7 is-uppercase" />
<div class="title is-6">
<a
v-if="property.action"
@click="property.action"
v-text="property.value"
/>
<span v-else class="title is-6" v-text="property.value" />
</div>
</div>
</template>
</modal-dialog>
</template>
<script>
import CoverArtwork from '@/components/CoverArtwork.vue'
import ModalDialog from '@/components/ModalDialog.vue'
import webapi from '@/webapi'
export default {
name: 'ModalDialogPlayable',
components: { ModalDialog },
components: { ModalDialog, CoverArtwork },
props: {
expression: { default: '', type: String },
item: {
default() {
return {}
},
type: Object
},
buttons: { default: () => [], type: Array },
item: { required: true, type: Object },
show: Boolean
},
emits: ['close'],
@@ -48,26 +72,26 @@ export default {
methods: {
play() {
this.$emit('close')
if (this.expression) {
webapi.player_play_expression(this.expression, false)
if (this.item.expression) {
webapi.player_play_expression(this.item.expression, false)
} else {
webapi.player_play_uri(this.item.uri, false)
webapi.player_play_uri(this.item.uris || this.item.item.uri, false)
}
},
queue_add() {
this.$emit('close')
if (this.expression) {
webapi.queue_expression_add(this.expression)
if (this.item.expression) {
webapi.queue_expression_add(this.item.expression)
} else {
webapi.queue_add(this.item.uri)
webapi.queue_add(this.item.uris || this.item.uri)
}
},
queue_add_next() {
this.$emit('close')
if (this.expression) {
webapi.queue_expression_add_next(this.expression)
if (this.item.expression) {
webapi.queue_expression_add_next(this.item.expression)
} else {
webapi.queue_add_next(this.item.uri)
webapi.queue_add_next(this.item.uris || this.item.uri)
}
}
}

View File

@@ -1,41 +1,17 @@
<template>
<modal-dialog :actions="actions" :show="show" @close="$emit('close')">
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.playlist.path')"
/>
<div class="title is-6" v-text="item.path" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.playlist.type')"
/>
<div class="title is-6" v-text="$t(`playlist.type.${item.type}`)" />
</div>
<div v-if="!item.folder" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.playlist.tracks')"
/>
<div class="title is-6" v-text="item.item_count" />
</div>
</template>
</modal-dialog>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
import ModalDialog from '@/components/ModalDialog.vue'
import webapi from '@/webapi'
import ModalDialogPlayable from '@/components/ModalDialogPlayable.vue'
export default {
name: 'ModalDialogPlaylist',
components: { ModalDialog },
components: { ModalDialogPlayable },
props: {
item: { required: true, type: Object },
show: Boolean,
@@ -43,27 +19,20 @@ export default {
},
emits: ['close'],
computed: {
actions() {
if (!this.item.folder) {
return [
playable() {
return {
name: this.item.name,
action: this.open,
uris: this.uris,
properties: [
{ label: 'dialog.playlist.tracks', value: this.item.item_count },
{
label: this.$t('dialog.playlist.add'),
handler: this.queue_add,
icon: 'playlist-plus'
label: 'dialog.playlist.type',
value: this.$t(`playlist.type.${this.item.type}`)
},
{
label: this.$t('dialog.playlist.add-next'),
handler: this.queue_add_next,
icon: 'playlist-play'
},
{
label: this.$t('dialog.playlist.play'),
handler: this.play,
icon: 'play'
}
{ label: 'dialog.playlist.path', value: this.item.path }
]
}
return []
}
},
methods: {
@@ -73,18 +42,6 @@ export default {
name: 'playlist',
params: { id: this.item.id }
})
},
play() {
this.$emit('close')
webapi.player_play_uri(this.uris || this.item.uri, false)
},
queue_add() {
this.$emit('close')
webapi.queue_add(this.uris || this.item.uri)
},
queue_add_next() {
this.$emit('close')
webapi.queue_add_next(this.uris || this.item.uri)
}
}
}

View File

@@ -1,8 +1,12 @@
<template>
<modal-dialog :actions="actions" :show="show" @close="$emit('close')">
<modal-dialog
:actions="actions"
:show="show"
:title="$t('dialog.playlist.save.title')"
@close="$emit('close')"
>
<template #content>
<form @submit.prevent="save">
<p class="title is-4" v-text="$t('dialog.playlist.save.title')" />
<div class="field">
<p class="control has-icons-left">
<input

View File

@@ -1,32 +1,9 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<div class="title is-4">
<a @click="open" v-text="item.name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.playlist.owner')"
/>
<div class="title is-6" v-text="item.owner.display_name" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.playlist.tracks')"
/>
<div class="title is-6" v-text="item.tracks.total" />
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.playlist.path')"
/>
<div class="title is-6" v-text="item.uri" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
@@ -37,6 +14,25 @@ export default {
components: { ModalDialogPlayable },
props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'],
computed: {
playable() {
return {
name: this.item.name,
action: this.open,
properties: [
{
label: 'dialog.spotify.playlist.owner',
value: this.item.owner?.display_name
},
{
label: 'dialog.spotify.playlist.tracks',
value: this.item.tracks?.total
},
{ label: 'dialog.spotify.playlist.path', value: this.item.uri }
]
}
}
},
methods: {
open() {
this.$emit('close')

View File

@@ -1,7 +1,11 @@
<template>
<modal-dialog :actions="actions" :show="show" @close="$emit('close')">
<modal-dialog
:actions="actions"
:show="show"
:title="$t('dialog.remote-pairing.title')"
@close="$emit('close')"
>
<template #content>
<p class="title is-4" v-text="$t('dialog.remote-pairing.title')" />
<form @submit.prevent="pair">
<label class="label" v-text="pairing.remote" />
<div class="field">

View File

@@ -1,156 +1,9 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<p class="title is-4" v-text="item.title" />
<p class="subtitle" v-text="item.artist" />
<div v-if="item.media_kind === 'podcast'" class="buttons">
<a
v-if="item.play_count > 0"
class="button is-small"
@click="mark_new"
v-text="$t('dialog.track.mark-as-new')"
/>
<a
v-if="item.play_count === 0"
class="button is-small"
@click="mark_played"
v-text="$t('dialog.track.mark-as-played')"
/>
</div>
<div v-if="item.album" class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.track.album')" />
<div class="title is-6">
<a @click="open_album" v-text="item.album" />
</div>
</div>
<div
v-if="item.album_artist && item.media_kind !== 'audiobook'"
class="mb-3"
>
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.album-artist')"
/>
<div class="title is-6">
<a @click="open_album_artist" v-text="item.album_artist" />
</div>
</div>
<div v-if="item.composer" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.composer')"
/>
<div class="title is-6" v-text="item.composer" />
</div>
<div v-if="item.date_released" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.release-date')"
/>
<div class="title is-6" v-text="$filters.date(item.date_released)" />
</div>
<div v-else-if="item.year" class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.track.year')" />
<div class="title is-6" v-text="item.year" />
</div>
<div v-if="item.genre" class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.track.genre')" />
<div class="title is-6">
<a @click="open_genre" v-text="item.genre" />
</div>
</div>
<div v-if="item.disc_number" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.position')"
/>
<div
class="title is-6"
v-text="[item.disc_number, item.track_number].join(' / ')"
/>
</div>
<div v-if="item.length_ms" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.duration')"
/>
<div
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</div>
<div class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.track.path')" />
<div class="title is-6" v-text="item.path" />
</div>
<div class="mb-3">
<div class="is-size-7 is-uppercase" v-text="$t('dialog.track.type')" />
<div
class="title is-6"
v-text="
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
"
/>
</div>
<div v-if="item.samplerate" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.quality')"
/>
<div class="title is-6">
<span v-text="item.type" />
<span
v-if="item.samplerate"
v-text="
$t('dialog.track.samplerate', {
rate: item.samplerate
})
"
/>
<span
v-if="item.channels"
v-text="
$t('dialog.track.channels', {
channels: $filters.channels(item.channels)
})
"
/>
<span
v-if="item.bitrate"
v-text="$t('dialog.track.bitrate', { rate: item.bitrate })"
/>
</div>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.added-on')"
/>
<div class="title is-6" v-text="$filters.datetime(item.time_added)" />
</div>
<div>
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.rating')"
/>
<div
class="title is-6"
v-text="
$t('dialog.track.rating-value', {
rating: Math.floor(item.rating / 10)
})
"
/>
</div>
<div v-if="item.comment" class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.track.comment')"
/>
<div class="title is-6" v-text="item.comment" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
@@ -172,6 +25,78 @@ export default {
spotify_track: {}
}
},
computed: {
buttons() {
if (this.item.media_kind === 'podcast') {
if (this.item.play_count > 0) {
return [{ label: 'dialog.track.mark-as-new', action: this.mark_new }]
}
if (this.item.play_count === 0) {
return [
{ label: 'dialog.track.mark-as-played', action: this.mark_played }
]
}
}
return []
},
playable() {
return {
name: this.item.title,
properties: [
{
label: 'dialog.track.album',
value: this.item.album,
action: this.open_album
},
{
label: 'dialog.track.album-artist',
value: this.item.album_artist,
action: this.open_artist
},
{ label: 'dialog.track.composer', value: this.item.composer },
{
label: 'dialog.track.release-date',
value: this.$filters.date(this.item.date_released)
},
{ label: 'dialog.track.year', value: this.item.year },
{ label: 'dialog.track.genre', value: this.item.genre },
{
label: 'dialog.track.position',
value: [this.item.disc_number, this.item.track_number].join(' / ')
},
{
label: 'dialog.track.duration',
value: this.$filters.durationInHours(this.item.length_ms)
},
{
label: 'dialog.track.type',
value: `${this.$t(`media.kind.${this.item.media_kind}`)} - ${this.$t(`data.kind.${this.item.data_kind}`)}`
},
{
label: 'dialog.track.quality',
value: this.$t('dialog.track.quality-value', {
format: this.item.type,
bitrate: this.item.bitrate,
channels: this.$filters.channels(this.item.channels),
samplerate: this.item.samplerate
})
},
{
label: 'dialog.track.added-on',
value: this.$filters.datetime(this.item.time_added)
},
{
label: 'dialog.track.rating',
value: this.$t('dialog.track.rating-value', {
rating: Math.floor(this.item.rating / 10)
})
},
{ label: 'dialog.track.comment', value: this.item.comment },
{ label: 'dialog.track.path', value: this.item.path }
]
}
}
},
watch: {
item() {
if (
@@ -234,7 +159,7 @@ export default {
})
}
},
open_album_artist() {
open_artist() {
if (this.item.data_kind === 'spotify') {
this.$router.push({
name: 'music-spotify-artist',

View File

@@ -1,65 +1,9 @@
<template>
<modal-dialog-playable :item="item" :show="show" @close="$emit('close')">
<template #content>
<p class="title is-4" v-text="item.name" />
<p class="subtitle" v-text="item.artists[0].name" />
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.track.album')"
/>
<div class="title is-6">
<a @click="open_album" v-text="item.album.name" />
</div>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.track.album-artist')"
/>
<div class="title is-6">
<a @click="open_artist" v-text="item.artists[0].name" />
</div>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.track.release-date')"
/>
<div
class="title is-6"
v-text="$filters.date(item.album.release_date)"
/>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.track.position')"
/>
<div
class="title is-6"
v-text="[item.disc_number, item.track_number].join(' / ')"
/>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.track.duration')"
/>
<div
class="title is-6"
v-text="$filters.durationInHours(item.duration_ms)"
/>
</div>
<div class="mb-3">
<div
class="is-size-7 is-uppercase"
v-text="$t('dialog.spotify.track.path')"
/>
<div class="title is-6" v-text="item.uri" />
</div>
</template>
</modal-dialog-playable>
<modal-dialog-playable
:item="playable"
:show="show"
@close="$emit('close')"
/>
</template>
<script>
@@ -70,6 +14,39 @@ export default {
components: { ModalDialogPlayable },
props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'],
computed: {
playable() {
return {
name: this.item.name,
subtitle: this.item.artists[0].name,
properties: [
{
label: 'dialog.spotify.track.album',
value: this.item.album.name,
action: this.open_album
},
{
label: 'dialog.spotify.track.album-artist',
value: this.item.artists[0].name,
action: this.open_artist
},
{
label: 'dialog.spotify.track.release-date',
value: this.$filters.date(item.album.release_date)
},
{
label: 'dialog.spotify.track.position',
value: [item.disc_number, item.track_number].join(' / ')
},
{
label: 'dialog.spotify.track.duration',
value: this.$filters.durationInHours(item.duration_ms)
},
{ label: 'dialog.spotify.track.path', value: this.item.uri }
]
}
}
},
methods: {
open_album() {
this.$emit('close')