[web] Simplify pages

This commit is contained in:
Alain Nussbaumer 2025-03-18 21:54:27 +01:00
parent 15e8854349
commit be44c0ce9f
38 changed files with 1353 additions and 1457 deletions

View File

@ -20,22 +20,14 @@
<slot name="actions" />
</div>
</div>
<template v-for="item in items" :key="item.path">
<div
class="media is-align-items-center is-clickable mb-0"
@click="open(item)"
>
<mdicon class="media-left icon" name="folder" />
<div class="media-content">
<div class="is-size-6 has-text-weight-bold" v-text="item.name" />
</div>
<div class="media-right">
<a @click.prevent.stop="openDetails(item)">
<mdicon class="icon has-text-grey" name="dots-vertical" size="16" />
</a>
</div>
</div>
</template>
<list-item
v-for="item in items"
:key="item.path"
icon="folder"
:lines="[item.name]"
@open="open(item)"
@open-details="openDetails(item)"
/>
<modal-dialog-directory
:item="selectedItem"
:show="showDetailsModal"
@ -44,17 +36,16 @@
</template>
<script>
import ListItem from '@/components/ListItem.vue'
import ModalDialogDirectory from '@/components/ModalDialogDirectory.vue'
export default {
name: 'ListDirectories',
components: { ModalDialogDirectory },
components: { ListItem, ModalDialogDirectory },
props: { items: { required: true, type: Array } },
data() {
return { selectedItem: '', showDetailsModal: false }
},
computed: {
directories() {
const directories = []
@ -69,7 +60,6 @@ export default {
return directories
}
},
methods: {
open(item) {
const route = { name: 'files' }

View File

@ -1,85 +1,83 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="{ title: $t('page.about.library') }" />
</template>
<template #actions>
<control-button
:button="{
handler: openUpdateDialog,
icon: 'refresh',
key: 'page.about.update'
}"
:class="{ 'is-loading': libraryStore.updating }"
:disabled="libraryStore.updating"
/>
</template>
<template #content>
<content-with-heading>
<template #heading>
<heading-title :content="{ title: $t('page.about.library') }" />
</template>
<template #actions>
<control-button
:button="{
handler: openUpdateDialog,
icon: 'refresh',
key: 'page.about.update'
}"
:class="{ 'is-loading': libraryStore.updating }"
:disabled="libraryStore.updating"
/>
</template>
<template #content>
<div
v-for="property in properties"
:key="property.key"
class="media is-align-items-center mb-0"
>
<div
v-for="property in properties"
:key="property.key"
class="media is-align-items-center mb-0"
>
<div
class="media-content has-text-weight-bold"
v-text="$t(property.key)"
class="media-content has-text-weight-bold"
v-text="$t(property.key)"
/>
<div class="media-right">
<span v-text="property.value" />
<span
v-if="property.alternate"
class="has-text-grey"
v-text="` (${property.alternate})`"
/>
<div class="media-right">
<span v-text="property.value" />
<span
v-if="property.alternate"
class="has-text-grey"
v-text="` (${property.alternate})`"
/>
</div>
</div>
<div
class="is-size-7 mt-6"
v-text="
$t('page.about.version', {
version: configurationStore.version
})
"
/>
<div
class="is-size-7"
v-text="
$t('page.about.compiled-with', {
options: configurationStore.buildoptions.join(', ')
})
"
/>
<i18n-t
tag="div"
class="is-size-7"
keypath="page.about.built-with"
scope="global"
>
<template #bulma>
<a href="https://bulma.io">Bulma</a>
</template>
<template #mdi>
<a href="https://pictogrammers.com/library/mdi/">
Material Design Icons
</a>
</template>
<template #vuejs>
<a href="https://vuejs.org/">Vue.js</a>
</template>
<template #axios>
<a href="https://github.com/axios/axios">axios</a>
</template>
<template #others>
<a
href="https://github.com/owntone/owntone-server/network/dependencies"
v-text="$t('page.about.more')"
/>
</template>
</i18n-t>
</template>
</content-with-heading>
</div>
</div>
<div
class="is-size-7 mt-6"
v-text="
$t('page.about.version', {
version: configurationStore.version
})
"
/>
<div
class="is-size-7"
v-text="
$t('page.about.compiled-with', {
options: configurationStore.buildoptions.join(', ')
})
"
/>
<i18n-t
tag="div"
class="is-size-7"
keypath="page.about.built-with"
scope="global"
>
<template #bulma>
<a href="https://bulma.io">Bulma</a>
</template>
<template #mdi>
<a href="https://pictogrammers.com/library/mdi/">
Material Design Icons
</a>
</template>
<template #vuejs>
<a href="https://vuejs.org/">Vue.js</a>
</template>
<template #axios>
<a href="https://github.com/axios/axios">axios</a>
</template>
<template #others>
<a
href="https://github.com/owntone/owntone-server/network/dependencies"
v-text="$t('page.about.more')"
/>
</template>
</i18n-t>
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,27 +1,25 @@
<template>
<div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.artwork_url"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks :items="tracks" :uris="album.uri" />
<modal-dialog-album
:item="album"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-hero>
</div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.artwork_url"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks :items="tracks" :uris="album.uri" />
</template>
</content-with-hero>
<modal-dialog-album
:item="album"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,27 +1,25 @@
<template>
<div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.images?.[0]?.url ?? ''"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks-spotify :items="tracks" :context_uri="album.uri" />
<modal-dialog-album-spotify
:item="album"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-hero>
</div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.images?.[0]?.url ?? ''"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks-spotify :items="tracks" :context_uri="album.uri" />
</template>
</content-with-hero>
<modal-dialog-album-spotify
:item="album"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,47 +1,45 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="albums.indices" />
<list-options>
<template #filter>
<control-switch v-model="uiStore.hideSingles">
<template #label>
<span v-text="$t('options.filter.hide-singles')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-singles-help')" />
</template>
</control-switch>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.albumsSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="albums.indices" />
<list-options>
<template #filter>
<control-switch v-model="uiStore.hideSingles">
<template #label>
<span v-text="$t('options.filter.hide-singles')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-singles-help')" />
</template>
</control-switch>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.albumsSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,50 +1,48 @@
<template>
<div>
<content-with-heading>
<template #options>
<list-options>
<template #filter>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('page.artist.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('page.artist.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.artistAlbumsSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
<modal-dialog-artist
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #options>
<list-options>
<template #filter>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('page.artist.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('page.artist.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.artistAlbumsSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
<modal-dialog-artist
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,42 +1,40 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums-spotify :items="albums" />
<vue-eternal-loading v-if="offset < total" :load="loadNext">
<template #loading>
<div class="columns is-centered">
<div class="column has-text-centered">
<mdicon class="icon mdi-spin" name="loading" />
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums-spotify :items="albums" />
<vue-eternal-loading v-if="offset < total" :load="loadNext">
<template #loading>
<div class="columns is-centered">
<div class="column has-text-centered">
<mdicon class="icon mdi-spin" name="loading" />
</div>
</template>
<template #no-more>
<br />
</template>
<template #no-results>
<br />
</template>
</vue-eternal-loading>
<modal-dialog-artist-spotify
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
</div>
</template>
<template #no-more>
<br />
</template>
<template #no-results>
<br />
</template>
</vue-eternal-loading>
</template>
</content-with-heading>
<modal-dialog-artist-spotify
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,51 +1,49 @@
<template>
<div>
<content-with-heading>
<template #options>
<index-button-list :indices="tracks.indices" />
<list-options>
<template #filter>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.artistTracksSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-tracks :items="tracks" :uris="trackUris" />
<modal-dialog-artist
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #options>
<index-button-list :indices="tracks.indices" />
<list-options>
<template #filter>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.artistTracksSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-tracks :items="tracks" :uris="trackUris" />
</template>
</content-with-heading>
<modal-dialog-artist
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,47 +1,45 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="artists.indices" />
<list-options>
<template #filter>
<control-switch v-model="uiStore.hideSingles">
<template #label>
<span v-text="$t('options.filter.hide-singles')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-singles-help')" />
</template>
</control-switch>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.artistsSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-artists :items="artists" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="artists.indices" />
<list-options>
<template #filter>
<control-switch v-model="uiStore.hideSingles">
<template #label>
<span v-text="$t('options.filter.hide-singles')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-singles-help')" />
</template>
</control-switch>
<control-switch
v-if="servicesStore.isSpotifyActive"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
<template #help>
<span v-text="$t('options.filter.hide-spotify-help')" />
</template>
</control-switch>
</template>
<template #sort>
<control-dropdown
v-model:value="uiStore.artistsSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-artists :items="artists" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,28 +1,26 @@
<template>
<div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.artwork_url"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks :items="tracks" :show-progress="true" :uris="album.uri" />
<modal-dialog-album
:item="album"
:show="showDetailsModal"
:media_kind="'audiobook'"
@close="showDetailsModal = false"
/>
</template>
</content-with-hero>
</div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.artwork_url"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks :items="tracks" :show-progress="true" :uris="album.uri" />
</template>
</content-with-hero>
<modal-dialog-album
:item="album"
:show="showDetailsModal"
:media_kind="'audiobook'"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,18 +1,16 @@
<template>
<div>
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :indices="albums.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
</div>
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :indices="albums.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,27 +1,25 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'play', key: 'actions.play' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
<modal-dialog-artist
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'play', key: 'actions.play' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
<modal-dialog-artist
:item="artist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,18 +1,16 @@
<template>
<div>
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :indices="artists.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-artists :items="artists" />
</template>
</content-with-heading>
</div>
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :indices="artists.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-artists :items="artists" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,18 +1,16 @@
<template>
<div>
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :indices="genres.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-genres :items="genres" :media_kind="'audiobook'" />
</template>
</content-with-heading>
</div>
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :indices="genres.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-genres :items="genres" :media_kind="'audiobook'" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,27 +1,25 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
<modal-dialog-composer
:item="composer"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
<modal-dialog-composer
:item="composer"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,38 +1,36 @@
<template>
<div>
<content-with-heading>
<template #options>
<index-button-list :indices="tracks.indices" />
<list-options>
<template #sort>
<control-dropdown
v-model:value="uiStore.composerTracksSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-tracks :items="tracks" :expression="expression" />
<modal-dialog-composer
:item="composer"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #options>
<index-button-list :indices="tracks.indices" />
<list-options>
<template #sort>
<control-dropdown
v-model:value="uiStore.composerTracksSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-tracks :items="tracks" :expression="expression" />
</template>
</content-with-heading>
<modal-dialog-composer
:item="composer"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,18 +1,16 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="composers.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-composers :items="composers" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="composers.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-composers :items="composers" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,28 +1,22 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="{ title: name }" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'play', key: 'actions.play' }"
/>
</template>
<template #content>
<list-directories :items="directories" />
<list-playlists :items="playlists" />
<list-tracks
:expression="expression"
:items="tracks"
icon="file-music-outline"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="{ title: name }" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'play', key: 'actions.play' }"
/>
</template>
<template #content>
<list-directories :items="directories" />
<list-playlists :items="playlists" />
<list-tracks :items="tracks" icon="file-music-outline" />
</template>
</content-with-heading>
<modal-dialog-playable
:item="playable"
:show="showDetailsModal"
@ -109,9 +103,6 @@ export default {
current() {
return this.$route.query?.directory || '/'
},
expression() {
return `path starts with "${this.current}" order by path asc`
},
name() {
if (this.current !== '/') {
return this.current?.slice(this.current.lastIndexOf('/') + 1)

View File

@ -1,31 +1,29 @@
<template>
<div>
<content-with-heading>
<template #options>
<index-button-list :indices="albums.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
<modal-dialog-genre
:item="genre"
:media_kind="media_kind"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #options>
<index-button-list :indices="albums.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
<modal-dialog-genre
:item="genre"
:media_kind="media_kind"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,39 +1,37 @@
<template>
<div>
<content-with-heading>
<template #options>
<index-button-list :indices="tracks.indices" />
<list-options>
<template #sort>
<control-dropdown
v-model:value="uiStore.genreTracksSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-tracks :items="tracks" :expression="expression" />
<modal-dialog-genre
:item="genre"
:media_kind="media_kind"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #options>
<index-button-list :indices="tracks.indices" />
<list-options>
<template #sort>
<control-dropdown
v-model:value="uiStore.genreTracksSort"
:options="groupings"
/>
</template>
</list-options>
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
</template>
<template #content>
<list-tracks :items="tracks" :expression="expression" />
</template>
</content-with-heading>
<modal-dialog-genre
:item="genre"
:media_kind="media_kind"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,18 +1,16 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="genres.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-genres :items="genres" :media_kind="'music'" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #options>
<index-button-list :indices="genres.indices" />
</template>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-genres :items="genres" :media_kind="'music'" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,43 +1,41 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-added.title') }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
<template #footer>
<router-link
class="button is-small is-rounded"
:to="{ name: 'music-recently-added' }"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-played.title') }"
/>
</template>
<template #content>
<list-tracks :items="tracks" />
</template>
<template #footer>
<router-link
class="button is-small is-rounded"
:to="{ name: 'music-recently-played' }"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-added.title') }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
<template #footer>
<router-link
class="button is-small is-rounded"
:to="{ name: 'music-recently-added' }"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-played.title') }"
/>
</template>
<template #content>
<list-tracks :items="tracks" />
</template>
<template #footer>
<router-link
class="button is-small is-rounded"
:to="{ name: 'music-recently-played' }"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,17 +1,15 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-added.title') }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-added.title') }"
/>
</template>
<template #content>
<list-albums :items="albums" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,17 +1,15 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-played.title') }"
/>
</template>
<template #content>
<list-tracks :items="tracks" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.music.recently-played.title') }"
/>
</template>
<template #content>
<list-tracks :items="tracks" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,43 +1,41 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.spotify.music.new-releases') }"
/>
</template>
<template #content>
<list-albums-spotify :items="albums" />
</template>
<template #footer>
<router-link
:to="{ name: 'music-spotify-new-releases' }"
class="button is-small is-rounded"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.spotify.music.featured-playlists') }"
/>
</template>
<template #content>
<list-playlists-spotify :items="playlists" />
</template>
<template #footer>
<router-link
:to="{ name: 'music-spotify-featured-playlists' }"
class="button is-small is-rounded"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.spotify.music.new-releases') }"
/>
</template>
<template #content>
<list-albums-spotify :items="albums" />
</template>
<template #footer>
<router-link
:to="{ name: 'music-spotify-new-releases' }"
class="button is-small is-rounded"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.spotify.music.featured-playlists') }"
/>
</template>
<template #content>
<list-playlists-spotify :items="playlists" />
</template>
<template #footer>
<router-link
:to="{ name: 'music-spotify-featured-playlists' }"
class="button is-small is-rounded"
>
{{ $t('actions.show-more') }}
</router-link>
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,15 +1,13 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-playlists-spotify :items="playlists" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-playlists-spotify :items="playlists" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,15 +1,13 @@
<template>
<div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-albums-spotify :items="albums" />
</template>
</content-with-heading>
</div>
<tabs-music />
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-albums-spotify :items="albums" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,14 +1,12 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-playlists :items="playlists" />
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-playlists :items="playlists" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,33 +1,31 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{
handler: play,
icon: 'shuffle',
key: 'actions.shuffle'
}"
:disabled="tracks.count === 0"
/>
</template>
<template #content>
<list-tracks :items="tracks" :uris="uris" />
<modal-dialog-playlist
:item="playlist"
:show="showDetailsModal"
:uris="uris"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{
handler: play,
icon: 'shuffle',
key: 'actions.shuffle'
}"
:disabled="tracks.count === 0"
/>
</template>
<template #content>
<list-tracks :items="tracks" :uris="uris" />
</template>
</content-with-heading>
<modal-dialog-playlist
:item="playlist"
:show="showDetailsModal"
:uris="uris"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,44 +1,42 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{
handler: play,
icon: 'shuffle',
key: 'actions.shuffle'
}"
:disabled="playlist.tracks.total === 0"
/>
</template>
<template #content>
<list-tracks-spotify :items="tracks" :context_uri="playlist.uri" />
<vue-eternal-loading v-if="offset < total" :load="load">
<template #loading>
<div class="columns is-centered">
<div class="column has-text-centered">
<mdicon class="icon mdi-spin" name="loading" />
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
<control-button
:button="{
handler: play,
icon: 'shuffle',
key: 'actions.shuffle'
}"
:disabled="playlist.tracks.total === 0"
/>
</template>
<template #content>
<list-tracks-spotify :items="tracks" :context_uri="playlist.uri" />
<vue-eternal-loading v-if="offset < total" :load="load">
<template #loading>
<div class="columns is-centered">
<div class="column has-text-centered">
<mdicon class="icon mdi-spin" name="loading" />
</div>
</template>
<template #no-more>
<br />
</template>
</vue-eternal-loading>
<modal-dialog-playlist-spotify
:item="playlist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
</div>
</div>
</template>
<template #no-more>
<br />
</template>
</vue-eternal-loading>
</template>
</content-with-heading>
<modal-dialog-playlist-spotify
:item="playlist"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
<script>

View File

@ -1,52 +1,50 @@
<template>
<div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.artwork_url"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks
:items="tracks"
:show-progress="true"
@play-count-changed="reloadTracks"
/>
<modal-dialog-album
:item="album"
:show="showDetailsModal"
:media_kind="'podcast'"
@close="showDetailsModal = false"
@play-count-changed="reloadTracks"
@remove-podcast="openRemovePodcastDialog"
/>
<modal-dialog
:actions="actions"
:show="showRemovePodcastModal"
:title="$t('page.podcast.remove-podcast')"
@cancel="showRemovePodcastModal = false"
@remove="removePodcast"
>
<template #content>
<i18n-t keypath="page.podcast.remove-info" tag="p" scope="global">
<template #separator>
<br />
</template>
<template #name>
<b v-text="playlistToRemove.name" />
</template>
</i18n-t>
</template>
</modal-dialog>
</template>
</content-with-hero>
</div>
<content-with-hero>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #image>
<control-image
:url="album.artwork_url"
:caption="album.name"
class="is-clickable is-medium"
@click="openDetails"
/>
</template>
<template #content>
<list-tracks
:items="tracks"
:show-progress="true"
@play-count-changed="reloadTracks"
/>
<modal-dialog-album
:item="album"
:show="showDetailsModal"
:media_kind="'podcast'"
@close="showDetailsModal = false"
@play-count-changed="reloadTracks"
@remove-podcast="openRemovePodcastDialog"
/>
<modal-dialog
:actions="actions"
:show="showRemovePodcastModal"
:title="$t('page.podcast.remove-podcast')"
@cancel="showRemovePodcastModal = false"
@remove="removePodcast"
>
<template #content>
<i18n-t keypath="page.podcast.remove-info" tag="p" scope="global">
<template #separator>
<br />
</template>
<template #name>
<b v-text="playlistToRemove.name" />
</template>
</i18n-t>
</template>
</modal-dialog>
</template>
</content-with-hero>
</template>
<script>

View File

@ -1,61 +1,59 @@
<template>
<div>
<content-with-heading v-if="tracks.items.length > 0">
<template #heading>
<heading-title :content="{ title: $t('page.podcasts.new-episodes') }" />
</template>
<template #actions>
<control-button
:button="{
handler: markAllAsPlayed,
icon: 'pencil',
key: 'actions.mark-all-played'
}"
/>
</template>
<template #content>
<list-tracks
:items="tracks"
:show-progress="true"
@play-count-changed="reloadNewEpisodes"
/>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
v-if="rss.tracks > 0"
:button="{
handler: updateRss,
icon: 'refresh',
key: 'actions.update'
}"
/>
<control-button
:button="{
handler: openAddPodcastDialog,
icon: 'rss',
key: 'actions.add'
}"
/>
</template>
<template #content>
<list-albums
:items="albums"
@play-count-changed="reloadNewEpisodes()"
@podcast-deleted="reloadPodcasts()"
/>
<modal-dialog-add-rss
:show="showAddPodcastModal"
@close="showAddPodcastModal = false"
@podcast-added="reloadPodcasts()"
/>
</template>
</content-with-heading>
</div>
<content-with-heading v-if="tracks.items.length > 0">
<template #heading>
<heading-title :content="{ title: $t('page.podcasts.new-episodes') }" />
</template>
<template #actions>
<control-button
:button="{
handler: markAllAsPlayed,
icon: 'pencil',
key: 'actions.mark-all-played'
}"
/>
</template>
<template #content>
<list-tracks
:items="tracks"
:show-progress="true"
@play-count-changed="reloadNewEpisodes"
/>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
v-if="rss.tracks > 0"
:button="{
handler: updateRss,
icon: 'refresh',
key: 'actions.update'
}"
/>
<control-button
:button="{
handler: openAddPodcastDialog,
icon: 'rss',
key: 'actions.add'
}"
/>
</template>
<template #content>
<list-albums
:items="albums"
@play-count-changed="reloadNewEpisodes()"
@podcast-deleted="reloadPodcasts()"
/>
</template>
</content-with-heading>
<modal-dialog-add-rss
:show="showAddPodcastModal"
@close="showAddPodcastModal = false"
@podcast-added="reloadPodcasts()"
/>
</template>
<script>

View File

@ -1,97 +1,95 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{
handler: uiStore.toggleHideReadItems,
icon: 'eye-off-outline',
key: 'actions.hide-previous'
}"
:class="{ 'is-dark': uiStore.hideReadItems }"
/>
<control-button
:button="{
handler: openAddStreamDialog,
icon: 'web',
key: 'actions.add-stream'
}"
/>
<control-button
:button="{
handler: toggleEdit,
icon: 'pencil',
key: 'actions.edit'
}"
:class="{ 'is-dark': editing }"
:disabled="queueStore.isEmpty"
/>
<control-button
:button="{
handler: clearQueue,
icon: 'delete-empty',
key: 'actions.clear'
}"
:disabled="queueStore.isEmpty"
/>
<control-button
v-if="queueStore.isSavingAllowed"
:button="{
handler: openSaveDialog,
icon: 'download',
key: 'actions.save'
}"
:disabled="queueStore.isEmpty"
/>
</template>
<template #content>
<draggable v-model="items" item-key="id" @end="moveItem">
<template #item="{ element, index }">
<list-item-queue-item
:item="element"
:position="index"
:current-position="currentPosition"
:hide-read-items="uiStore.hideReadItems"
:editing="editing"
>
<template #actions>
<a v-if="!editing" @click.prevent.stop="openDetails(element)">
<mdicon
class="icon has-text-grey"
name="dots-vertical"
size="16"
/>
</a>
<a
v-if="isRemovable(element)"
@click.prevent.stop="remove(element)"
>
<mdicon class="icon has-text-grey" name="delete" size="18" />
</a>
</template>
</list-item-queue-item>
</template>
</draggable>
<modal-dialog-queue-item
:show="showDetailsModal"
:item="selectedItem"
@close="showDetailsModal = false"
/>
<modal-dialog-add-stream
:show="showAddStreamDialog"
@close="showAddStreamDialog = false"
/>
<modal-dialog-playlist-save
v-if="queueStore.isSavingAllowed"
:show="showSaveModal"
@close="showSaveModal = false"
/>
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #actions>
<control-button
:button="{
handler: uiStore.toggleHideReadItems,
icon: 'eye-off-outline',
key: 'actions.hide-previous'
}"
:class="{ 'is-dark': uiStore.hideReadItems }"
/>
<control-button
:button="{
handler: openAddStreamDialog,
icon: 'web',
key: 'actions.add-stream'
}"
/>
<control-button
:button="{
handler: toggleEdit,
icon: 'pencil',
key: 'actions.edit'
}"
:class="{ 'is-dark': editing }"
:disabled="queueStore.isEmpty"
/>
<control-button
:button="{
handler: clearQueue,
icon: 'delete-empty',
key: 'actions.clear'
}"
:disabled="queueStore.isEmpty"
/>
<control-button
v-if="queueStore.isSavingAllowed"
:button="{
handler: openSaveDialog,
icon: 'download',
key: 'actions.save'
}"
:disabled="queueStore.isEmpty"
/>
</template>
<template #content>
<draggable v-model="items" item-key="id" @end="moveItem">
<template #item="{ element, index }">
<list-item-queue-item
:item="element"
:position="index"
:current-position="currentPosition"
:hide-read-items="uiStore.hideReadItems"
:editing="editing"
>
<template #actions>
<a v-if="!editing" @click.prevent.stop="openDetails(element)">
<mdicon
class="icon has-text-grey"
name="dots-vertical"
size="16"
/>
</a>
<a
v-if="isRemovable(element)"
@click.prevent.stop="remove(element)"
>
<mdicon class="icon has-text-grey" name="delete" size="18" />
</a>
</template>
</list-item-queue-item>
</template>
</draggable>
</template>
</content-with-heading>
<modal-dialog-queue-item
:show="showDetailsModal"
:item="selectedItem"
@close="showDetailsModal = false"
/>
<modal-dialog-add-stream
:show="showAddStreamDialog"
@close="showAddStreamDialog = false"
/>
<modal-dialog-playlist-save
v-if="queueStore.isSavingAllowed"
:show="showSaveModal"
@close="showSaveModal = false"
/>
</template>
<script>

View File

@ -1,14 +1,12 @@
<template>
<div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-tracks :items="tracks" />
</template>
</content-with-heading>
</div>
<content-with-heading>
<template #heading>
<heading-title :content="heading" />
</template>
<template #content>
<list-tracks :items="tracks" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,81 +1,71 @@
<template>
<div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.artwork.title') }"
/>
</template>
<template #content>
<div
class="content"
v-text="$t('page.settings.artwork.explanation-1')"
/>
<div class="content">
<control-setting-switch category="artwork" name="streamurl_ignore">
<template #label>
<span v-text="$t('page.settings.artwork.streaming')" />
</template>
</control-setting-switch>
<control-setting-switch
category="artwork"
name="show_cover_artwork_in_album_lists"
>
<template #label>
<span v-text="$t('page.settings.artwork.show-coverart')" />
</template>
</control-setting-switch>
</div>
<div
class="content"
v-text="$t('page.settings.artwork.explanation-2')"
/>
<div class="content">
<control-setting-switch
v-if="servicesStore.spotify_logged_in"
category="artwork"
name="use_artwork_source_spotify"
>
<template #label>
<span v-text="$t('page.settings.artwork.spotify')" />
<a href="https://www.spotify.com/" target="_blank">
<span class="icon">
<mdicon name="open-in-new" size="16" />
</span>
</a>
</template>
</control-setting-switch>
<control-setting-switch
category="artwork"
name="use_artwork_source_discogs"
>
<template #label>
<span v-text="$t('page.settings.artwork.discogs')" />
<a href="https://www.discogs.com/" target="_blank">
<span class="icon">
<mdicon name="open-in-new" size="16" />
</span>
</a>
</template>
</control-setting-switch>
<control-setting-switch
category="artwork"
name="use_artwork_source_coverartarchive"
>
<template #label>
<span v-text="$t('page.settings.artwork.coverartarchive')" />
<a href="https://coverartarchive.org/" target="_blank">
<span class="icon">
<mdicon name="open-in-new" size="16" />
</span>
</a>
</template>
</control-setting-switch>
</div>
</template>
</content-with-heading>
</div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title :content="{ title: $t('page.settings.artwork.title') }" />
</template>
<template #content>
<div class="content" v-text="$t('page.settings.artwork.explanation-1')" />
<div class="content">
<control-setting-switch category="artwork" name="streamurl_ignore">
<template #label>
<span v-text="$t('page.settings.artwork.streaming')" />
</template>
</control-setting-switch>
<control-setting-switch
category="artwork"
name="show_cover_artwork_in_album_lists"
>
<template #label>
<span v-text="$t('page.settings.artwork.show-coverart')" />
</template>
</control-setting-switch>
</div>
<div class="content" v-text="$t('page.settings.artwork.explanation-2')" />
<div class="content">
<control-setting-switch
v-if="servicesStore.spotify_logged_in"
category="artwork"
name="use_artwork_source_spotify"
>
<template #label>
<span v-text="$t('page.settings.artwork.spotify')" />
<a href="https://www.spotify.com/" target="_blank">
<span class="icon">
<mdicon name="open-in-new" size="16" />
</span>
</a>
</template>
</control-setting-switch>
<control-setting-switch
category="artwork"
name="use_artwork_source_discogs"
>
<template #label>
<span v-text="$t('page.settings.artwork.discogs')" />
<a href="https://www.discogs.com/" target="_blank">
<span class="icon">
<mdicon name="open-in-new" size="16" />
</span>
</a>
</template>
</control-setting-switch>
<control-setting-switch
category="artwork"
name="use_artwork_source_coverartarchive"
>
<template #label>
<span v-text="$t('page.settings.artwork.coverartarchive')" />
<a href="https://coverartarchive.org/" target="_blank">
<span class="icon">
<mdicon name="open-in-new" size="16" />
</span>
</a>
</template>
</control-setting-switch>
</div>
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,124 +1,119 @@
<template>
<div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.services.spotify.title') }"
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.services.spotify.title') }"
/>
</template>
<template #content>
<div v-if="servicesStore.isSpotifyEnabled">
<div v-text="$t('page.settings.services.spotify.grant-access')" />
<div
class="notification help"
v-text="
$t('page.settings.services.spotify.requirements', {
scopes: servicesStore.requiredSpotifyScopes.join(', ')
})
"
/>
</template>
<template #content>
<div v-if="servicesStore.isSpotifyEnabled">
<div v-text="$t('page.settings.services.spotify.grant-access')" />
<div v-if="servicesStore.isSpotifyActive">
<div
class="notification help"
v-text="
$t('page.settings.services.spotify.requirements', {
scopes: servicesStore.requiredSpotifyScopes.join(', ')
$t('page.settings.services.spotify.user', {
user: servicesStore.spotify.webapi_user
})
"
/>
<div v-if="servicesStore.isSpotifyActive">
<div
v-text="
$t('page.settings.services.spotify.user', {
user: servicesStore.spotify.webapi_user
})
"
/>
<div
v-if="servicesStore.hasMissingSpotifyScopes"
class="notification help is-danger is-light"
v-text="
$t('page.settings.services.spotify.reauthorize', {
scopes: servicesStore.missingSpotifyScopes.join(', ')
})
"
/>
</div>
<div class="field is-grouped mt-5">
<div v-if="servicesStore.isAuthorizationRequired" class="control">
<a
class="button"
:href="servicesStore.spotify.oauth_uri"
v-text="$t('page.settings.services.spotify.authorize')"
/>
</div>
<div v-if="servicesStore.isSpotifyActive" class="control">
<button
class="button is-danger"
@click="logoutSpotify"
v-text="$t('actions.logout')"
/>
</div>
</div>
</div>
<div v-else v-text="$t('page.settings.services.spotify.no-support')" />
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.services.lastfm.title') }"
/>
</template>
<template #content>
<div v-if="servicesStore.isLastfmEnabled">
<div v-text="$t('page.settings.services.lastfm.grant-access')" />
<div
class="notification help"
v-text="$t('page.settings.services.lastfm.info')"
v-if="servicesStore.hasMissingSpotifyScopes"
class="notification help is-danger is-light"
v-text="
$t('page.settings.services.spotify.reauthorize', {
scopes: servicesStore.missingSpotifyScopes.join(', ')
})
"
/>
<div v-if="!servicesStore.isLastfmActive">
<form @submit.prevent="loginLastfm">
<div class="field is-grouped">
<div class="control">
<input
v-model="lastfm_login.user"
class="input"
type="text"
:placeholder="$t('page.settings.services.username')"
/>
<div
class="help is-danger"
v-text="lastfm_login.errors.user"
/>
</div>
<div class="control">
<input
v-model="lastfm_login.password"
class="input"
type="password"
:placeholder="$t('page.settings.services.password')"
/>
<div
class="help is-danger"
v-text="lastfm_login.errors.password"
/>
</div>
<div class="control">
<button
class="button"
type="submit"
v-text="$t('actions.login')"
/>
</div>
</div>
<div class="help is-danger" v-text="lastfm_login.errors.error" />
</form>
</div>
<div class="field is-grouped mt-5">
<div v-if="servicesStore.isAuthorizationRequired" class="control">
<a
class="button"
:href="servicesStore.spotify.oauth_uri"
v-text="$t('page.settings.services.spotify.authorize')"
/>
</div>
<div v-else>
<div v-if="servicesStore.isSpotifyActive" class="control">
<button
class="button is-danger"
@click="logoutLastfm"
@click="logoutSpotify"
v-text="$t('actions.logout')"
/>
</div>
</div>
<div v-else v-text="$t('page.settings.services.lastfm.no-support')" />
</template>
</content-with-heading>
</div>
</div>
<div v-else v-text="$t('page.settings.services.spotify.no-support')" />
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.services.lastfm.title') }"
/>
</template>
<template #content>
<div v-if="servicesStore.isLastfmEnabled">
<div v-text="$t('page.settings.services.lastfm.grant-access')" />
<div
class="notification help"
v-text="$t('page.settings.services.lastfm.info')"
/>
<div v-if="!servicesStore.isLastfmActive">
<form @submit.prevent="loginLastfm">
<div class="field is-grouped">
<div class="control">
<input
v-model="lastfm_login.user"
class="input"
type="text"
:placeholder="$t('page.settings.services.username')"
/>
<div class="help is-danger" v-text="lastfm_login.errors.user" />
</div>
<div class="control">
<input
v-model="lastfm_login.password"
class="input"
type="password"
:placeholder="$t('page.settings.services.password')"
/>
<div
class="help is-danger"
v-text="lastfm_login.errors.password"
/>
</div>
<div class="control">
<button
class="button"
type="submit"
v-text="$t('actions.login')"
/>
</div>
</div>
<div class="help is-danger" v-text="lastfm_login.errors.error" />
</form>
</div>
<div v-else>
<button
class="button is-danger"
@click="logoutLastfm"
v-text="$t('actions.logout')"
/>
</div>
</div>
<div v-else v-text="$t('page.settings.services.lastfm.no-support')" />
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,90 +1,88 @@
<template>
<div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.devices.pairing') }"
/>
</template>
<template #content>
<div v-if="pairing.active">
<form @submit.prevent="kickoffPairing">
<label class="label has-text-weight-normal content">
<span v-text="$t('page.settings.devices.pairing-request')" />
<b v-text="pairing.remote" />
</label>
<div class="field is-grouped">
<div class="control">
<input
v-model="pairingRequest.pin"
class="input"
inputmode="numeric"
pattern="[\d]{4}"
:placeholder="$t('page.settings.devices.pairing-code')"
/>
</div>
<div class="control">
<button
class="button"
type="submit"
v-text="$t('actions.send')"
/>
</div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.devices.pairing') }"
/>
</template>
<template #content>
<div v-if="pairing.active">
<form @submit.prevent="kickoffPairing">
<label class="label has-text-weight-normal content">
<span v-text="$t('page.settings.devices.pairing-request')" />
<b v-text="pairing.remote" />
</label>
<div class="field is-grouped">
<div class="control">
<input
v-model="pairingRequest.pin"
class="input"
inputmode="numeric"
pattern="[\d]{4}"
:placeholder="$t('page.settings.devices.pairing-code')"
/>
</div>
</form>
</div>
<div v-else v-text="$t('page.settings.devices.no-active-pairing')" />
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.devices.speaker-pairing') }"
/>
</template>
<template #content>
<div
class="content"
v-text="$t('page.settings.devices.speaker-pairing-info')"
/>
<div v-for="output in outputs" :key="output.id">
<control-switch
v-model="output.selected"
@update:model-value="toggleOutput(output.id)"
>
<template #label>
<span v-text="output.name" />
</template>
</control-switch>
<form
v-if="output.needs_auth_key"
class="mb-5"
@submit.prevent="kickoffVerification(output.id)"
>
<div class="field is-grouped">
<div class="control">
<input
v-model="verificationRequest.pin"
class="input"
inputmode="numeric"
pattern="[\d]{4}"
:placeholder="$t('page.settings.devices.verification-code')"
/>
</div>
<div class="control">
<button
class="button"
type="submit"
v-text="$t('actions.verify')"
/>
</div>
<div class="control">
<button
class="button"
type="submit"
v-text="$t('actions.send')"
/>
</div>
</form>
</div>
</template>
</content-with-heading>
</div>
</div>
</form>
</div>
<div v-else v-text="$t('page.settings.devices.no-active-pairing')" />
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.devices.speaker-pairing') }"
/>
</template>
<template #content>
<div
class="content"
v-text="$t('page.settings.devices.speaker-pairing-info')"
/>
<div v-for="output in outputs" :key="output.id">
<control-switch
v-model="output.selected"
@update:model-value="toggleOutput(output.id)"
>
<template #label>
<span v-text="output.name" />
</template>
</control-switch>
<form
v-if="output.needs_auth_key"
class="mb-5"
@submit.prevent="kickoffVerification(output.id)"
>
<div class="field is-grouped">
<div class="control">
<input
v-model="verificationRequest.pin"
class="input"
inputmode="numeric"
pattern="[\d]{4}"
:placeholder="$t('page.settings.devices.verification-code')"
/>
</div>
<div class="control">
<button
class="button"
type="submit"
v-text="$t('actions.verify')"
/>
</div>
</div>
</form>
</div>
</template>
</content-with-heading>
</template>
<script>

View File

@ -1,160 +1,156 @@
<template>
<div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.language') }"
/>
</template>
<template #content>
<control-dropdown
v-model:value="locale"
:options="settingsStore.locales"
/>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.navigation-items') }"
/>
</template>
<template #content>
<div
class=" "
v-text="$t('page.settings.general.navigation-item-selection')"
/>
<div
class="notification is-size-7"
v-text="$t('page.settings.general.navigation-item-selection-info')"
/>
<control-setting-switch
category="webinterface"
name="show_menu_item_playlists"
>
<template #label>
<span v-text="$t('page.settings.general.playlists')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_music"
>
<template #label>
<span v-text="$t('page.settings.general.music')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_podcasts"
>
<template #label>
<span v-text="$t('page.settings.general.podcasts')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_audiobooks"
>
<template #label>
<span v-text="$t('page.settings.general.audiobooks')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_radio"
>
<template #label>
<span v-text="$t('page.settings.general.radio')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_files"
>
<template #label>
<span v-text="$t('page.settings.general.files')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_search"
>
<template #label>
<span v-text="$t('page.settings.general.search')" />
</template>
</control-setting-switch>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.now-playing-page') }"
/>
</template>
<template #content>
<control-setting-switch
category="webinterface"
name="show_filepath_now_playing"
>
<template #label>
<span v-text="$t('page.settings.general.show-path')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_composer_now_playing"
>
<template #label>
<span v-text="$t('page.settings.general.show-composer')" />
</template>
<template #help>
<span v-text="$t('page.settings.general.show-composer-info')" />
</template>
</control-setting-switch>
<control-setting-text-field
category="webinterface"
name="show_composer_for_genre"
:disabled="!settingsStore.show_composer_now_playing"
:placeholder="$t('page.settings.general.genres')"
>
<template #label>
<span v-text="$t('page.settings.general.show-composer-genres')" />
</template>
<template #help>
<i18n-t
keypath="page.settings.general.show-composer-genres-help"
tag="p"
class="help"
scope="global"
>
<br />
</i18n-t>
</template>
</control-setting-text-field>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.recently-added-page') }"
/>
</template>
<template #content>
<control-setting-integer-field
category="webinterface"
name="recently_added_limit"
>
<template #label>
<span
v-text="$t('page.settings.general.recently-added-page-info')"
/>
</template>
</control-setting-integer-field>
</template>
</content-with-heading>
</div>
<tabs-settings />
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.language') }"
/>
</template>
<template #content>
<control-dropdown
v-model:value="locale"
:options="settingsStore.locales"
/>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.navigation-items') }"
/>
</template>
<template #content>
<div
class=" "
v-text="$t('page.settings.general.navigation-item-selection')"
/>
<div
class="notification is-size-7"
v-text="$t('page.settings.general.navigation-item-selection-info')"
/>
<control-setting-switch
category="webinterface"
name="show_menu_item_playlists"
>
<template #label>
<span v-text="$t('page.settings.general.playlists')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_music"
>
<template #label>
<span v-text="$t('page.settings.general.music')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_podcasts"
>
<template #label>
<span v-text="$t('page.settings.general.podcasts')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_audiobooks"
>
<template #label>
<span v-text="$t('page.settings.general.audiobooks')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_radio"
>
<template #label>
<span v-text="$t('page.settings.general.radio')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_files"
>
<template #label>
<span v-text="$t('page.settings.general.files')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_menu_item_search"
>
<template #label>
<span v-text="$t('page.settings.general.search')" />
</template>
</control-setting-switch>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.now-playing-page') }"
/>
</template>
<template #content>
<control-setting-switch
category="webinterface"
name="show_filepath_now_playing"
>
<template #label>
<span v-text="$t('page.settings.general.show-path')" />
</template>
</control-setting-switch>
<control-setting-switch
category="webinterface"
name="show_composer_now_playing"
>
<template #label>
<span v-text="$t('page.settings.general.show-composer')" />
</template>
<template #help>
<span v-text="$t('page.settings.general.show-composer-info')" />
</template>
</control-setting-switch>
<control-setting-text-field
category="webinterface"
name="show_composer_for_genre"
:disabled="!settingsStore.show_composer_now_playing"
:placeholder="$t('page.settings.general.genres')"
>
<template #label>
<span v-text="$t('page.settings.general.show-composer-genres')" />
</template>
<template #help>
<i18n-t
keypath="page.settings.general.show-composer-genres-help"
tag="p"
class="help"
scope="global"
>
<br />
</i18n-t>
</template>
</control-setting-text-field>
</template>
</content-with-heading>
<content-with-heading>
<template #heading>
<heading-title
:content="{ title: $t('page.settings.general.recently-added-page') }"
/>
</template>
<template #content>
<control-setting-integer-field
category="webinterface"
name="recently_added_limit"
>
<template #label>
<span v-text="$t('page.settings.general.recently-added-page-info')" />
</template>
</control-setting-integer-field>
</template>
</content-with-heading>
</template>
<script>