[web] Avoid the scrollable page behind all modal dialogs

This commit is contained in:
Alain Nussbaumer 2024-09-10 21:05:12 +02:00
parent 8f627f1df0
commit c8e4862245
18 changed files with 967 additions and 1220 deletions

View File

@ -0,0 +1,37 @@
<template>
<transition name="fade">
<div v-if="show" class="modal is-active">
<div class="modal-background" @click="$emit('close')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<slot name="content" />
</div>
<footer class="card-footer is-clipped">
<slot name="footer" />
</footer>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
name: 'BaseModal',
props: {
show: Boolean
},
emits: ['close'],
watch: {
show(value) {
const { classList } = document.querySelector('html')
if (value) {
classList.add('is-clipped')
} else {
classList.remove('is-clipped')
}
}
}
}
</script>

View File

@ -1,49 +1,40 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p v-if="title" class="title is-4" v-text="title" />
<div class="modal-content"> <slot name="modal-content" />
<div class="card"> </template>
<div class="card-content"> <template #footer>
<p v-if="title" class="title is-4" v-text="title" /> <a class="card-footer-item has-text-dark" @click="$emit('close')">
<slot name="modal-content" /> <mdicon class="icon" name="cancel" size="16" />
</div> <span class="is-size-7" v-text="close_action" />
<footer class="card-footer"> </a>
<a class="card-footer-item has-text-dark" @click="$emit('close')"> <a
<mdicon class="icon" name="cancel" size="16" /> v-if="delete_action"
<span class="is-size-7" v-text="close_action" /> class="card-footer-item has-background-danger has-text-white has-text-weight-bold"
</a> @click="$emit('delete')"
<a >
v-if="delete_action" <mdicon class="icon" name="delete" size="16" />
class="card-footer-item has-background-danger has-text-white has-text-weight-bold" <span class="is-size-7" v-text="delete_action" />
@click="$emit('delete')" </a>
> <a
<mdicon class="icon" name="delete" size="16" /> v-if="ok_action"
<span class="is-size-7" v-text="delete_action" /> class="card-footer-item has-background-info has-text-white has-text-weight-bold"
</a> @click="$emit('ok')"
<a >
v-if="ok_action" <mdicon class="icon" name="check" size="16" />
class="card-footer-item has-background-info has-text-white has-text-weight-bold" <span class="is-size-7" v-text="ok_action" />
@click="$emit('ok')" </a>
> </template>
<mdicon class="icon" name="check" size="16" /> </base-modal>
<span class="is-size-7" v-text="ok_action" />
</a>
</footer>
</div>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/>
</div>
</transition>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
export default { export default {
name: 'ModalDialog', name: 'ModalDialog',
components: { BaseModal },
props: { props: {
close_action: { default: '', type: String }, close_action: { default: '', type: String },
delete_action: { default: '', type: String }, delete_action: { default: '', type: String },

View File

@ -1,68 +1,55 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4" v-text="$t('dialog.add.rss.title')" />
<div class="modal-content"> <div class="field">
<form class="card" @submit.prevent="add_stream"> <p class="control has-icons-left">
<div class="card-content"> <input
<p class="title is-4" v-text="$t('dialog.add.rss.title')" /> ref="url_field"
<div class="field"> v-model="url"
<p class="control has-icons-left"> class="input is-shadowless"
<input type="url"
ref="url_field" pattern="http[s]?://.+"
v-model="url" required
class="input is-shadowless" :placeholder="$t('dialog.add.rss.placeholder')"
type="url" :disabled="loading"
pattern="http[s]?://.+" @input="check_url"
required />
:placeholder="$t('dialog.add.rss.placeholder')" <mdicon class="icon is-left" name="rss" size="16" />
:disabled="loading" </p>
@input="check_url" <p class="help" v-text="$t('dialog.add.rss.help')" />
/>
<mdicon class="icon is-left" name="rss" size="16" />
</p>
<p class="help" v-text="$t('dialog.add.rss.help')" />
</div>
</div>
<footer v-if="loading" class="card-footer">
<a class="card-footer-item has-text-dark">
<mdicon class="icon" name="web" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.add.rss.processing')"
/>
</a>
</footer>
<footer v-else class="card-footer is-clipped">
<a class="card-footer-item has-text-dark" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.rss.cancel')" />
</a>
<a
:class="{ 'is-disabled': disabled }"
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="add_stream"
>
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.rss.add')" />
</a>
</footer>
</form>
</div> </div>
<button </template>
class="modal-close is-large" <template v-if="loading" #footer>
aria-label="close" <a class="card-footer-item has-text-dark">
@click="$emit('close')" <mdicon class="icon" name="web" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.add.rss.processing')" />
</div> </a>
</transition> </template>
<template v-else #footer>
<a class="card-footer-item has-text-dark" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.rss.cancel')" />
</a>
<a
:class="{ 'is-disabled': disabled }"
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="add_stream"
>
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.rss.add')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogAddRss', name: 'ModalDialogAddRss',
components: { BaseModal },
props: { show: Boolean }, props: { show: Boolean },
emits: ['close', 'podcast-added'], emits: ['close', 'podcast-added'],

View File

@ -1,75 +1,64 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <form @submit.prevent="play">
<div class="modal-content"> <p class="title is-4" v-text="$t('dialog.add.stream.title')" />
<form class="card" @submit.prevent="play"> <div class="field">
<div class="card-content"> <p class="control has-icons-left">
<p class="title is-4" v-text="$t('dialog.add.stream.title')" /> <input
<div class="field"> ref="url_field"
<p class="control has-icons-left"> v-model="url"
<input class="input is-shadowless"
ref="url_field" type="url"
v-model="url" pattern="http[s]?://.+"
class="input is-shadowless" required
type="url" :placeholder="$t('dialog.add.stream.placeholder')"
pattern="http[s]?://.+" :disabled="loading"
required @input="check_url"
:placeholder="$t('dialog.add.stream.placeholder')" />
:disabled="loading" <mdicon class="icon is-left" name="web" size="16" />
@input="check_url" </p>
/> </div>
<mdicon class="icon is-left" name="web" size="16" /> </form>
</p> </template>
</div> <template v-if="loading" #footer>
</div> <a class="card-footer-item has-text-dark">
<footer v-if="loading" class="card-footer"> <mdicon class="icon" name="web" size="16" />
<a class="card-footer-item has-text-dark"> <span class="is-size-7" v-text="$t('dialog.add.stream.loading')" />
<mdicon class="icon" name="web" size="16" /> </a>
<span </template>
class="is-size-7" <template v-else #footer>
v-text="$t('dialog.add.stream.loading')" <a class="card-footer-item has-text-dark" @click="$emit('close')">
/> <mdicon class="icon" name="cancel" size="16" />
</a> <span class="is-size-7" v-text="$t('dialog.add.stream.cancel')" />
</footer> </a>
<footer v-else class="card-footer is-clipped"> <a
<a class="card-footer-item has-text-dark" @click="$emit('close')"> :class="{ 'is-disabled': disabled }"
<mdicon class="icon" name="cancel" size="16" /> class="card-footer-item has-text-dark"
<span class="is-size-7" v-text="$t('dialog.add.stream.cancel')" /> @click="add_stream"
</a> >
<a <mdicon class="icon" name="playlist-plus" size="16" />
:class="{ 'is-disabled': disabled }" <span class="is-size-7" v-text="$t('dialog.add.stream.add')" />
class="card-footer-item has-text-dark" </a>
@click="add_stream" <a
> :class="{ 'is-disabled': disabled }"
<mdicon class="icon" name="playlist-plus" size="16" /> class="card-footer-item has-background-info has-text-white has-text-weight-bold"
<span class="is-size-7" v-text="$t('dialog.add.stream.add')" /> @click="play"
</a> >
<a <mdicon class="icon" name="play" size="16" />
:class="{ 'is-disabled': disabled }" <span class="is-size-7" v-text="$t('dialog.add.stream.play')" />
class="card-footer-item has-background-info has-text-white has-text-weight-bold" </a>
@click="play" </template>
> </base-modal>
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.stream.play')" />
</a>
</footer>
</form>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/>
</div>
</transition>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogAddUrlStream', name: 'ModalDialogAddUrlStream',
components: { BaseModal },
props: { show: Boolean }, props: { show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,116 +1,99 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <cover-artwork
<div class="modal-content"> :url="item.artwork_url"
<div class="card"> :artist="item.artist"
<div class="card-content"> :album="item.name"
<cover-artwork class="fd-has-shadow fd-cover fd-cover-normal-image"
:url="item.artwork_url"
:artist="item.artist"
:album="item.name"
class="fd-has-shadow fd-cover fd-cover-normal-image"
/>
<p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" />
</p>
<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 class="content is-small">
<p v-if="item.artist">
<span class="heading" v-text="$t('dialog.album.artist')" />
<a
class="title is-6 has-text-link"
@click="open_artist"
v-text="item.artist"
/>
</p>
<p v-if="item.date_released">
<span
class="heading"
v-text="$t('dialog.album.release-date')"
/>
<span
class="title is-6"
v-text="$filters.date(item.date_released)"
/>
</p>
<p v-else-if="item.year">
<span class="heading" v-text="$t('dialog.album.year')" />
<span class="title is-6" v-text="item.year" />
</p>
<p>
<span class="heading" v-text="$t('dialog.album.tracks')" />
<span class="title is-6" v-text="item.track_count" />
</p>
<p>
<span class="heading" v-text="$t('dialog.album.duration')" />
<span
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.album.type')" />
<span
class="title is-6"
v-text="
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.album.added-on')" />
<span
class="title is-6"
v-text="$filters.datetime(item.time_added)"
/>
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.play')" />
</a>
</footer>
</div>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/> />
</div> <p class="title is-4">
</transition> <a class="has-text-link" @click="open" v-text="item.name" />
</p>
<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 class="content is-small">
<p v-if="item.artist">
<span class="heading" v-text="$t('dialog.album.artist')" />
<a
class="title is-6 has-text-link"
@click="open_artist"
v-text="item.artist"
/>
</p>
<p v-if="item.date_released">
<span class="heading" v-text="$t('dialog.album.release-date')" />
<span class="title is-6" v-text="$filters.date(item.date_released)" />
</p>
<p v-else-if="item.year">
<span class="heading" v-text="$t('dialog.album.year')" />
<span class="title is-6" v-text="item.year" />
</p>
<p>
<span class="heading" v-text="$t('dialog.album.tracks')" />
<span class="title is-6" v-text="item.track_count" />
</p>
<p>
<span class="heading" v-text="$t('dialog.album.duration')" />
<span
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.album.type')" />
<span
class="title is-6"
v-text="
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.album.added-on')" />
<span
class="title is-6"
v-text="$filters.datetime(item.time_added)"
/>
</p>
</div>
</template>
<template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import CoverArtwork from '@/components/CoverArtwork.vue' import CoverArtwork from '@/components/CoverArtwork.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogAlbum', name: 'ModalDialogAlbum',
components: { CoverArtwork }, components: { BaseModal, CoverArtwork },
props: { props: {
item: { required: true, type: Object }, item: { required: true, type: Object },
media_kind: { default: '', type: String }, media_kind: { default: '', type: String },

View File

@ -1,90 +1,67 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <cover-artwork
<div class="modal-content"> :url="artwork_url(item)"
<div class="card"> :artist="item.artist"
<div class="card-content"> :album="item.name"
<cover-artwork class="fd-has-shadow fd-cover fd-cover-normal-image"
:url="artwork_url(item)" @load="artwork_loaded"
:artist="item.artist" @error="artwork_error"
:album="item.name"
class="fd-has-shadow fd-cover fd-cover-normal-image"
@load="artwork_loaded"
@error="artwork_error"
/>
<p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" />
</p>
<div class="content is-small">
<p>
<span
class="heading"
v-text="$t('dialog.spotify.album.album-artist')"
/>
<a
class="title is-6 has-text-link"
@click="open_artist"
v-text="item.artists[0].name"
/>
</p>
<p>
<span
class="heading"
v-text="$t('dialog.spotify.album.release-date')"
/>
<span
class="title is-6"
v-text="$filters.date(item.release_date)"
/>
</p>
<p>
<span
class="heading"
v-text="$t('dialog.spotify.album.type')"
/>
<span class="title is-6" v-text="item.album_type" />
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.album.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.album.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.album.play')"
/>
</a>
</footer>
</div>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/> />
</div> <p class="title is-4">
</transition> <a class="has-text-link" @click="open" v-text="item.name" />
</p>
<div class="content is-small">
<p>
<span
class="heading"
v-text="$t('dialog.spotify.album.album-artist')"
/>
<a
class="title is-6 has-text-link"
@click="open_artist"
v-text="item.artists[0].name"
/>
</p>
<p>
<span
class="heading"
v-text="$t('dialog.spotify.album.release-date')"
/>
<span class="title is-6" v-text="$filters.date(item.release_date)" />
</p>
<p>
<span class="heading" v-text="$t('dialog.spotify.album.type')" />
<span class="title is-6" v-text="item.album_type" />
</p>
</div>
</template>
<template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.album.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.album.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.album.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import CoverArtwork from '@/components/CoverArtwork.vue' import CoverArtwork from '@/components/CoverArtwork.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogAlbumSpotify', name: 'ModalDialogAlbumSpotify',
components: { CoverArtwork }, components: { BaseModal, CoverArtwork },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,68 +1,55 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4">
<div class="modal-content"> <a class="has-text-link" @click="open" v-text="item.name" />
<div class="card"> </p>
<div class="card-content"> <div class="content is-small">
<p class="title is-4"> <p>
<a class="has-text-link" @click="open" v-text="item.name" /> <span class="heading" v-text="$t('dialog.artist.albums')" />
</p> <span class="title is-6" v-text="item.album_count" />
<div class="content is-small"> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.artist.albums')" /> <span class="heading" v-text="$t('dialog.artist.tracks')" />
<span class="title is-6" v-text="item.album_count" /> <span class="title is-6" v-text="item.track_count" />
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.artist.tracks')" /> <span class="heading" v-text="$t('dialog.artist.type')" />
<span class="title is-6" v-text="item.track_count" /> <span class="title is-6" v-text="$t(`data.kind.${item.data_kind}`)" />
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.artist.type')" /> <span class="heading" v-text="$t('dialog.artist.added-on')" />
<span <span
class="title is-6" class="title is-6"
v-text="$t(`data.kind.${item.data_kind}`)" v-text="$filters.datetime(item.time_added)"
/> />
</p> </p>
<p>
<span class="heading" v-text="$t('dialog.artist.added-on')" />
<span
class="title is-6"
v-text="$filters.datetime(item.time_added)"
/>
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.play')" />
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="queue_add">
@click="$emit('close')" <mdicon class="icon" name="playlist-plus" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.artist.add')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogArtist', name: 'ModalDialogArtist',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,72 +1,50 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4">
<div class="modal-content"> <a class="has-text-link" @click="open" v-text="item.name" />
<div class="card"> </p>
<div class="card-content"> <div class="content is-small">
<p class="title is-4"> <p>
<a class="has-text-link" @click="open" v-text="item.name" /> <span
</p> class="heading"
<div class="content is-small"> v-text="$t('dialog.spotify.artist.popularity')"
<p> />
<span <span
class="heading" class="title is-6"
v-text="$t('dialog.spotify.artist.popularity')" v-text="[item.popularity, item.followers.total].join(' / ')"
/> />
<span </p>
class="title is-6" <p>
v-text="[item.popularity, item.followers.total].join(' / ')" <span class="heading" v-text="$t('dialog.spotify.artist.genres')" />
/> <span class="title is-6" v-text="item.genres.join(', ')" />
</p> </p>
<p>
<span
class="heading"
v-text="$t('dialog.spotify.artist.genres')"
/>
<span class="title is-6" v-text="item.genres.join(', ')" />
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.artist.add')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.artist.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.artist.play')"
/>
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="queue_add">
@click="$emit('close')" <mdicon class="icon" name="playlist-plus" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.spotify.artist.add')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.artist.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.artist.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogArtistSpotify', name: 'ModalDialogArtistSpotify',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,71 +1,57 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4">
<div class="modal-content"> <a class="has-text-link" @click="open_albums" v-text="item.name" />
<div class="card"> </p>
<div class="card-content"> <p>
<p class="title is-4"> <span class="heading" v-text="$t('dialog.composer.albums')" />
<a <a
class="has-text-link" class="has-text-link is-6"
@click="open_albums" @click="open_albums"
v-text="item.name" v-text="item.album_count"
/> />
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.composer.albums')" /> <span class="heading" v-text="$t('dialog.composer.tracks')" />
<a <a
class="has-text-link is-6" class="has-text-link is-6"
@click="open_albums" @click="open_tracks"
v-text="item.album_count" v-text="item.track_count"
/> />
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.composer.tracks')" /> <span class="heading" v-text="$t('dialog.composer.duration')" />
<a <span
class="has-text-link is-6" class="title is-6"
@click="open_tracks" v-text="$filters.durationInHours(item.length_ms)"
v-text="item.track_count" />
/> </p>
</p> </template>
<p> <template #footer>
<span class="heading" v-text="$t('dialog.composer.duration')" /> <a class="card-footer-item has-text-dark" @click="queue_add">
<span <mdicon class="icon" name="playlist-plus" size="16" />
class="title is-6" <span class="is-size-7" v-text="$t('dialog.composer.add')" />
v-text="$filters.durationInHours(item.length_ms)" </a>
/> <a class="card-footer-item has-text-dark" @click="queue_add_next">
</p> <mdicon class="icon" name="playlist-play" size="16" />
</div> <span class="is-size-7" v-text="$t('dialog.composer.add-next')" />
<footer class="card-footer"> </a>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.composer.add')" /> <span class="is-size-7" v-text="$t('dialog.composer.play')" />
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> </template>
<mdicon class="icon" name="playlist-play" size="16" /> </base-modal>
<span class="is-size-7" v-text="$t('dialog.composer.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.composer.play')" />
</a>
</footer>
</div>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/>
</div>
</transition>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogComposer', name: 'ModalDialogComposer',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,45 +1,32 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4" v-text="item" />
<div class="modal-content"> </template>
<div class="card"> <template #footer>
<div class="card-content"> <a class="card-footer-item has-text-dark" @click="queue_add">
<p class="title is-4" v-text="item" /> <mdicon class="icon" name="playlist-plus" size="16" />
</div> <span class="is-size-7" v-text="$t('dialog.directory.add')" />
<footer class="card-footer"> </a>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.directory.add')" /> <span class="is-size-7" v-text="$t('dialog.directory.add-next')" />
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="playlist-play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.directory.play')" />
class="is-size-7" </a>
v-text="$t('dialog.directory.add-next')" </template>
/> </base-modal>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.directory.play')" />
</a>
</footer>
</div>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/>
</div>
</transition>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogDirectory', name: 'ModalDialogDirectory',
components: { BaseModal },
props: { item: { required: true, type: String }, show: Boolean }, props: { item: { required: true, type: String }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,61 +1,51 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4">
<div class="modal-content"> <a class="has-text-link" @click="open" v-text="item.name" />
<div class="card"> </p>
<div class="card-content"> <div class="content is-small">
<p class="title is-4"> <p>
<a class="has-text-link" @click="open" v-text="item.name" /> <span class="heading" v-text="$t('dialog.genre.albums')" />
</p> <span class="title is-6" v-text="item.album_count" />
<div class="content is-small"> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.genre.albums')" /> <span class="heading" v-text="$t('dialog.genre.tracks')" />
<span class="title is-6" v-text="item.album_count" /> <span class="title is-6" v-text="item.track_count" />
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.genre.tracks')" /> <span class="heading" v-text="$t('dialog.genre.duration')" />
<span class="title is-6" v-text="item.track_count" /> <span
</p> class="title is-6"
<p> v-text="$filters.durationInHours(item.length_ms)"
<span class="heading" v-text="$t('dialog.genre.duration')" /> />
<span </p>
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.play')" />
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="queue_add">
@click="$emit('close')" <mdicon class="icon" name="playlist-plus" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.genre.add')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogGenre', name: 'ModalDialogGenre',
components: { BaseModal },
props: { props: {
item: { required: true, type: Object }, item: { required: true, type: Object },
media_kind: { required: true, type: String }, media_kind: { required: true, type: String },

View File

@ -1,61 +1,48 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4">
<div class="modal-content"> <a class="has-text-link" @click="open" v-text="item.name" />
<div class="card"> </p>
<div class="card-content"> <div class="content is-small">
<p class="title is-4"> <p>
<a class="has-text-link" @click="open" v-text="item.name" /> <span class="heading" v-text="$t('dialog.playlist.path')" />
</p> <span class="title is-6" v-text="item.path" />
<div class="content is-small"> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.playlist.path')" /> <span class="heading" v-text="$t('dialog.playlist.type')" />
<span class="title is-6" v-text="item.path" /> <span class="title is-6" v-text="$t(`playlist.type.${item.type}`)" />
</p> </p>
<p> <p v-if="!item.folder">
<span class="heading" v-text="$t('dialog.playlist.type')" /> <span class="heading" v-text="$t('dialog.playlist.tracks')" />
<span <span class="title is-6" v-text="item.item_count" />
class="title is-6" </p>
v-text="$t(`playlist.type.${item.type}`)"
/>
</p>
<p v-if="!item.folder">
<span class="heading" v-text="$t('dialog.playlist.tracks')" />
<span class="title is-6" v-text="item.item_count" />
</p>
</div>
</div>
<footer v-if="!item.folder" class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.play')" />
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template v-if="!item.folder" #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="queue_add">
@click="$emit('close')" <mdicon class="icon" name="playlist-plus" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.playlist.add')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogPlaylist', name: 'ModalDialogPlaylist',
components: { BaseModal },
props: { props: {
item: { required: true, type: Object }, item: { required: true, type: Object },
show: Boolean, show: Boolean,

View File

@ -1,73 +1,56 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <form @submit.prevent="save">
<div class="modal-content"> <p class="title is-4" v-text="$t('dialog.playlist.save.title')" />
<form class="card" @submit.prevent="save"> <div class="field">
<div class="card-content"> <p class="control has-icons-left">
<p class="title is-4" v-text="$t('dialog.playlist.save.title')" /> <input
<div class="field"> ref="playlist_name_field"
<p class="control has-icons-left"> v-model="playlist_name"
<input class="input is-shadowless"
ref="playlist_name_field" type="text"
v-model="playlist_name" pattern=".+"
class="input is-shadowless" required
type="text" :placeholder="$t('dialog.playlist.save.playlist-name')"
pattern=".+" :disabled="loading"
required @input="check_name"
:placeholder="$t('dialog.playlist.save.playlist-name')" />
:disabled="loading" <mdicon class="icon is-left" name="file-music" size="16" />
@input="check_name" </p>
/> </div>
<mdicon class="icon is-left" name="file-music" size="16" /> </form>
</p> </template>
</div> <template v-if="loading" #footer>
</div> <a class="card-footer-item has-text-dark">
<footer v-if="loading" class="card-footer"> <mdicon class="icon" name="web" size="16" />
<a class="card-footer-item has-text-dark"> <span class="is-size-7" v-text="$t('dialog.playlist.save.saving')" />
<mdicon class="icon" name="web" size="16" /> </a>
<span </template>
class="is-size-7" <template v-else #footer>
v-text="$t('dialog.playlist.save.saving')" <a class="card-footer-item has-text-danger" @click="$emit('close')">
/> <mdicon class="icon" name="cancel" size="16" />
</a> <span class="is-size-7" v-text="$t('dialog.playlist.save.cancel')" />
</footer> </a>
<footer v-else class="card-footer is-clipped"> <a
<a class="card-footer-item has-text-danger" @click="$emit('close')"> :class="{ 'is-disabled': disabled }"
<mdicon class="icon" name="cancel" size="16" /> class="card-footer-item has-background-info has-text-white has-text-weight-bold"
<span @click="save"
class="is-size-7" >
v-text="$t('dialog.playlist.save.cancel')" <mdicon class="icon" name="content-save" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.playlist.save.save')" />
</a> </a>
<a </template>
:class="{ 'is-disabled': disabled }" </base-modal>
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="save"
>
<mdicon class="icon" name="content-save" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.playlist.save.save')"
/>
</a>
</footer>
</form>
</div>
<button
class="modal-close is-large"
aria-label="close"
@click="$emit('close')"
/>
</div>
</transition>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogPlaylistSave', name: 'ModalDialogPlaylistSave',
components: { BaseModal },
props: { show: Boolean }, props: { show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,76 +1,51 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4">
<div class="modal-content"> <a class="has-text-link" @click="open" v-text="item.name" />
<div class="card"> </p>
<div class="card-content"> <div class="content is-small">
<p class="title is-4"> <p>
<a class="has-text-link" @click="open" v-text="item.name" /> <span class="heading" v-text="$t('dialog.spotify.playlist.owner')" />
</p> <span class="title is-6" v-text="item.owner.display_name" />
<div class="content is-small"> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.playlist.tracks')" />
class="heading" <span class="title is-6" v-text="item.tracks.total" />
v-text="$t('dialog.spotify.playlist.owner')" </p>
/> <p>
<span class="title is-6" v-text="item.owner.display_name" /> <span class="heading" v-text="$t('dialog.spotify.playlist.path')" />
</p> <span class="title is-6" v-text="item.uri" />
<p> </p>
<span
class="heading"
v-text="$t('dialog.spotify.playlist.tracks')"
/>
<span class="title is-6" v-text="item.tracks.total" />
</p>
<p>
<span
class="heading"
v-text="$t('dialog.spotify.playlist.path')"
/>
<span class="title is-6" v-text="item.uri" />
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.add')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.play')"
/>
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="queue_add">
@click="$emit('close')" <mdicon class="icon" name="playlist-plus" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.spotify.playlist.add')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.playlist.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogPlaylistSpotify', name: 'ModalDialogPlaylistSpotify',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,146 +1,119 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4" v-text="item.title" />
<div class="modal-content"> <p class="subtitle" v-text="item.artist" />
<div class="card"> <div class="content is-small">
<div class="card-content"> <p v-if="item.album">
<p class="title is-4" v-text="item.title" /> <span class="heading" v-text="$t('dialog.queue-item.album')" />
<p class="subtitle" v-text="item.artist" /> <a
<div class="content is-small"> class="title is-6 has-text-link"
<p v-if="item.album"> @click="open_album"
<span class="heading" v-text="$t('dialog.queue-item.album')" /> v-text="item.album"
<a />
class="title is-6 has-text-link" </p>
@click="open_album" <p v-if="item.album_artist">
v-text="item.album" <span class="heading" v-text="$t('dialog.queue-item.album-artist')" />
/> <a
</p> class="title is-6 has-text-link"
<p v-if="item.album_artist"> @click="open_album_artist"
<span v-text="item.album_artist"
class="heading" />
v-text="$t('dialog.queue-item.album-artist')" </p>
/> <p v-if="item.composer">
<a <span class="heading" v-text="$t('dialog.queue-item.composer')" />
class="title is-6 has-text-link" <span class="title is-6" v-text="item.composer" />
@click="open_album_artist" </p>
v-text="item.album_artist" <p v-if="item.year">
/> <span class="heading" v-text="$t('dialog.queue-item.year')" />
</p> <span class="title is-6" v-text="item.year" />
<p v-if="item.composer"> </p>
<span <p v-if="item.genre">
class="heading" <span class="heading" v-text="$t('dialog.queue-item.genre')" />
v-text="$t('dialog.queue-item.composer')" <a
/> class="title is-6 has-text-link"
<span class="title is-6" v-text="item.composer" /> @click="open_genre"
</p> v-text="item.genre"
<p v-if="item.year"> />
<span class="heading" v-text="$t('dialog.queue-item.year')" /> </p>
<span class="title is-6" v-text="item.year" /> <p v-if="item.disc_number">
</p> <span class="heading" v-text="$t('dialog.queue-item.position')" />
<p v-if="item.genre"> <span
<span class="heading" v-text="$t('dialog.queue-item.genre')" /> class="title is-6"
<a v-text="[item.disc_number, item.track_number].join(' / ')"
class="title is-6 has-text-link" />
@click="open_genre" </p>
v-text="item.genre" <p v-if="item.length_ms">
/> <span class="heading" v-text="$t('dialog.queue-item.duration')" />
</p> <span
<p v-if="item.disc_number"> class="title is-6"
<span v-text="$filters.durationInHours(item.length_ms)"
class="heading" />
v-text="$t('dialog.queue-item.position')" </p>
/> <p>
<span <span class="heading" v-text="$t('dialog.queue-item.path')" />
class="title is-6" <span class="title is-6" v-text="item.path" />
v-text="[item.disc_number, item.track_number].join(' / ')" </p>
/> <p>
</p> <span class="heading" v-text="$t('dialog.queue-item.type')" />
<p v-if="item.length_ms"> <span class="title is-6">
<span <span
class="heading" v-text="
v-text="$t('dialog.queue-item.duration')" `${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
/> "
<span />
class="title is-6" </span>
v-text="$filters.durationInHours(item.length_ms)" </p>
/> <p v-if="item.samplerate">
</p> <span class="heading" v-text="$t('dialog.queue-item.quality')" />
<p> <span class="title is-6">
<span class="heading" v-text="$t('dialog.queue-item.path')" /> <span v-text="item.type" />
<span class="title is-6" v-text="item.path" /> <span
</p> v-if="item.samplerate"
<p> v-text="
<span class="heading" v-text="$t('dialog.queue-item.type')" /> $t('dialog.queue-item.samplerate', {
<span class="title is-6"> rate: item.samplerate
<span })
v-text=" "
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}` />
" <span
/> v-if="item.channels"
</span> v-text="
</p> $t('dialog.queue-item.channels', {
<p v-if="item.samplerate"> channels: $filters.channels(item.channels)
<span })
class="heading" "
v-text="$t('dialog.queue-item.quality')" />
/> <span
<span class="title is-6"> v-if="item.bitrate"
<span v-text="item.type" /> v-text="$t('dialog.queue-item.bitrate', { rate: item.bitrate })"
<span />
v-if="item.samplerate" </span>
v-text=" </p>
$t('dialog.queue-item.samplerate', {
rate: item.samplerate
})
"
/>
<span
v-if="item.channels"
v-text="
$t('dialog.queue-item.channels', {
channels: $filters.channels(item.channels)
})
"
/>
<span
v-if="item.bitrate"
v-text="
$t('dialog.queue-item.bitrate', { rate: item.bitrate })
"
/>
</span>
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="remove">
<mdicon class="icon" name="delete" size="16" />
<span class="is-size-7" v-text="$t('dialog.queue-item.remove')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.queue-item.play')" />
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="remove">
@click="$emit('close')" <mdicon class="icon" name="delete" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.queue-item.remove')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.queue-item.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import SpotifyWebApi from 'spotify-web-api-js' import SpotifyWebApi from 'spotify-web-api-js'
import { useServicesStore } from '@/stores/services' import { useServicesStore } from '@/stores/services'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogQueueItem', name: 'ModalDialogQueueItem',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,63 +1,47 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4" v-text="$t('dialog.remote-pairing.title')" />
<div class="modal-content"> <form @submit.prevent="kickoff_pairing">
<div class="card"> <label class="label" v-text="pairing.remote" />
<div class="card-content"> <div class="field">
<p class="title is-4" v-text="$t('dialog.remote-pairing.title')" /> <div class="control">
<form @submit.prevent="kickoff_pairing"> <input
<label class="label" v-text="pairing.remote" /> ref="pin_field"
<div class="field"> v-model="pairing_req.pin"
<div class="control"> class="input"
<input inputmode="numeric"
ref="pin_field" pattern="[\d]{4}"
v-model="pairing_req.pin" :placeholder="$t('dialog.remote-pairing.pairing-code')"
class="input" />
inputmode="numeric"
pattern="[\d]{4}"
:placeholder="$t('dialog.remote-pairing.pairing-code')"
/>
</div>
</div>
</form>
</div> </div>
<footer class="card-footer is-clipped">
<a class="card-footer-item has-text-danger" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.remote-pairing.cancel')"
/>
</a>
<a
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="kickoff_pairing"
>
<mdicon class="icon" name="cellphone" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.remote-pairing.pair')"
/>
</a>
</footer>
</div> </div>
</div> </form>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-danger" @click="$emit('close')">
@click="$emit('close')" <mdicon class="icon" name="cancel" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.remote-pairing.cancel')" />
</div> </a>
</transition> <a
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="kickoff_pairing"
>
<mdicon class="icon" name="cellphone" size="16" />
<span class="is-size-7" v-text="$t('dialog.remote-pairing.pair')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import { useRemotesStore } from '@/stores/remotes' import { useRemotesStore } from '@/stores/remotes'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogRemotePairing', name: 'ModalDialogRemotePairing',
components: { BaseModal },
props: { show: Boolean }, props: { show: Boolean },
emits: ['close'], emits: ['close'],

View File

@ -1,181 +1,162 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4" v-text="item.title" />
<div class="modal-content"> <p class="subtitle" v-text="item.artist" />
<div class="card"> <div v-if="item.media_kind === 'podcast'" class="buttons">
<div class="card-content"> <a
<p class="title is-4" v-text="item.title" /> v-if="item.play_count > 0"
<p class="subtitle" v-text="item.artist" /> class="button is-small"
<div v-if="item.media_kind === 'podcast'" class="buttons"> @click="mark_new"
<a v-text="$t('dialog.track.mark-as-new')"
v-if="item.play_count > 0" />
class="button is-small" <a
@click="mark_new" v-if="item.play_count === 0"
v-text="$t('dialog.track.mark-as-new')" class="button is-small"
/> @click="mark_played"
<a v-text="$t('dialog.track.mark-as-played')"
v-if="item.play_count === 0" />
class="button is-small"
@click="mark_played"
v-text="$t('dialog.track.mark-as-played')"
/>
</div>
<div class="content is-small">
<p v-if="item.album">
<span class="heading" v-text="$t('dialog.track.album')" />
<a
class="title is-6 has-text-link"
@click="open_album"
v-text="item.album"
/>
</p>
<p v-if="item.album_artist && item.media_kind !== 'audiobook'">
<span
class="heading"
v-text="$t('dialog.track.album-artist')"
/>
<a
class="title is-6 has-text-link"
@click="open_album_artist"
v-text="item.album_artist"
/>
</p>
<p v-if="item.composer">
<span class="heading" v-text="$t('dialog.track.composer')" />
<span class="title is-6" v-text="item.composer" />
</p>
<p v-if="item.date_released">
<span
class="heading"
v-text="$t('dialog.track.release-date')"
/>
<span
class="title is-6"
v-text="$filters.date(item.date_released)"
/>
</p>
<p v-else-if="item.year">
<span class="heading" v-text="$t('dialog.track.year')" />
<span class="title is-6" v-text="item.year" />
</p>
<p v-if="item.genre">
<span class="heading" v-text="$t('dialog.track.genre')" />
<a
class="title is-6 has-text-link"
@click="open_genre"
v-text="item.genre"
/>
</p>
<p v-if="item.disc_number">
<span class="heading" v-text="$t('dialog.track.position')" />
<span
class="title is-6"
v-text="[item.disc_number, item.track_number].join(' / ')"
/>
</p>
<p v-if="item.length_ms">
<span class="heading" v-text="$t('dialog.track.duration')" />
<span
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.track.path')" />
<span class="title is-6" v-text="item.path" />
</p>
<p>
<span class="heading" v-text="$t('dialog.track.type')" />
<span
class="title is-6"
v-text="
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
"
/>
</p>
<p v-if="item.samplerate">
<span class="heading" v-text="$t('dialog.track.quality')" />
<span 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 })"
/>
</span>
</p>
<p>
<span class="heading" v-text="$t('dialog.track.added-on')" />
<span
class="title is-6"
v-text="$filters.datetime(item.time_added)"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.track.rating')" />
<span
class="title is-6"
v-text="
$t('dialog.track.rating-value', {
rating: Math.floor(item.rating / 10)
})
"
/>
</p>
<p v-if="item.comment">
<span class="heading" v-text="$t('dialog.track.comment')" />
<span class="title is-6" v-text="item.comment" />
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.play')" />
</a>
</footer>
</div>
</div> </div>
<button <div class="content is-small">
class="modal-close is-large" <p v-if="item.album">
aria-label="close" <span class="heading" v-text="$t('dialog.track.album')" />
@click="$emit('close')" <a
/> class="title is-6 has-text-link"
</div> @click="open_album"
</transition> v-text="item.album"
/>
</p>
<p v-if="item.album_artist && item.media_kind !== 'audiobook'">
<span class="heading" v-text="$t('dialog.track.album-artist')" />
<a
class="title is-6 has-text-link"
@click="open_album_artist"
v-text="item.album_artist"
/>
</p>
<p v-if="item.composer">
<span class="heading" v-text="$t('dialog.track.composer')" />
<span class="title is-6" v-text="item.composer" />
</p>
<p v-if="item.date_released">
<span class="heading" v-text="$t('dialog.track.release-date')" />
<span class="title is-6" v-text="$filters.date(item.date_released)" />
</p>
<p v-else-if="item.year">
<span class="heading" v-text="$t('dialog.track.year')" />
<span class="title is-6" v-text="item.year" />
</p>
<p v-if="item.genre">
<span class="heading" v-text="$t('dialog.track.genre')" />
<a
class="title is-6 has-text-link"
@click="open_genre"
v-text="item.genre"
/>
</p>
<p v-if="item.disc_number">
<span class="heading" v-text="$t('dialog.track.position')" />
<span
class="title is-6"
v-text="[item.disc_number, item.track_number].join(' / ')"
/>
</p>
<p v-if="item.length_ms">
<span class="heading" v-text="$t('dialog.track.duration')" />
<span
class="title is-6"
v-text="$filters.durationInHours(item.length_ms)"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.track.path')" />
<span class="title is-6" v-text="item.path" />
</p>
<p>
<span class="heading" v-text="$t('dialog.track.type')" />
<span
class="title is-6"
v-text="
`${$t(`media.kind.${item.media_kind}`)} - ${$t(`data.kind.${item.data_kind}`)}`
"
/>
</p>
<p v-if="item.samplerate">
<span class="heading" v-text="$t('dialog.track.quality')" />
<span 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 })"
/>
</span>
</p>
<p>
<span class="heading" v-text="$t('dialog.track.added-on')" />
<span
class="title is-6"
v-text="$filters.datetime(item.time_added)"
/>
</p>
<p>
<span class="heading" v-text="$t('dialog.track.rating')" />
<span
class="title is-6"
v-text="
$t('dialog.track.rating-value', {
rating: Math.floor(item.rating / 10)
})
"
/>
</p>
<p v-if="item.comment">
<span class="heading" v-text="$t('dialog.track.comment')" />
<span class="title is-6" v-text="item.comment" />
</p>
</div>
</template>
<template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import SpotifyWebApi from 'spotify-web-api-js' import SpotifyWebApi from 'spotify-web-api-js'
import { useServicesStore } from '@/stores/services' import { useServicesStore } from '@/stores/services'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogTrack', name: 'ModalDialogTrack',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close', 'play-count-changed'], emits: ['close', 'play-count-changed'],

View File

@ -1,110 +1,82 @@
<template> <template>
<transition name="fade"> <base-modal :show="show" @close="$emit('close')">
<div v-if="show" class="modal is-active"> <template #content>
<div class="modal-background" @click="$emit('close')" /> <p class="title is-4" v-text="item.name" />
<div class="modal-content"> <p class="subtitle" v-text="item.artists[0].name" />
<div class="card"> <div class="content is-small">
<div class="card-content"> <p>
<p class="title is-4" v-text="item.name" /> <span class="heading" v-text="$t('dialog.spotify.track.album')" />
<p class="subtitle" v-text="item.artists[0].name" /> <a
<div class="content is-small"> class="title is-6 has-text-link"
<p> @click="open_album"
<span v-text="item.album.name"
class="heading" />
v-text="$t('dialog.spotify.track.album')" </p>
/> <p>
<a <span
class="title is-6 has-text-link" class="heading"
@click="open_album" v-text="$t('dialog.spotify.track.album-artist')"
v-text="item.album.name" />
/> <a
</p> class="title is-6 has-text-link"
<p> @click="open_artist"
<span v-text="item.artists[0].name"
class="heading" />
v-text="$t('dialog.spotify.track.album-artist')" </p>
/> <p>
<a <span
class="title is-6 has-text-link" class="heading"
@click="open_artist" v-text="$t('dialog.spotify.track.release-date')"
v-text="item.artists[0].name" />
/> <span
</p> class="title is-6"
<p> v-text="$filters.date(item.album.release_date)"
<span />
class="heading" </p>
v-text="$t('dialog.spotify.track.release-date')" <p>
/> <span class="heading" v-text="$t('dialog.spotify.track.position')" />
<span <span
class="title is-6" class="title is-6"
v-text="$filters.date(item.album.release_date)" v-text="[item.disc_number, item.track_number].join(' / ')"
/> />
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.track.duration')" />
class="heading" <span
v-text="$t('dialog.spotify.track.position')" class="title is-6"
/> v-text="$filters.durationInHours(item.duration_ms)"
<span />
class="title is-6" </p>
v-text="[item.disc_number, item.track_number].join(' / ')" <p>
/> <span class="heading" v-text="$t('dialog.spotify.track.path')" />
</p> <span class="title is-6" v-text="item.uri" />
<p> </p>
<span
class="heading"
v-text="$t('dialog.spotify.track.duration')"
/>
<span
class="title is-6"
v-text="$filters.durationInHours(item.duration_ms)"
/>
</p>
<p>
<span
class="heading"
v-text="$t('dialog.spotify.track.path')"
/>
<span class="title is-6" v-text="item.uri" />
</p>
</div>
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.track.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.track.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span
class="is-size-7"
v-text="$t('dialog.spotify.track.play')"
/>
</a>
</footer>
</div>
</div> </div>
<button </template>
class="modal-close is-large" <template #footer>
aria-label="close" <a class="card-footer-item has-text-dark" @click="queue_add">
@click="$emit('close')" <mdicon class="icon" name="playlist-plus" size="16" />
/> <span class="is-size-7" v-text="$t('dialog.spotify.track.add')" />
</div> </a>
</transition> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.track.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.track.play')" />
</a>
</template>
</base-modal>
</template> </template>
<script> <script>
import BaseModal from '@/components/BaseModal.vue'
import webapi from '@/webapi' import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogTrackSpotify', name: 'ModalDialogTrackSpotify',
components: { BaseModal },
props: { item: { required: true, type: Object }, show: Boolean }, props: { item: { required: true, type: Object }, show: Boolean },
emits: ['close'], emits: ['close'],