[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,14 +1,10 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p v-if="title" class="title is-4" v-text="title" /> <p v-if="title" class="title is-4" v-text="title" />
<slot name="modal-content" /> <slot name="modal-content" />
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="$emit('close')"> <a class="card-footer-item has-text-dark" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" /> <mdicon class="icon" name="cancel" size="16" />
<span class="is-size-7" v-text="close_action" /> <span class="is-size-7" v-text="close_action" />
@ -29,21 +25,16 @@
<mdicon class="icon" name="check" size="16" /> <mdicon class="icon" name="check" size="16" />
<span class="is-size-7" v-text="ok_action" /> <span class="is-size-7" v-text="ok_action" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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,10 +1,6 @@
<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')" />
<div class="modal-content">
<form class="card" @submit.prevent="add_stream">
<div class="card-content">
<p class="title is-4" v-text="$t('dialog.add.rss.title')" /> <p class="title is-4" v-text="$t('dialog.add.rss.title')" />
<div class="field"> <div class="field">
<p class="control has-icons-left"> <p class="control has-icons-left">
@ -23,17 +19,14 @@
</p> </p>
<p class="help" v-text="$t('dialog.add.rss.help')" /> <p class="help" v-text="$t('dialog.add.rss.help')" />
</div> </div>
</div> </template>
<footer v-if="loading" class="card-footer"> <template v-if="loading" #footer>
<a class="card-footer-item has-text-dark"> <a class="card-footer-item has-text-dark">
<mdicon class="icon" name="web" size="16" /> <mdicon class="icon" name="web" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.add.rss.processing')" />
class="is-size-7"
v-text="$t('dialog.add.rss.processing')"
/>
</a> </a>
</footer> </template>
<footer v-else class="card-footer is-clipped"> <template v-else #footer>
<a class="card-footer-item has-text-dark" @click="$emit('close')"> <a class="card-footer-item has-text-dark" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" /> <mdicon class="icon" name="cancel" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.rss.cancel')" /> <span class="is-size-7" v-text="$t('dialog.add.rss.cancel')" />
@ -46,23 +39,17 @@
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.rss.add')" /> <span class="is-size-7" v-text="$t('dialog.add.rss.add')" />
</a> </a>
</footer> </template>
</form> </base-modal>
</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: 'ModalDialogAddRss', name: 'ModalDialogAddRss',
components: { BaseModal },
props: { show: Boolean }, props: { show: Boolean },
emits: ['close', 'podcast-added'], emits: ['close', 'podcast-added'],

View File

@ -1,10 +1,7 @@
<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">
<form class="card" @submit.prevent="play">
<div class="card-content">
<p class="title is-4" v-text="$t('dialog.add.stream.title')" /> <p class="title is-4" v-text="$t('dialog.add.stream.title')" />
<div class="field"> <div class="field">
<p class="control has-icons-left"> <p class="control has-icons-left">
@ -22,17 +19,15 @@
<mdicon class="icon is-left" name="web" size="16" /> <mdicon class="icon is-left" name="web" size="16" />
</p> </p>
</div> </div>
</div> </form>
<footer v-if="loading" class="card-footer"> </template>
<template v-if="loading" #footer>
<a class="card-footer-item has-text-dark"> <a class="card-footer-item has-text-dark">
<mdicon class="icon" name="web" size="16" /> <mdicon class="icon" name="web" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.add.stream.loading')" />
class="is-size-7"
v-text="$t('dialog.add.stream.loading')"
/>
</a> </a>
</footer> </template>
<footer v-else class="card-footer is-clipped"> <template v-else #footer>
<a class="card-footer-item has-text-dark" @click="$emit('close')"> <a class="card-footer-item has-text-dark" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" /> <mdicon class="icon" name="cancel" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.stream.cancel')" /> <span class="is-size-7" v-text="$t('dialog.add.stream.cancel')" />
@ -53,23 +48,17 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.add.stream.play')" /> <span class="is-size-7" v-text="$t('dialog.add.stream.play')" />
</a> </a>
</footer> </template>
</form> </base-modal>
</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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<cover-artwork <cover-artwork
:url="item.artwork_url" :url="item.artwork_url"
:artist="item.artist" :artist="item.artist"
@ -37,14 +33,8 @@
/> />
</p> </p>
<p v-if="item.date_released"> <p v-if="item.date_released">
<span <span class="heading" v-text="$t('dialog.album.release-date')" />
class="heading" <span class="title is-6" v-text="$filters.date(item.date_released)" />
v-text="$t('dialog.album.release-date')"
/>
<span
class="title is-6"
v-text="$filters.date(item.date_released)"
/>
</p> </p>
<p v-else-if="item.year"> <p v-else-if="item.year">
<span class="heading" v-text="$t('dialog.album.year')" /> <span class="heading" v-text="$t('dialog.album.year')" />
@ -78,8 +68,8 @@
/> />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.add')" /> <span class="is-size-7" v-text="$t('dialog.album.add')" />
@ -92,25 +82,18 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.album.play')" /> <span class="is-size-7" v-text="$t('dialog.album.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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 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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<cover-artwork <cover-artwork
:url="artwork_url(item)" :url="artwork_url(item)"
:artist="item.artist" :artist="item.artist"
@ -33,58 +29,39 @@
class="heading" class="heading"
v-text="$t('dialog.spotify.album.release-date')" v-text="$t('dialog.spotify.album.release-date')"
/> />
<span <span class="title is-6" v-text="$filters.date(item.release_date)" />
class="title is-6"
v-text="$filters.date(item.release_date)"
/>
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.album.type')" />
class="heading"
v-text="$t('dialog.spotify.album.type')"
/>
<span class="title is-6" v-text="item.album_type" /> <span class="title is-6" v-text="item.album_type" />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.album.add')" /> <span class="is-size-7" v-text="$t('dialog.spotify.album.add')" />
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" /> <mdicon class="icon" name="playlist-play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.album.add-next')" />
class="is-size-7"
v-text="$t('dialog.spotify.album.add-next')"
/>
</a> </a>
<a class="card-footer-item has-text-dark" @click="play"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.album.play')" />
class="is-size-7"
v-text="$t('dialog.spotify.album.play')"
/>
</a> </a>
</footer> </template>
</div> </base-modal>
</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 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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4"> <p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" /> <a class="has-text-link" @click="open" v-text="item.name" />
</p> </p>
@ -19,10 +15,7 @@
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.artist.type')" /> <span class="heading" v-text="$t('dialog.artist.type')" />
<span <span class="title is-6" v-text="$t(`data.kind.${item.data_kind}`)" />
class="title is-6"
v-text="$t(`data.kind.${item.data_kind}`)"
/>
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.artist.added-on')" /> <span class="heading" v-text="$t('dialog.artist.added-on')" />
@ -32,8 +25,8 @@
/> />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.add')" /> <span class="is-size-7" v-text="$t('dialog.artist.add')" />
@ -46,23 +39,17 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.artist.play')" /> <span class="is-size-7" v-text="$t('dialog.artist.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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: '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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4"> <p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" /> <a class="has-text-link" @click="open" v-text="item.name" />
</p> </p>
@ -20,53 +16,35 @@
/> />
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.artist.genres')" />
class="heading"
v-text="$t('dialog.spotify.artist.genres')"
/>
<span class="title is-6" v-text="item.genres.join(', ')" /> <span class="title is-6" v-text="item.genres.join(', ')" />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.artist.add')" />
class="is-size-7"
v-text="$t('dialog.spotify.artist.add')"
/>
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" /> <mdicon class="icon" name="playlist-play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.artist.add-next')" />
class="is-size-7"
v-text="$t('dialog.spotify.artist.add-next')"
/>
</a> </a>
<a class="card-footer-item has-text-dark" @click="play"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.artist.play')" />
class="is-size-7"
v-text="$t('dialog.spotify.artist.play')"
/>
</a> </a>
</footer> </template>
</div> </base-modal>
</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: '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,16 +1,8 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4"> <p class="title is-4">
<a <a class="has-text-link" @click="open_albums" v-text="item.name" />
class="has-text-link"
@click="open_albums"
v-text="item.name"
/>
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.composer.albums')" /> <span class="heading" v-text="$t('dialog.composer.albums')" />
@ -35,8 +27,8 @@
v-text="$filters.durationInHours(item.length_ms)" v-text="$filters.durationInHours(item.length_ms)"
/> />
</p> </p>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.composer.add')" /> <span class="is-size-7" v-text="$t('dialog.composer.add')" />
@ -49,23 +41,17 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.composer.play')" /> <span class="is-size-7" v-text="$t('dialog.composer.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4" v-text="item" /> <p class="title is-4" v-text="item" />
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.directory.add')" /> <span class="is-size-7" v-text="$t('dialog.directory.add')" />
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" /> <mdicon class="icon" name="playlist-play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.directory.add-next')" />
class="is-size-7"
v-text="$t('dialog.directory.add-next')"
/>
</a> </a>
<a class="card-footer-item has-text-dark" @click="play"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.directory.play')" /> <span class="is-size-7" v-text="$t('dialog.directory.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4"> <p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" /> <a class="has-text-link" @click="open" v-text="item.name" />
</p> </p>
@ -25,8 +21,8 @@
/> />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.add')" /> <span class="is-size-7" v-text="$t('dialog.genre.add')" />
@ -39,23 +35,17 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.genre.play')" /> <span class="is-size-7" v-text="$t('dialog.genre.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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: '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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4"> <p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" /> <a class="has-text-link" @click="open" v-text="item.name" />
</p> </p>
@ -15,18 +11,15 @@
</p> </p>
<p> <p>
<span class="heading" v-text="$t('dialog.playlist.type')" /> <span class="heading" v-text="$t('dialog.playlist.type')" />
<span <span class="title is-6" v-text="$t(`playlist.type.${item.type}`)" />
class="title is-6"
v-text="$t(`playlist.type.${item.type}`)"
/>
</p> </p>
<p v-if="!item.folder"> <p v-if="!item.folder">
<span class="heading" v-text="$t('dialog.playlist.tracks')" /> <span class="heading" v-text="$t('dialog.playlist.tracks')" />
<span class="title is-6" v-text="item.item_count" /> <span class="title is-6" v-text="item.item_count" />
</p> </p>
</div> </div>
</div> </template>
<footer v-if="!item.folder" class="card-footer"> <template v-if="!item.folder" #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.add')" /> <span class="is-size-7" v-text="$t('dialog.playlist.add')" />
@ -39,23 +32,17 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.playlist.play')" /> <span class="is-size-7" v-text="$t('dialog.playlist.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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: 'ModalDialogPlaylist', name: 'ModalDialogPlaylist',
components: { BaseModal },
props: { props: {
item: { required: true, type: Object }, item: { required: true, type: Object },
show: Boolean, show: Boolean,

View File

@ -1,10 +1,7 @@
<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">
<form class="card" @submit.prevent="save">
<div class="card-content">
<p class="title is-4" v-text="$t('dialog.playlist.save.title')" /> <p class="title is-4" v-text="$t('dialog.playlist.save.title')" />
<div class="field"> <div class="field">
<p class="control has-icons-left"> <p class="control has-icons-left">
@ -22,23 +19,18 @@
<mdicon class="icon is-left" name="file-music" size="16" /> <mdicon class="icon is-left" name="file-music" size="16" />
</p> </p>
</div> </div>
</div> </form>
<footer v-if="loading" class="card-footer"> </template>
<template v-if="loading" #footer>
<a class="card-footer-item has-text-dark"> <a class="card-footer-item has-text-dark">
<mdicon class="icon" name="web" size="16" /> <mdicon class="icon" name="web" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.playlist.save.saving')" />
class="is-size-7"
v-text="$t('dialog.playlist.save.saving')"
/>
</a> </a>
</footer> </template>
<footer v-else class="card-footer is-clipped"> <template v-else #footer>
<a class="card-footer-item has-text-danger" @click="$emit('close')"> <a class="card-footer-item has-text-danger" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" /> <mdicon class="icon" name="cancel" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.playlist.save.cancel')" />
class="is-size-7"
v-text="$t('dialog.playlist.save.cancel')"
/>
</a> </a>
<a <a
:class="{ 'is-disabled': disabled }" :class="{ 'is-disabled': disabled }"
@ -46,28 +38,19 @@
@click="save" @click="save"
> >
<mdicon class="icon" name="content-save" size="16" /> <mdicon class="icon" name="content-save" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.playlist.save.save')" />
class="is-size-7"
v-text="$t('dialog.playlist.save.save')"
/>
</a> </a>
</footer> </template>
</form> </base-modal>
</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,44 +1,28 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4"> <p class="title is-4">
<a class="has-text-link" @click="open" v-text="item.name" /> <a class="has-text-link" @click="open" v-text="item.name" />
</p> </p>
<div class="content is-small"> <div class="content is-small">
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.playlist.owner')" />
class="heading"
v-text="$t('dialog.spotify.playlist.owner')"
/>
<span class="title is-6" v-text="item.owner.display_name" /> <span class="title is-6" v-text="item.owner.display_name" />
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.playlist.tracks')" />
class="heading"
v-text="$t('dialog.spotify.playlist.tracks')"
/>
<span class="title is-6" v-text="item.tracks.total" /> <span class="title is-6" v-text="item.tracks.total" />
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.playlist.path')" />
class="heading"
v-text="$t('dialog.spotify.playlist.path')"
/>
<span class="title is-6" v-text="item.uri" /> <span class="title is-6" v-text="item.uri" />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.playlist.add')" />
class="is-size-7"
v-text="$t('dialog.spotify.playlist.add')"
/>
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" /> <mdicon class="icon" name="playlist-play" size="16" />
@ -49,28 +33,19 @@
</a> </a>
<a class="card-footer-item has-text-dark" @click="play"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.playlist.play')" />
class="is-size-7"
v-text="$t('dialog.spotify.playlist.play')"
/>
</a> </a>
</footer> </template>
</div> </base-modal>
</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: '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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4" v-text="item.title" /> <p class="title is-4" v-text="item.title" />
<p class="subtitle" v-text="item.artist" /> <p class="subtitle" v-text="item.artist" />
<div class="content is-small"> <div class="content is-small">
@ -17,10 +13,7 @@
/> />
</p> </p>
<p v-if="item.album_artist"> <p v-if="item.album_artist">
<span <span class="heading" v-text="$t('dialog.queue-item.album-artist')" />
class="heading"
v-text="$t('dialog.queue-item.album-artist')"
/>
<a <a
class="title is-6 has-text-link" class="title is-6 has-text-link"
@click="open_album_artist" @click="open_album_artist"
@ -28,10 +21,7 @@
/> />
</p> </p>
<p v-if="item.composer"> <p v-if="item.composer">
<span <span class="heading" v-text="$t('dialog.queue-item.composer')" />
class="heading"
v-text="$t('dialog.queue-item.composer')"
/>
<span class="title is-6" v-text="item.composer" /> <span class="title is-6" v-text="item.composer" />
</p> </p>
<p v-if="item.year"> <p v-if="item.year">
@ -47,20 +37,14 @@
/> />
</p> </p>
<p v-if="item.disc_number"> <p v-if="item.disc_number">
<span <span class="heading" v-text="$t('dialog.queue-item.position')" />
class="heading"
v-text="$t('dialog.queue-item.position')"
/>
<span <span
class="title is-6" class="title is-6"
v-text="[item.disc_number, item.track_number].join(' / ')" v-text="[item.disc_number, item.track_number].join(' / ')"
/> />
</p> </p>
<p v-if="item.length_ms"> <p v-if="item.length_ms">
<span <span class="heading" v-text="$t('dialog.queue-item.duration')" />
class="heading"
v-text="$t('dialog.queue-item.duration')"
/>
<span <span
class="title is-6" class="title is-6"
v-text="$filters.durationInHours(item.length_ms)" v-text="$filters.durationInHours(item.length_ms)"
@ -81,10 +65,7 @@
</span> </span>
</p> </p>
<p v-if="item.samplerate"> <p v-if="item.samplerate">
<span <span class="heading" v-text="$t('dialog.queue-item.quality')" />
class="heading"
v-text="$t('dialog.queue-item.quality')"
/>
<span class="title is-6"> <span class="title is-6">
<span v-text="item.type" /> <span v-text="item.type" />
<span <span
@ -105,15 +86,13 @@
/> />
<span <span
v-if="item.bitrate" v-if="item.bitrate"
v-text=" v-text="$t('dialog.queue-item.bitrate', { rate: item.bitrate })"
$t('dialog.queue-item.bitrate', { rate: item.bitrate })
"
/> />
</span> </span>
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="remove"> <a class="card-footer-item has-text-dark" @click="remove">
<mdicon class="icon" name="delete" size="16" /> <mdicon class="icon" name="delete" size="16" />
<span class="is-size-7" v-text="$t('dialog.queue-item.remove')" /> <span class="is-size-7" v-text="$t('dialog.queue-item.remove')" />
@ -122,25 +101,19 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.queue-item.play')" /> <span class="is-size-7" v-text="$t('dialog.queue-item.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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 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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4" v-text="$t('dialog.remote-pairing.title')" /> <p class="title is-4" v-text="$t('dialog.remote-pairing.title')" />
<form @submit.prevent="kickoff_pairing"> <form @submit.prevent="kickoff_pairing">
<label class="label" v-text="pairing.remote" /> <label class="label" v-text="pairing.remote" />
@ -21,43 +17,31 @@
</div> </div>
</div> </div>
</form> </form>
</div> </template>
<footer class="card-footer is-clipped"> <template #footer>
<a class="card-footer-item has-text-danger" @click="$emit('close')"> <a class="card-footer-item has-text-danger" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" /> <mdicon class="icon" name="cancel" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.remote-pairing.cancel')" />
class="is-size-7"
v-text="$t('dialog.remote-pairing.cancel')"
/>
</a> </a>
<a <a
class="card-footer-item has-background-info has-text-white has-text-weight-bold" class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="kickoff_pairing" @click="kickoff_pairing"
> >
<mdicon class="icon" name="cellphone" size="16" /> <mdicon class="icon" name="cellphone" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.remote-pairing.pair')" />
class="is-size-7"
v-text="$t('dialog.remote-pairing.pair')"
/>
</a> </a>
</footer> </template>
</div> </base-modal>
</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 { 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,10 +1,6 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4" v-text="item.title" /> <p class="title is-4" v-text="item.title" />
<p class="subtitle" v-text="item.artist" /> <p class="subtitle" v-text="item.artist" />
<div v-if="item.media_kind === 'podcast'" class="buttons"> <div v-if="item.media_kind === 'podcast'" class="buttons">
@ -31,10 +27,7 @@
/> />
</p> </p>
<p v-if="item.album_artist && item.media_kind !== 'audiobook'"> <p v-if="item.album_artist && item.media_kind !== 'audiobook'">
<span <span class="heading" v-text="$t('dialog.track.album-artist')" />
class="heading"
v-text="$t('dialog.track.album-artist')"
/>
<a <a
class="title is-6 has-text-link" class="title is-6 has-text-link"
@click="open_album_artist" @click="open_album_artist"
@ -46,14 +39,8 @@
<span class="title is-6" v-text="item.composer" /> <span class="title is-6" v-text="item.composer" />
</p> </p>
<p v-if="item.date_released"> <p v-if="item.date_released">
<span <span class="heading" v-text="$t('dialog.track.release-date')" />
class="heading" <span class="title is-6" v-text="$filters.date(item.date_released)" />
v-text="$t('dialog.track.release-date')"
/>
<span
class="title is-6"
v-text="$filters.date(item.date_released)"
/>
</p> </p>
<p v-else-if="item.year"> <p v-else-if="item.year">
<span class="heading" v-text="$t('dialog.track.year')" /> <span class="heading" v-text="$t('dialog.track.year')" />
@ -143,8 +130,8 @@
<span class="title is-6" v-text="item.comment" /> <span class="title is-6" v-text="item.comment" />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.add')" /> <span class="is-size-7" v-text="$t('dialog.track.add')" />
@ -157,25 +144,19 @@
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span class="is-size-7" v-text="$t('dialog.track.play')" /> <span class="is-size-7" v-text="$t('dialog.track.play')" />
</a> </a>
</footer> </template>
</div> </base-modal>
</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 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,18 +1,11 @@
<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')" />
<div class="modal-content">
<div class="card">
<div class="card-content">
<p class="title is-4" v-text="item.name" /> <p class="title is-4" v-text="item.name" />
<p class="subtitle" v-text="item.artists[0].name" /> <p class="subtitle" v-text="item.artists[0].name" />
<div class="content is-small"> <div class="content is-small">
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.track.album')" />
class="heading"
v-text="$t('dialog.spotify.track.album')"
/>
<a <a
class="title is-6 has-text-link" class="title is-6 has-text-link"
@click="open_album" @click="open_album"
@ -41,70 +34,49 @@
/> />
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.track.position')" />
class="heading"
v-text="$t('dialog.spotify.track.position')"
/>
<span <span
class="title is-6" class="title is-6"
v-text="[item.disc_number, item.track_number].join(' / ')" 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"
v-text="$t('dialog.spotify.track.duration')"
/>
<span <span
class="title is-6" class="title is-6"
v-text="$filters.durationInHours(item.duration_ms)" v-text="$filters.durationInHours(item.duration_ms)"
/> />
</p> </p>
<p> <p>
<span <span class="heading" v-text="$t('dialog.spotify.track.path')" />
class="heading"
v-text="$t('dialog.spotify.track.path')"
/>
<span class="title is-6" v-text="item.uri" /> <span class="title is-6" v-text="item.uri" />
</p> </p>
</div> </div>
</div> </template>
<footer class="card-footer"> <template #footer>
<a class="card-footer-item has-text-dark" @click="queue_add"> <a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" /> <mdicon class="icon" name="playlist-plus" size="16" />
<span class="is-size-7" v-text="$t('dialog.spotify.track.add')" /> <span class="is-size-7" v-text="$t('dialog.spotify.track.add')" />
</a> </a>
<a class="card-footer-item has-text-dark" @click="queue_add_next"> <a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" /> <mdicon class="icon" name="playlist-play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.track.add-next')" />
class="is-size-7"
v-text="$t('dialog.spotify.track.add-next')"
/>
</a> </a>
<a class="card-footer-item has-text-dark" @click="play"> <a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" /> <mdicon class="icon" name="play" size="16" />
<span <span class="is-size-7" v-text="$t('dialog.spotify.track.play')" />
class="is-size-7"
v-text="$t('dialog.spotify.track.play')"
/>
</a> </a>
</footer> </template>
</div> </base-modal>
</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: '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'],