[web] Change to camel case.

This commit is contained in:
Alain Nussbaumer 2025-03-11 19:42:17 +01:00
parent 905d0ca88b
commit da30c338fc
62 changed files with 522 additions and 647 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,15 +9,15 @@
@close="pairing_active = false"
/>
<modal-dialog-update
:show="show_update_dialog"
@close="show_update_dialog = false"
:show="showUpdateDialog"
@close="showUpdateDialog = false"
/>
<notification-list v-show="!show_burger_menu" />
<notification-list v-show="!showBurgerMenu" />
<navbar-bottom />
<div
v-show="show_burger_menu || show_player_menu"
v-show="showBurgerMenu || showPlayerMenu"
class="overlay-fullscreen"
@click="show_burger_menu = show_player_menu = false"
@click="uiStore.hideMenus"
/>
</template>
@ -50,7 +50,6 @@ export default {
NavbarTop,
NotificationList
},
setup() {
return {
configurationStore: useConfigurationStore(),
@ -66,7 +65,6 @@ export default {
uiStore: useUIStore()
}
},
data() {
return {
pairing_active: false,
@ -74,50 +72,47 @@ export default {
token_timer_id: 0
}
},
computed: {
show_burger_menu: {
showBurgerMenu: {
get() {
return this.uiStore.show_burger_menu
return this.uiStore.showBurgerMenu
},
set(value) {
this.uiStore.show_burger_menu = value
this.uiStore.showBurgerMenu = value
}
},
show_player_menu: {
showPlayerMenu: {
get() {
return this.uiStore.show_player_menu
return this.uiStore.showPlayerMenu
},
set(value) {
this.uiStore.show_player_menu = value
this.uiStore.showPlayerMenu = value
}
},
show_update_dialog: {
showUpdateDialog: {
get() {
return this.uiStore.show_update_dialog
return this.uiStore.showUpdateDialog
},
set(value) {
this.uiStore.show_update_dialog = value
this.uiStore.showUpdateDialog = value
}
}
},
watch: {
show_burger_menu() {
showBurgerMenu() {
this.update_is_clipped()
},
show_player_menu() {
showPlayerMenu() {
this.update_is_clipped()
}
},
created() {
this.connect()
// Start the progress bar on app start
this.$Progress.start()
// Hook the progress bar to start before we move router-view
this.$router.beforeEach((to, from, next) => {
if (to.meta.show_progress && !(to.path === from.path && to.hash)) {
if (!(to.path === from.path && to.hash)) {
if (to.meta.progress) {
this.$Progress.parseMeta(to.meta.progress)
}
@ -127,19 +122,16 @@ export default {
})
// Hook the progress bar to finish after we've finished moving router-view
this.$router.afterEach((to, from) => {
if (to.meta.show_progress) {
this.$Progress.finish()
}
this.$Progress.finish()
})
},
methods: {
connect() {
webapi
.config()
.then(({ data }) => {
this.configurationStore.$state = data
this.uiStore.hide_singles = data.hide_singles
this.uiStore.hideSingles = data.hide_singles
document.title = data.library_name
this.openWebsocket()
this.$Progress.finish()
@ -267,7 +259,7 @@ export default {
})
},
update_is_clipped() {
if (this.show_burger_menu || this.show_player_menu) {
if (this.showBurgerMenu || this.showPlayerMenu) {
document.querySelector('html').classList.add('is-clipped')
} else {
document.querySelector('html').classList.remove('is-clipped')

View File

@ -17,8 +17,7 @@ export default {
},
methods: {
open() {
this.uiStore.show_burger_menu = false
this.uiStore.show_player_menu = false
this.uiStore.hideMenus()
this.$router.push(this.to)
}
}

View File

@ -18,36 +18,26 @@ export default {
props: {
offset: { required: true, type: Number }
},
setup() {
return {
playerStore: usePlayerStore(),
queueStore: useQueueStore()
}
},
computed: {
disabled() {
return (
this.queueStore?.count <= 0 ||
this.is_stopped ||
this.current.data_kind === 'pipe'
this.playerStore.isStopped ||
this.queueStore.current.data_kind === 'pipe'
)
},
is_stopped() {
return this.player.state === 'stop'
},
current() {
return this.queueStore.current
},
player() {
return this.playerStore
},
visible() {
return ['podcast', 'audiobook'].includes(this.current.media_kind)
return ['podcast', 'audiobook'].includes(
this.queueStore.current.media_kind
)
}
},
methods: {
seek() {
if (!this.disabled) {

View File

@ -1,5 +1,5 @@
<template>
<a :class="{ 'is-dark': is_consume }" @click="toggle">
<a :class="{ 'is-dark': playerStore.consume }" @click="toggle">
<mdicon
class="icon"
name="fire"
@ -15,22 +15,14 @@ import webapi from '@/webapi'
export default {
name: 'ControlPlayerConsume',
setup() {
return {
playerStore: usePlayerStore()
}
},
computed: {
is_consume() {
return this.playerStore.consume
}
},
methods: {
toggle() {
webapi.player_consume(!this.is_consume)
webapi.player_consume(!this.playerStore.consume)
}
}
}

View File

@ -25,24 +25,17 @@ export default {
}
},
computed: {
current() {
return this.queueStore.current
},
disabled() {
return (
this.queueStore?.count <= 0 ||
this.is_stopped ||
this.current.data_kind === 'pipe'
this.playerStore.isStopped ||
this.queueStore.current.data_kind === 'pipe'
)
},
is_stopped() {
return this.player.state === 'stop'
},
player() {
return this.playerStore
},
visible() {
return ['podcast', 'audiobook'].includes(this.current.media_kind)
return ['podcast', 'audiobook'].includes(
this.queueStore.current.media_kind
)
}
},
methods: {

View File

@ -1,5 +1,5 @@
<template>
<a :class="{ 'is-dark': isActive }" @click="toggle">
<a :class="{ 'is-dark': lyricsStore.active }" @click="lyricsStore.toggle">
<mdicon
class="icon"
:name="icon"
@ -21,15 +21,9 @@ export default {
},
computed: {
icon() {
return this.isActive ? 'script-text-play' : 'script-text-outline'
},
isActive() {
return this.lyricsStore.pane
}
},
methods: {
toggle() {
this.lyricsStore.pane = !this.lyricsStore.pane
return this.lyricsStore.active
? 'script-text-play'
: 'script-text-outline'
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<a :disabled="disabled" @click="play_next">
<a :disabled="disabled" @click="next">
<mdicon
class="icon"
name="skip-forward"
@ -14,15 +14,16 @@ import webapi from '@/webapi'
export default {
name: 'ControlPlayerNext',
setup() {
return { queueStore: useQueueStore() }
},
computed: {
disabled() {
return useQueueStore()?.count <= 0
return this.queueStore.count <= 0
}
},
methods: {
play_next() {
next() {
if (this.disabled) {
return
}

View File

@ -27,19 +27,12 @@ export default {
return this.queueStore?.count <= 0
},
icon() {
if (!this.is_playing) {
if (!this.playerStore.isPlaying) {
return 'play'
} else if (this.is_pause_allowed) {
} else if (this.queueStore.isPauseAllowed) {
return 'pause'
}
return 'stop'
},
is_pause_allowed() {
const { current } = this.queueStore
return current && current.data_kind !== 'pipe'
},
is_playing() {
return this.playerStore.state === 'play'
}
},
methods: {
@ -55,9 +48,12 @@ export default {
}
return
}
if (this.is_playing && this.is_pause_allowed) {
if (this.playerStore.isPlaying && this.queueStore.isPauseAllowed) {
webapi.player_pause()
} else if (this.is_playing && !this.is_pause_allowed) {
} else if (
this.playerStore.isPlaying &&
!this.queueStore.isPauseAllowed
) {
webapi.player_stop()
} else {
webapi.player_play()

View File

@ -15,9 +15,7 @@ import webapi from '@/webapi'
export default {
name: 'ControlPlayerPrevious',
setup() {
return {
queueStore: useQueueStore()
}
return { queueStore: useQueueStore() }
},
computed: {
disabled() {

View File

@ -1,5 +1,5 @@
<template>
<a :class="{ 'is-dark': !is_repeat_off }" @click="toggle">
<a :class="{ 'is-dark': !playerStore.isRepeatOff }" @click="toggle">
<mdicon
class="icon"
:name="icon"
@ -16,35 +16,23 @@ import webapi from '@/webapi'
export default {
name: 'ControlPlayerRepeat',
setup() {
return {
playerStore: usePlayerStore()
}
return { playerStore: usePlayerStore() }
},
computed: {
icon() {
if (this.is_repeat_all) {
if (this.playerStore.isRepeatAll) {
return 'repeat'
} else if (this.is_repeat_single) {
} else if (this.playerStore.isRepeatSingle) {
return 'repeat-once'
}
return 'repeat-off'
},
is_repeat_all() {
return this.playerStore.repeat === 'all'
},
is_repeat_off() {
return !this.is_repeat_all && !this.is_repeat_single
},
is_repeat_single() {
return this.playerStore.repeat === 'single'
}
},
methods: {
toggle() {
if (this.is_repeat_all) {
if (this.playerStore.isRepeatAll) {
webapi.player_repeat('single')
} else if (this.is_repeat_single) {
} else if (this.playerStore.isRepeatSingle) {
webapi.player_repeat('off')
} else {
webapi.player_repeat('all')

View File

@ -1,5 +1,5 @@
<template>
<a :class="{ 'is-dark': isShuffle }" @click="toggle">
<a :class="{ 'is-dark': playerStore.shuffle }" @click="toggle">
<mdicon
class="icon"
:name="icon"
@ -16,24 +16,19 @@ import webapi from '@/webapi'
export default {
name: 'ControlPlayerShuffle',
setup() {
return {
playerStore: usePlayerStore()
}
return { playerStore: usePlayerStore() }
},
computed: {
icon() {
if (this.isShuffle) {
if (this.playerStore.shuffle) {
return 'shuffle'
}
return 'shuffle-disabled'
},
isShuffle() {
return this.playerStore.shuffle
}
},
methods: {
toggle() {
webapi.player_shuffle(!this.is_shuffle)
webapi.player_shuffle(!this.playerStore.shuffle)
}
}
}

View File

@ -40,18 +40,18 @@
</template>
<teleport to="#app">
<modal-dialog-album
:item="selected_item"
:item="selectedItem"
:media_kind="media_kind"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
@remove-podcast="openRemovePodcastDialog()"
@play-count-changed="onPlayCountChange()"
/>
<modal-dialog
:actions="actions"
:show="show_remove_podcast_modal"
:show="showRemovePodcastModal"
:title="$t('page.podcast.remove-podcast')"
@cancel="show_remove_podcast_modal = false"
@cancel="showRemovePodcastModal = false"
@remove="removePodcast"
>
<template #content>
@ -89,9 +89,9 @@ export default {
data() {
return {
rss_playlist_to_remove: {},
selected_item: {},
show_details_modal: false,
show_remove_podcast_modal: false
selectedItem: {},
showDetailsModal: false,
showRemovePodcastModal: false
}
},
computed: {
@ -102,12 +102,12 @@ export default {
]
},
media_kind_resolved() {
return this.media_kind || this.selected_item.media_kind
return this.media_kind || this.selectedItem.media_kind
}
},
methods: {
open(item) {
this.selected_item = item
this.selectedItem = item
if (this.media_kind_resolved === 'podcast') {
this.$router.push({ name: 'podcast', params: { id: item.id } })
} else if (this.media_kind_resolved === 'audiobook') {
@ -120,19 +120,19 @@ export default {
}
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
},
openRemovePodcastDialog() {
webapi
.library_album_tracks(this.selected_item.id, { limit: 1 })
.library_album_tracks(this.selectedItem.id, { limit: 1 })
.then(({ data: album }) => {
webapi.library_track_playlists(album.items[0].id).then(({ data }) => {
;[this.rss_playlist_to_remove] = data.items.filter(
(playlist) => playlist.type === 'rss'
)
this.show_remove_podcast_modal = true
this.show_details_modal = false
this.showRemovePodcastModal = true
this.showDetailsModal = false
})
})
},
@ -140,7 +140,7 @@ export default {
this.$emit('play-count-changed')
},
removePodcast() {
this.show_remove_podcast_modal = false
this.showRemovePodcastModal = false
webapi
.library_playlist_delete(this.rss_playlist_to_remove.id)
.then(() => {

View File

@ -31,9 +31,9 @@
</template>
<teleport to="#app">
<modal-dialog-album-spotify
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -51,7 +51,7 @@ export default {
return { settingsStore: useSettingsStore() }
},
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
open(item) {
@ -61,8 +61,8 @@ export default {
})
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
}
}
}

View File

@ -24,9 +24,9 @@
</template>
<teleport to="#app">
<modal-dialog-artist
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -40,19 +40,19 @@ export default {
props: { items: { required: true, type: Object } },
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
open(item) {
this.selected_item = item
this.selectedItem = item
const route =
item.media_kind === 'audiobook' ? 'audiobooks-artist' : 'music-artist'
this.$router.push({ name: route, params: { id: item.id } })
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
}
}
}

View File

@ -13,9 +13,9 @@
</template>
<teleport to="#app">
<modal-dialog-artist-spotify
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -29,7 +29,7 @@ export default {
props: { items: { required: true, type: Object } },
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
open(item) {
@ -39,8 +39,8 @@ export default {
})
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
}
}
}

View File

@ -26,9 +26,9 @@
</template>
<teleport to="#app">
<modal-dialog-composer
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -42,12 +42,12 @@ export default {
props: { items: { required: true, type: Object } },
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
open(item) {
this.selected_item = item
this.selectedItem = item
this.$router.push({
name: 'music-composer-albums',
params: { name: item.name }
@ -55,8 +55,8 @@ export default {
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
}
}
}

View File

@ -38,9 +38,9 @@
</template>
<teleport to="#app">
<modal-dialog-directory
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -54,7 +54,7 @@ export default {
props: { items: { required: true, type: Array } },
data() {
return { selected_item: '', show_details_modal: false }
return { selectedItem: '', showDetailsModal: false }
},
computed: {
@ -81,8 +81,8 @@ export default {
this.$router.push(route)
},
openDialog(item) {
this.selected_item = item.path
this.show_details_modal = true
this.selectedItem = item.path
this.showDetailsModal = true
},
openParent() {
this.open(this.directories.slice(-1).pop())

View File

@ -26,10 +26,10 @@
</template>
<teleport to="#app">
<modal-dialog-genre
:item="selected_item"
:item="selectedItem"
:media_kind="media_kind"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -45,7 +45,7 @@ export default {
media_kind: { required: true, type: String }
},
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
open(item) {
@ -56,8 +56,8 @@ export default {
})
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
}
}
}

View File

@ -1,10 +1,10 @@
<template>
<div
v-if="isNext || !show_only_next_items"
v-if="isNext || !hideReadItems"
class="media is-align-items-center is-clickable mb-0"
@click="play"
>
<div v-if="edit_mode" class="media-left">
<div v-if="editing" class="media-left">
<mdicon
class="icon has-text-grey is-movable"
name="drag-horizontal"
@ -53,10 +53,10 @@ export default {
name: 'ListItemQueueItem',
props: {
current_position: { required: true, type: Number },
edit_mode: Boolean,
editing: Boolean,
item: { required: true, type: Object },
position: { required: true, type: Number },
show_only_next_items: Boolean
hideReadItems: Boolean
},
setup() {
return { playerStore: usePlayerStore() }

View File

@ -18,8 +18,8 @@
<teleport to="#app">
<modal-dialog-playlist
:item="selectedItem"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -33,7 +33,7 @@ export default {
props: { items: { required: true, type: Object } },
data() {
return { selectedItem: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
@ -54,7 +54,7 @@ export default {
},
openDialog(item) {
this.selectedItem = item
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -20,9 +20,9 @@
</template>
<teleport to="#app">
<modal-dialog-playlist-spotify
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -38,7 +38,7 @@ export default {
props: { items: { required: true, type: Object } },
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
@ -46,8 +46,8 @@ export default {
this.$router.push({ name: 'playlist-spotify', params: { id: item.id } })
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
}
}
}

View File

@ -10,11 +10,11 @@
<div
v-else
class="media is-align-items-center is-clickable mb-0"
:class="{ 'with-progress': show_progress }"
:class="{ 'with-progress': showProgress }"
@click="play(item.item)"
>
<mdicon
v-if="show_icon"
v-if="showIcon"
class="media-left icon"
name="file-music-outline"
/>
@ -33,7 +33,7 @@
/>
<div class="is-size-7 has-text-grey" v-text="item.item.album" />
<progress
v-if="show_progress && item.item.seek_ms > 0"
v-if="showProgress && item.item.seek_ms > 0"
class="progress is-dark"
:max="item.item.length_ms"
:value="item.item.seek_ms"
@ -48,9 +48,9 @@
</template>
<teleport to="#app">
<modal-dialog-track
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
@play-count-changed="$emit('play-count-changed')"
/>
</teleport>
@ -66,20 +66,18 @@ export default {
props: {
expression: { default: '', type: String },
items: { required: true, type: Object },
show_icon: Boolean,
show_progress: Boolean,
showIcon: Boolean,
showProgress: Boolean,
uris: { default: '', type: String }
},
emits: ['play-count-changed'],
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
},
play(item) {
if (this.uris) {

View File

@ -44,9 +44,9 @@
</template>
<teleport to="#app">
<modal-dialog-track-spotify
:item="selected_item"
:show="show_details_modal"
@close="show_details_modal = false"
:item="selectedItem"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</teleport>
</template>
@ -63,12 +63,12 @@ export default {
items: { required: true, type: Object }
},
data() {
return { selected_item: {}, show_details_modal: false }
return { selectedItem: {}, showDetailsModal: false }
},
methods: {
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
},
play(item) {
if (item.is_playable) {

View File

@ -10,7 +10,7 @@
<template v-for="(verse, index) in lyrics" :key="index">
<div
v-if="index === verse_index"
:class="{ 'is-highlighted': is_playing }"
:class="{ 'is-highlighted': playerStore.isPlaying }"
>
<span
v-for="word in verse.words"
@ -53,9 +53,6 @@ export default {
}
},
computed: {
is_playing() {
return this.playerStore.state === 'play'
},
lyrics() {
const raw = this.lyricsStore.content
const parsed = []

View File

@ -25,11 +25,11 @@ export default {
if (this.media_kind_resolved === 'podcast') {
if (this.item.data_kind === 'url') {
return [
{ handler: this.mark_played, key: 'actions.mark-as-played' },
{ handler: this.remove_podcast, key: 'actions.remove-podcast' }
{ handler: this.markAsPlayed, key: 'actions.mark-as-played' },
{ handler: this.removePodcast, key: 'actions.remove-podcast' }
]
}
return [{ handler: this.mark_played, key: 'actions.mark-as-played' }]
return [{ handler: this.markAsPlayed, key: 'actions.mark-as-played' }]
}
return []
},
@ -71,7 +71,7 @@ export default {
}
},
methods: {
mark_played() {
markAsPlayed() {
webapi
.library_album_track_update(this.item.id, { play_count: 'played' })
.then(() => {
@ -109,7 +109,7 @@ export default {
})
}
},
remove_podcast() {
removePodcast() {
this.$emit('remove-podcast')
}
}

View File

@ -7,7 +7,10 @@
>
<template #content>
<div v-if="!libraryStore.updating">
<div v-if="spotify_enabled || rss.tracks > 0" class="field">
<div
v-if="servicesStore.isSpotifyEnabled || rss.tracks > 0"
class="field"
>
<label class="label" v-text="$t('dialog.update.info')" />
<div class="control">
<div class="select is-small">
@ -15,7 +18,7 @@
<option value="" v-text="$t('dialog.update.all')" />
<option value="files" v-text="$t('dialog.update.local')" />
<option
v-if="spotify_enabled"
v-if="servicesStore.isSpotifyEnabled"
value="spotify"
v-text="$t('dialog.update.spotify')"
/>
@ -80,9 +83,6 @@ export default {
},
rss() {
return this.libraryStore.rss
},
spotify_enabled() {
return this.servicesStore.spotify.webapi_token_valid
}
},
methods: {

View File

@ -1,13 +1,10 @@
<template>
<nav
class="navbar is-fixed-bottom"
:class="{ 'is-dark': !is_now_playing_page }"
>
<nav class="navbar is-fixed-bottom" :class="{ 'is-dark': !isNowPlayingPage }">
<div class="navbar-brand is-flex-grow-1">
<control-link class="navbar-item" :to="{ name: 'queue' }">
<mdicon class="icon" name="playlist-play" />
</control-link>
<template v-if="is_now_playing_page">
<template v-if="isNowPlayingPage">
<control-player-previous class="navbar-item ml-auto" />
<control-player-back class="navbar-item" :offset="10000" />
<control-player-play class="navbar-item" show_disabled_message />
@ -21,26 +18,30 @@
class="navbar-item is-justify-content-flex-start is-expanded is-clipped is-size-7"
>
<div class="is-text-clipped">
<strong v-text="current.title" />
<strong v-text="queueStore.current.title" />
<br />
<span v-text="current.artist" />
<span v-text="queueStore.current.artist" />
<span
v-if="current.album"
v-text="$t('navigation.now-playing', { album: current.album })"
v-if="queueStore.current.album"
v-text="
$t('navigation.now-playing', {
album: queueStore.current.album
})
"
/>
</div>
</control-link>
<control-player-play class="navbar-item" show_disabled_message />
</template>
<a class="navbar-item" @click="toggle">
<a class="navbar-item" @click="uiStore.togglePlayerMenu">
<mdicon
class="icon"
:name="uiStore.show_player_menu ? 'chevron-down' : 'chevron-up'"
:name="uiStore.showPlayerMenu ? 'chevron-down' : 'chevron-up'"
/>
</a>
<div
class="dropdown is-up is-right"
:class="{ 'is-active': uiStore.show_player_menu }"
:class="{ 'is-active': uiStore.showPlayerMenu }"
>
<div class="dropdown-menu is-mobile">
<div class="dropdown-content">
@ -105,7 +106,6 @@ export default {
ControlPlayerShuffle,
ControlStreamVolume
},
setup() {
return {
notificationsStore: useNotificationsStore(),
@ -114,20 +114,10 @@ export default {
uiStore: useUIStore()
}
},
computed: {
current() {
return this.queueStore.current
},
is_now_playing_page() {
isNowPlayingPage() {
return this.$route.name === 'now-playing'
}
},
methods: {
toggle() {
this.uiStore.show_player_menu = !this.uiStore.show_player_menu
this.uiStore.show_burger_menu = false
}
}
}
</script>

View File

@ -9,18 +9,15 @@
>
<mdicon class="icon" :name="menu.icon" size="16" />
</control-link>
<a
class="navbar-item ml-auto"
@click="uiStore.show_burger_menu = !uiStore.show_burger_menu"
>
<a class="navbar-item ml-auto" @click="uiStore.toggleBurgerMenu">
<mdicon
class="icon"
:name="uiStore.show_burger_menu ? 'close' : 'menu'"
:name="uiStore.showBurgerMenu ? 'close' : 'menu'"
/>
</a>
<div
class="dropdown is-right"
:class="{ 'is-active': uiStore.show_burger_menu }"
:class="{ 'is-active': uiStore.showBurgerMenu }"
>
<div class="dropdown-menu is-mobile">
<div class="dropdown-content">
@ -161,7 +158,7 @@ export default {
]
},
zindex() {
if (this.uiStore.show_player_menu) {
if (this.uiStore.showPlayerMenu) {
return 'z-index: 21'
}
return ''
@ -169,8 +166,8 @@ export default {
},
methods: {
openUpdateDialog() {
this.uiStore.show_update_dialog = true
this.uiStore.show_burger_menu = false
this.uiStore.showUpdateDialog = true
this.uiStore.hideMenus()
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<section v-if="spotify_enabled">
<section v-if="servicesStore.isSpotifyEnabled">
<div class="container">
<div class="columns is-centered">
<div class="column is-four-fifths">
@ -41,11 +41,6 @@ export default {
emits: ['search-library', 'search-spotify'],
setup() {
return { servicesStore: useServicesStore() }
},
computed: {
spotify_enabled() {
return this.servicesStore.spotify.webapi_token_valid
}
}
}
</script>

View File

@ -7,7 +7,7 @@
<template #heading-right>
<control-button
:button="{
handler: showUpdateDialog,
handler: openUpdateDialog,
icon: 'refresh',
key: 'page.about.update'
}"
@ -139,8 +139,8 @@ export default {
}
},
methods: {
showUpdateDialog() {
this.uiStore.show_update_dialog = true
openUpdateDialog() {
this.uiStore.showUpdateDialog = true
}
}
}

View File

@ -32,8 +32,8 @@
<list-tracks :items="tracks" :uris="album.uri" />
<modal-dialog-album
:item="album"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-hero>
@ -86,13 +86,13 @@ export default {
data() {
return {
album: {},
show_details_modal: false,
showDetailsModal: false,
tracks: new GroupedList()
}
},
methods: {
openArtist() {
this.show_details_modal = false
this.showDetailsModal = false
this.$router.push({
name: 'music-artist',
params: { id: this.album.artist_id }
@ -102,7 +102,7 @@ export default {
webapi.player_play_uri(this.album.uri, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -32,8 +32,8 @@
<list-tracks-spotify :items="tracks" :context_uri="album.uri" />
<modal-dialog-album-spotify
:item="album"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-hero>
@ -83,7 +83,7 @@ export default {
data() {
return {
album: { artists: [{}], tracks: {} },
show_details_modal: false
showDetailsModal: false
}
},
computed: {
@ -103,11 +103,11 @@ export default {
})
},
play() {
this.show_details_modal = false
this.showDetailsModal = false
webapi.player_play_uri(this.album.uri, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -10,7 +10,7 @@
class="is-size-7 is-uppercase"
v-text="$t('options.filter.title')"
/>
<control-switch v-model="uiStore.hide_singles">
<control-switch v-model="uiStore.hideSingles">
<template #label>
<span v-text="$t('options.filter.hide-singles')" />
</template>
@ -19,8 +19,8 @@
</template>
</control-switch>
<control-switch
v-if="spotify_enabled"
v-model="uiStore.hide_spotify"
v-if="servicesStore.isSpotifyEnabled"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
@ -70,7 +70,7 @@ const dataObject = {
return webapi.library_albums('music')
},
set(vm, response) {
vm.albums_list = new GroupedList(response.data)
vm.albumList = new GroupedList(response.data)
}
}
@ -95,7 +95,7 @@ export default {
},
data() {
return {
albums_list: new GroupedList()
albumList: new GroupedList()
}
},
computed: {
@ -104,10 +104,10 @@ export default {
(grouping) => grouping.id === this.uiStore.albums_sort
)
options.filters = [
(album) => !this.uiStore.hide_singles || album.track_count > 2,
(album) => !this.uiStore.hide_spotify || album.data_kind !== 'spotify'
(album) => !this.uiStore.hideSingles || album.track_count > 2,
(album) => !this.uiStore.hideSpotify || album.data_kind !== 'spotify'
]
return this.albums_list.group(options)
return this.albumList.group(options)
},
groupings() {
return [
@ -161,9 +161,6 @@ export default {
subtitle: [{ count: this.albums.count, key: 'count.albums' }],
title: this.$t('page.albums.title')
}
},
spotify_enabled() {
return this.servicesStore.spotify.webapi_token_valid
}
}
}

View File

@ -9,8 +9,8 @@
v-text="$t('page.artist.filter.title')"
/>
<control-switch
v-if="spotify_enabled"
v-model="uiStore.hide_spotify"
v-if="servicesStore.isSpotifyEnabled"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('page.artist.filter.hide-spotify')" />
@ -47,8 +47,8 @@
<list-albums :items="albums" />
<modal-dialog-artist
:item="artist"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -77,7 +77,7 @@ const dataObject = {
},
set(vm, response) {
vm.artist = response[0].data
vm.albums_list = new GroupedList(response[1].data)
vm.albumList = new GroupedList(response[1].data)
}
}
@ -102,9 +102,9 @@ export default {
},
data() {
return {
albums_list: new GroupedList(),
albumList: new GroupedList(),
artist: {},
show_details_modal: false
showDetailsModal: false
}
},
computed: {
@ -113,9 +113,9 @@ export default {
(grouping) => grouping.id === this.uiStore.artist_albums_sort
)
options.filters = [
(album) => !this.uiStore.hide_spotify || album.data_kind !== 'spotify'
(album) => !this.uiStore.hideSpotify || album.data_kind !== 'spotify'
]
return this.albums_list.group(options)
return this.albumList.group(options)
},
groupings() {
return [
@ -136,7 +136,7 @@ export default {
subtitle: [
{ count: this.albums.count, key: 'count.albums' },
{
count: this.track_count,
count: this.trackCount,
handler: this.openTracks,
key: 'count.tracks'
}
@ -144,10 +144,7 @@ export default {
title: this.artist.name
}
},
spotify_enabled() {
return this.servicesStore.spotify.webapi_token_valid
},
track_count() {
trackCount() {
// The count of tracks is incorrect when albums have Spotify tracks.
return [...this.albums].reduce(
(total, album) => total + (album.isItem ? album.item.track_count : 0),
@ -169,7 +166,7 @@ export default {
)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -14,7 +14,7 @@
</template>
<template #content>
<list-albums-spotify :items="albums" />
<vue-eternal-loading v-if="offset < total" :load="load_next">
<vue-eternal-loading v-if="offset < total" :load="loadNext">
<template #loading>
<div class="columns is-centered">
<div class="column has-text-centered">
@ -31,8 +31,8 @@
</vue-eternal-loading>
<modal-dialog-artist-spotify
:item="artist"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -71,7 +71,7 @@ const dataObject = {
vm.albums = []
vm.total = 0
vm.offset = 0
vm.append_albums(response.shift())
vm.appendAlbums(response.shift())
}
}
@ -98,7 +98,7 @@ export default {
albums: [],
artist: {},
offset: 0,
show_details_modal: false,
showDetailsModal: false,
total: 0
}
},
@ -111,12 +111,12 @@ export default {
}
},
methods: {
append_albums(data) {
appendAlbums(data) {
this.albums = this.albums.concat(data.items)
this.total = data.total
this.offset += data.limit
},
load_next({ loaded }) {
loadNext({ loaded }) {
const spotifyApi = new SpotifyWebApi()
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
spotifyApi
@ -126,16 +126,16 @@ export default {
offset: this.offset
})
.then((data) => {
this.append_albums(data)
this.appendAlbums(data)
loaded(data.items.length, PAGE_SIZE)
})
},
play() {
this.show_album_details_modal = false
this.showDetailsModal = false
webapi.player_play_uri(this.artist.uri, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -10,8 +10,8 @@
v-text="$t('options.filter.title')"
/>
<control-switch
v-if="spotify_enabled"
v-model="uiStore.hide_spotify"
v-if="servicesStore.isSpotifyEnabled"
v-model="uiStore.hideSpotify"
>
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
@ -48,8 +48,8 @@
<list-tracks :items="tracks" :uris="track_uris" />
<modal-dialog-artist
:item="artist"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -79,7 +79,7 @@ const dataObject = {
},
set(vm, response) {
vm.artist = response[0].data
vm.tracks_list = new GroupedList(response[1].data.tracks)
vm.trackList = new GroupedList(response[1].data.tracks)
}
}
@ -106,8 +106,8 @@ export default {
data() {
return {
artist: {},
show_details_modal: false,
tracks_list: new GroupedList()
showDetailsModal: false,
trackList: new GroupedList()
}
},
computed: {
@ -148,25 +148,22 @@ export default {
title: this.artist.name
}
},
spotify_enabled() {
return this.servicesStore.spotify.webapi_token_valid
},
track_uris() {
return this.tracks_list.items.map((item) => item.uri).join()
return this.trackList.items.map((item) => item.uri).join()
},
tracks() {
const { options } = this.groupings.find(
(grouping) => grouping.id === this.uiStore.artist_tracks_sort
)
options.filters = [
(track) => !this.uiStore.hide_spotify || track.data_kind !== 'spotify'
(track) => !this.uiStore.hideSpotify || track.data_kind !== 'spotify'
]
return this.tracks_list.group(options)
return this.trackList.group(options)
}
},
methods: {
openArtist() {
this.show_details_modal = false
this.showDetailsModal = false
this.$router.push({
name: 'music-artist',
params: { id: this.artist.id }
@ -174,12 +171,12 @@ export default {
},
play() {
webapi.player_play_uri(
this.tracks_list.items.map((item) => item.uri).join(),
this.trackList.items.map((item) => item.uri).join(),
true
)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -10,7 +10,7 @@
class="is-size-7 is-uppercase"
v-text="$t('options.filter.title')"
/>
<control-switch v-model="uiStore.hide_singles">
<control-switch v-model="uiStore.hideSingles">
<template #label>
<span v-text="$t('options.filter.hide-singles')" />
</template>
@ -18,8 +18,8 @@
<span v-text="$t('options.filter.hide-singles-help')" />
</template>
</control-switch>
<div v-if="spotify_enabled" class="field">
<control-switch v-model="uiStore.hide_spotify">
<div v-if="servicesStore.isSpotifyEnabled" class="field">
<control-switch v-model="uiStore.hideSpotify">
<template #label>
<span v-text="$t('options.filter.hide-spotify')" />
</template>
@ -69,7 +69,7 @@ const dataObject = {
return webapi.library_artists('music')
},
set(vm, response) {
vm.artists_list = new GroupedList(response.data)
vm.artistList = new GroupedList(response.data)
}
}
@ -94,7 +94,7 @@ export default {
},
data() {
return {
artists_list: new GroupedList()
artistList: new GroupedList()
}
},
computed: {
@ -104,11 +104,11 @@ export default {
)
options.filters = [
(artist) =>
!this.uiStore.hide_singles ||
!this.uiStore.hideSingles ||
artist.track_count > artist.album_count * 2,
(artist) => !this.uiStore.hide_spotify || artist.data_kind !== 'spotify'
(artist) => !this.uiStore.hideSpotify || artist.data_kind !== 'spotify'
]
return this.artists_list.group(options)
return this.artistList.group(options)
},
groupings() {
return [
@ -132,9 +132,6 @@ export default {
subtitle: [{ count: this.artists.count, key: 'count.artists' }],
title: this.$t('page.artists.title')
}
},
spotify_enabled() {
return this.servicesStore.spotify.webapi_token_valid
}
}
}

View File

@ -15,7 +15,7 @@
:button="{
handler: play,
icon: 'play',
key: 'page.audiobooks.album.play'
key: 'actions.play'
}"
/>
<control-button
@ -33,12 +33,12 @@
/>
</template>
<template #content>
<list-tracks :items="tracks" :show_progress="true" :uris="album.uri" />
<list-tracks :items="tracks" :show-progress="true" :uris="album.uri" />
<modal-dialog-album
:item="album"
:show="show_details_modal"
:show="showDetailsModal"
:media_kind="'audiobook'"
@close="show_details_modal = false"
@close="showDetailsModal = false"
/>
</template>
</content-with-hero>
@ -84,13 +84,13 @@ export default {
data() {
return {
album: {},
show_details_modal: false,
showDetailsModal: false,
tracks: new GroupedList()
}
},
methods: {
openArtist() {
this.show_details_modal = false
this.showDetailsModal = false
this.$router.push({
name: 'audiobooks-artist',
params: { id: this.album.artist_id }
@ -100,7 +100,7 @@ export default {
webapi.player_play_uri(this.album.uri, false)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -20,8 +20,8 @@
<list-albums :items="albums" />
<modal-dialog-artist
:item="artist"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -68,7 +68,7 @@ export default {
return {
albums: new GroupedList(),
artist: {},
show_details_modal: false
showDetailsModal: false
}
},
computed: {
@ -92,7 +92,7 @@ export default {
)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -16,8 +16,8 @@
<list-albums :items="albums" />
<modal-dialog-composer
:item="composer"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -64,7 +64,7 @@ export default {
return {
albums: new GroupedList(),
composer: {},
show_details_modal: false
showDetailsModal: false
}
},
computed: {
@ -99,7 +99,7 @@ export default {
webapi.player_play_expression(this.expression, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -31,8 +31,8 @@
<list-tracks :items="tracks" :expression="expression" />
<modal-dialog-composer
:item="composer"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -60,7 +60,7 @@ const dataObject = {
},
set(vm, response) {
vm.composer = response[0].data
vm.tracks_list = new GroupedList(response[1].data.tracks)
vm.trackList = new GroupedList(response[1].data.tracks)
}
}
@ -86,8 +86,8 @@ export default {
data() {
return {
composer: {},
show_details_modal: false,
tracks_list: new GroupedList()
showDetailsModal: false,
trackList: new GroupedList()
}
},
computed: {
@ -145,7 +145,7 @@ export default {
webapi.player_play_expression(this.expression, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -18,12 +18,12 @@
<list-tracks
:expression="expression"
:items="tracks"
:show_icon="true"
:show-icon="true"
/>
<modal-dialog-directory
:item="current"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -101,7 +101,7 @@ export default {
return {
directories: [],
playlists: new GroupedList(),
show_details_modal: false,
showDetailsModal: false,
tracks: new GroupedList()
}
},
@ -124,7 +124,7 @@ export default {
webapi.player_play_expression(this.expression, false)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
},
transform(path) {
return { name: path.slice(path.lastIndexOf('/') + 1), path }

View File

@ -20,8 +20,8 @@
<modal-dialog-genre
:item="genre"
:media_kind="media_kind"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -73,7 +73,7 @@ export default {
albums: new GroupedList(),
genre: {},
media_kind: this.$route.query.media_kind,
show_details_modal: false
showDetailsModal: false
}
},
computed: {
@ -96,7 +96,7 @@ export default {
},
methods: {
openTracks() {
this.show_details_modal = false
this.showDetailsModal = false
this.$router.push({
name: 'genre-tracks',
params: { name: this.genre.name },
@ -110,7 +110,7 @@ export default {
)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -32,8 +32,8 @@
<modal-dialog-genre
:item="genre"
:media_kind="media_kind"
:show="show_details_modal"
@close="show_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -61,7 +61,7 @@ const dataObject = {
},
set(vm, response) {
vm.genre = response[0].data.genres.items.shift()
vm.tracks_list = new GroupedList(response[1].data.tracks)
vm.trackList = new GroupedList(response[1].data.tracks)
}
}
@ -88,8 +88,8 @@ export default {
return {
genre: {},
media_kind: this.$route.query.media_kind,
show_details_modal: false,
tracks_list: new GroupedList()
showDetailsModal: false,
trackList: new GroupedList()
}
},
computed: {
@ -133,12 +133,12 @@ export default {
const { options } = this.groupings.find(
(grouping) => grouping.id === this.uiStore.genre_tracks_sort
)
return this.tracks_list.group(options)
return this.trackList.group(options)
}
},
methods: {
openGenre() {
this.show_details_modal = false
this.showDetailsModal = false
this.$router.push({
name: 'genre-albums',
params: { name: this.genre.name },
@ -149,7 +149,7 @@ export default {
webapi.player_play_expression(this.expression, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -89,7 +89,6 @@ export default {
data() {
return {
albums: [],
selected_track: {},
tracks: { items: [] }
}
}

View File

@ -8,10 +8,10 @@
:artist="track.artist"
:album="track.album"
class="is-clickable is-big"
:class="{ 'is-masked': lyricsStore.pane }"
:class="{ 'is-masked': lyricsStore.active }"
@click="openDialog(track)"
/>
<lyrics-pane v-if="lyricsStore.pane" />
<lyrics-pane v-if="lyricsStore.active" />
<control-slider
v-model:value="track_progress"
class="mt-5"
@ -45,9 +45,9 @@
</div>
</div>
<modal-dialog-queue-item
:show="show_details_modal"
:item="selected_item"
@close="show_details_modal = false"
:show="showDetailsModal"
:item="selectedItem"
@close="showDetailsModal = false"
/>
</template>
@ -85,8 +85,8 @@ export default {
INTERVAL,
interval_id: 0,
is_dragged: false,
selected_item: {},
show_details_modal: false
selectedItem: {},
showDetailsModal: false
}
},
computed: {
@ -165,8 +165,8 @@ export default {
this.is_dragged = false
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
},
seek() {
if (!this.is_live) {

View File

@ -21,9 +21,9 @@
<list-tracks :items="tracks" :uris="uris" />
<modal-dialog-playlist
:item="playlist"
:show="show_details_modal"
:show="showDetailsModal"
:uris="uris"
@close="show_details_modal = false"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -69,7 +69,7 @@ export default {
data() {
return {
playlist: {},
show_details_modal: false,
showDetailsModal: false,
tracks: new GroupedList()
}
},
@ -92,7 +92,7 @@ export default {
webapi.player_play_uri(this.uris, true)
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -19,7 +19,7 @@
</template>
<template #content>
<list-tracks-spotify :items="tracks" :context_uri="playlist.uri" />
<vue-eternal-loading v-if="offset < total" :load="load_next">
<vue-eternal-loading v-if="offset < total" :load="load">
<template #loading>
<div class="columns is-centered">
<div class="column has-text-centered">
@ -33,8 +33,8 @@
</vue-eternal-loading>
<modal-dialog-playlist-spotify
:item="playlist"
:show="show_playlist_details_modal"
@close="show_playlist_details_modal = false"
:show="showDetailsModal"
@close="showDetailsModal = false"
/>
</template>
</content-with-heading>
@ -72,7 +72,7 @@ const dataObject = {
vm.tracks = []
vm.total = 0
vm.offset = 0
vm.append_tracks(response.shift())
vm.appendTracks(response.shift())
}
}
@ -98,23 +98,26 @@ export default {
return {
offset: 0,
playlist: { tracks: {} },
show_playlist_details_modal: false,
showDetailsModal: false,
total: 0,
tracks: []
}
},
computed: {
heading() {
return {
subtitle: [
{ count: this.playlist.tracks.total, key: 'count.playlists' }
],
title: this.playlist.name
if (this.playlist.name) {
return {
subtitle: [
{ count: this.playlist.tracks.total, key: 'count.playlists' }
],
title: this.playlist.name
}
}
return {}
}
},
methods: {
append_tracks(data) {
appendTracks(data) {
let position = Math.max(
-1,
...this.tracks.map((item) => item.position).filter((item) => item)
@ -132,7 +135,7 @@ export default {
this.total = data.total
this.offset += data.limit
},
load_next({ loaded }) {
load({ loaded }) {
const spotifyApi = new SpotifyWebApi()
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
spotifyApi
@ -142,16 +145,16 @@ export default {
offset: this.offset
})
.then((data) => {
this.append_tracks(data)
this.appendTracks(data)
loaded(data.items.length, PAGE_SIZE)
})
},
play() {
this.show_details_modal = false
this.showDetailsModal = false
webapi.player_play_uri(this.playlist.uri, true)
},
showDetails() {
this.show_playlist_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -31,22 +31,22 @@
<template #content>
<list-tracks
:items="tracks"
:show_progress="true"
:show-progress="true"
@play-count-changed="reloadTracks"
/>
<modal-dialog-album
:item="album"
:show="show_details_modal"
:show="showDetailsModal"
:media_kind="'podcast'"
@close="show_details_modal = false"
@close="showDetailsModal = false"
@play-count-changed="reloadTracks"
@remove-podcast="openRemovePodcastDialog"
/>
<modal-dialog
:actions="actions"
:show="show_remove_podcast_modal"
:show="showRemovePodcastModal"
:title="$t('page.podcast.remove-podcast')"
@cancel="show_remove_podcast_modal = false"
@cancel="showRemovePodcastModal = false"
@remove="removePodcast"
>
<template #content>
@ -107,8 +107,8 @@ export default {
return {
album: {},
rss_playlist_to_remove: {},
show_details_modal: false,
show_remove_podcast_modal: false,
showDetailsModal: false,
showRemovePodcastModal: false,
tracks: new GroupedList()
}
},
@ -136,8 +136,8 @@ export default {
;[this.rss_playlist_to_remove] = data.items.filter(
(pl) => pl.type === 'rss'
)
this.show_remove_podcast_modal = true
this.show_details_modal = false
this.showRemovePodcastModal = true
this.showDetailsModal = false
})
},
play() {
@ -149,7 +149,7 @@ export default {
})
},
removePodcast() {
this.show_remove_podcast_modal = false
this.showRemovePodcastModal = false
webapi
.library_playlist_delete(this.rss_playlist_to_remove.id)
.then(() => {
@ -157,7 +157,7 @@ export default {
})
},
showDetails() {
this.show_details_modal = true
this.showDetailsModal = true
}
}
}

View File

@ -16,7 +16,7 @@
<template #content>
<list-tracks
:items="tracks"
:show_progress="true"
:show-progress="true"
@play-count-changed="reloadNewEpisodes"
/>
</template>
@ -49,8 +49,8 @@
@podcast-deleted="reloadPodcasts()"
/>
<modal-dialog-add-rss
:show="show_url_modal"
@close="show_url_modal = false"
:show="showAddPodcastModal"
@close="showAddPodcastModal = false"
@podcast-added="reloadPodcasts()"
/>
</template>
@ -104,7 +104,7 @@ export default {
data() {
return {
albums: [],
show_url_modal: false,
showAddPodcastModal: false,
tracks: { items: [] }
}
},
@ -130,7 +130,7 @@ export default {
this.tracks.items = {}
},
openAddPodcastDialog() {
this.show_url_modal = true
this.showAddPodcastModal = true
},
reloadNewEpisodes() {
webapi.library_podcasts_new_episodes().then(({ data }) => {
@ -145,7 +145,7 @@ export default {
},
updateRss() {
this.libraryStore.update_dialog_scan_kind = 'rss'
this.uiStore.show_update_dialog = true
this.uiStore.showUpdateDialog = true
}
}
}

View File

@ -7,11 +7,11 @@
<template #heading-right>
<control-button
:button="{
handler: toggleHideReadItems,
handler: uiStore.toggleHideReadItems,
icon: 'eye-off-outline',
key: 'actions.hide-previous'
}"
:class="{ 'is-dark': uiStore.show_only_next_items }"
:class="{ 'is-dark': uiStore.hideReadItems }"
/>
<control-button
:button="{
@ -26,8 +26,8 @@
icon: 'pencil',
key: 'actions.edit'
}"
:class="{ 'is-dark': edit_mode }"
:disabled="queue_items.length === 0"
:class="{ 'is-dark': editing }"
:disabled="queueStore.isEmpty"
/>
<control-button
:button="{
@ -35,30 +35,30 @@
icon: 'delete-empty',
key: 'actions.clear'
}"
:disabled="queue_items.length === 0"
:disabled="queueStore.isEmpty"
/>
<control-button
v-if="is_queue_save_allowed"
v-if="queueStore.isSavingAllowed"
:button="{
handler: showSaveDialog,
handler: openSaveDialog,
icon: 'download',
key: 'actions.save'
}"
:disabled="queue_items.length === 0"
:disabled="queueStore.isEmpty"
/>
</template>
<template #content>
<draggable v-model="queue_items" item-key="id" @end="move_item">
<draggable v-model="items" item-key="id" @end="moveItem">
<template #item="{ element, index }">
<list-item-queue-item
:item="element"
:position="index"
:current_position="current_position"
:show_only_next_items="uiStore.show_only_next_items"
:edit_mode="edit_mode"
:hide-read-items="uiStore.hideReadItems"
:editing="editing"
>
<template #actions>
<a v-if="!edit_mode" @click.prevent.stop="openDialog(element)">
<a v-if="!editing" @click.prevent.stop="openDialog(element)">
<mdicon
class="icon has-text-grey"
name="dots-vertical"
@ -66,7 +66,7 @@
/>
</a>
<a
v-if="element.id !== player.item_id && edit_mode"
v-if="isRemovable(element)"
@click.prevent.stop="remove(element)"
>
<mdicon class="icon has-text-grey" name="delete" size="18" />
@ -76,18 +76,18 @@
</template>
</draggable>
<modal-dialog-queue-item
:show="show_details_modal"
:item="selected_item"
@close="show_details_modal = false"
:show="showDetailsModal"
:item="selectedItem"
@close="showDetailsModal = false"
/>
<modal-dialog-add-stream
:show="show_url_modal"
@close="show_url_modal = false"
:show="showAddStreamDialog"
@close="showAddStreamDialog = false"
/>
<modal-dialog-playlist-save
v-if="is_queue_save_allowed"
:show="show_pls_save_modal"
@close="show_pls_save_modal = false"
v-if="queueStore.isSavingAllowed"
:show="showSaveModal"
@close="showSaveModal = false"
/>
</template>
</content-with-heading>
@ -131,78 +131,65 @@ export default {
},
data() {
return {
edit_mode: false,
selected_item: {},
show_details_modal: false,
show_pls_save_modal: false,
show_url_modal: false
editing: false,
selectedItem: {},
showDetailsModal: false,
showSaveModal: false,
showAddStreamDialog: false
}
},
computed: {
current_position() {
return this.queue.current?.position ?? -1
return this.queueStore.current?.position ?? -1
},
heading() {
return {
subtitle: [{ count: this.queue.count, key: 'count.tracks' }],
subtitle: [{ count: this.queueStore.count, key: 'count.tracks' }],
title: this.$t('page.queue.title')
}
},
is_queue_save_allowed() {
return (
this.configurationStore.allow_modifying_stored_playlists &&
this.configurationStore.default_playlist_directory
)
},
player() {
return this.playerStore
},
queue() {
return this.queueStore
},
queue_items: {
items: {
get() {
return this.queue.items
return this.queueStore.items
},
set() {
set(value) {
/* Do nothing? Send move request in @end event */
}
}
},
methods: {
move_item(event) {
clearQueue() {
webapi.queue_clear()
},
isRemovable(item) {
return item.id !== this.playerStore.item_id && this.editing
},
moveItem(event) {
const oldPosition =
event.oldIndex +
(this.uiStore.show_only_next_items && this.current_position)
const item = this.queue_items[oldPosition]
event.oldIndex + (this.uiStore.hideReadItems && this.current_position)
const item = this.items[oldPosition]
const newPosition = item.position + (event.newIndex - event.oldIndex)
if (newPosition !== oldPosition) {
webapi.queue_move(item.id, newPosition)
}
},
openAddStreamDialog() {
this.show_url_modal = true
this.showAddStreamDialog = true
},
openDialog(item) {
this.selected_item = item
this.show_details_modal = true
this.selectedItem = item
this.showDetailsModal = true
},
clearQueue() {
webapi.queue_clear()
openSaveDialog() {
if (!this.queueStore.isEmpty) {
this.showSaveModal = true
}
},
remove(item) {
webapi.queue_remove(item.id)
},
showSaveDialog() {
if (this.queue_items.length > 0) {
this.show_pls_save_modal = true
}
},
toggleEdit() {
this.edit_mode = !this.edit_mode
},
toggleHideReadItems() {
this.uiStore.show_only_next_items = !this.uiStore.show_only_next_items
this.editing = !this.editing
}
}
}

View File

@ -36,10 +36,10 @@
</div>
</form>
<div class="field is-grouped is-grouped-multiline mt-4">
<div v-for="query in history" :key="query" class="control">
<div v-for="item in history" :key="item" class="control">
<div class="tags has-addons">
<a class="tag" @click="openSearch(query)" v-text="query" />
<a class="tag is-delete" @click="removeSearch(query)" />
<a class="tag" @click="openSearch(item)" v-text="item" />
<a class="tag is-delete" @click="removeSearch(item)" />
</div>
</div>
</div>
@ -131,14 +131,14 @@ export default {
track: ListTracks.name
},
results: new Map(),
search_limit: {},
limit: {},
query: '',
search_types: SEARCH_TYPES
types: SEARCH_TYPES
}
},
computed: {
expanded() {
return this.search_types.length === 1
return this.types.length === 1
},
history() {
return this.searchStore.history
@ -152,20 +152,20 @@ export default {
mounted() {
this.searchStore.source = this.$route.name
this.query = this.searchStore.query
this.search_limit = PAGE_SIZE
this.limit = PAGE_SIZE
this.search()
},
methods: {
expand(type) {
this.query = this.searchStore.query
this.search_types = [type]
this.search_limit = -1
this.types = [type]
this.limit = -1
this.search()
},
openSearch(query) {
this.query = query
this.search_types = SEARCH_TYPES
this.search_limit = PAGE_SIZE
this.types = SEARCH_TYPES
this.limit = PAGE_SIZE
this.search()
},
removeSearch(query) {
@ -173,14 +173,14 @@ export default {
},
reset() {
this.results.clear()
this.search_types.forEach((type) => {
this.types.forEach((type) => {
this.results.set(type, new GroupedList())
})
},
search(event) {
if (event) {
this.search_types = SEARCH_TYPES
this.search_limit = PAGE_SIZE
this.types = SEARCH_TYPES
this.limit = PAGE_SIZE
}
this.query = this.query.trim()
if (!this.query || !this.query.replace(/^query:/u, '')) {
@ -188,7 +188,7 @@ export default {
return
}
this.reset()
this.search_types.forEach((type) => {
this.types.forEach((type) => {
this.searchItems(type)
})
this.searchStore.add(this.query)
@ -197,7 +197,7 @@ export default {
const music = type !== 'audiobook' && type !== 'podcast'
const kind = music ? 'music' : type
const parameters = {
limit: this.search_limit,
limit: this.limit,
type: music ? type : 'album'
}
if (this.query.startsWith('query:')) {
@ -216,7 +216,7 @@ export default {
this.$router.push({ name: 'search-spotify' })
},
show(type) {
return this.search_types.includes(type)
return this.types.includes(type)
},
showAllButton(items) {
return items.total > items.items.length

View File

@ -19,10 +19,10 @@
</div>
</form>
<div class="field is-grouped is-grouped-multiline mt-4">
<div v-for="query in history" :key="query" class="control">
<div v-for="item in history" :key="item" class="control">
<div class="tags has-addons">
<a class="tag" @click="openSearch(query)" v-text="query" />
<a class="tag is-delete" @click="removeSearch(query)" />
<a class="tag" @click="openSearch(item)" v-text="item" />
<a class="tag is-delete" @click="removeSearch(item)" />
</div>
</div>
</div>
@ -118,14 +118,14 @@ export default {
track: ListTracksSpotify.name
},
results: new Map(),
search_parameters: {},
parameters: {},
query: '',
search_types: SEARCH_TYPES
types: SEARCH_TYPES
}
},
computed: {
expanded() {
return this.search_types.length === 1
return this.types.length === 1
},
history() {
return this.searchStore.history.filter(
@ -141,22 +141,22 @@ export default {
mounted() {
this.searchStore.source = this.$route.name
this.query = this.searchStore.query
this.search_parameters.limit = PAGE_SIZE
this.parameters.limit = PAGE_SIZE
this.search()
},
methods: {
expand(type) {
this.query = this.searchStore.query
this.search_types = [type]
this.search_parameters.limit = PAGE_SIZE_EXPANDED
this.search_parameters.offset = 0
this.types = [type]
this.parameters.limit = PAGE_SIZE_EXPANDED
this.parameters.offset = 0
this.search()
},
openSearch(query) {
this.query = query
this.search_types = SEARCH_TYPES
this.search_parameters.limit = PAGE_SIZE
this.search_parameters.offset = 0
this.types = SEARCH_TYPES
this.parameters.limit = PAGE_SIZE
this.parameters.offset = 0
this.search()
},
removeSearch(query) {
@ -164,14 +164,14 @@ export default {
},
reset() {
this.results.clear()
this.search_types.forEach((type) => {
this.types.forEach((type) => {
this.results.set(type, { items: [], total: 0 })
})
},
search(event) {
if (event) {
this.search_types = SEARCH_TYPES
this.search_parameters.limit = PAGE_SIZE
this.types = SEARCH_TYPES
this.parameters.limit = PAGE_SIZE
}
this.query = this.query.trim()
if (!this.query) {
@ -180,7 +180,7 @@ export default {
}
this.reset()
this.searchItems().then((data) => {
this.search_types.forEach((type) => {
this.types.forEach((type) => {
this.results.set(type, data[`${type}s`])
})
})
@ -188,14 +188,10 @@ export default {
},
searchItems() {
return webapi.spotify().then(({ data }) => {
this.search_parameters.market = data.webapi_country
this.parameters.market = data.webapi_country
const spotifyApi = new SpotifyWebApi()
spotifyApi.setAccessToken(data.webapi_token)
return spotifyApi.search(
this.query,
this.search_types,
this.search_parameters
)
return spotifyApi.search(this.query, this.types, this.parameters)
})
},
searchLibrary() {
@ -204,22 +200,22 @@ export default {
})
},
searchNext({ loaded }) {
const [type] = this.search_types,
const [type] = this.types,
items = this.results.get(type)
this.search_parameters.limit = PAGE_SIZE_EXPANDED
this.parameters.limit = PAGE_SIZE_EXPANDED
this.searchItems().then((data) => {
const [next] = Object.values(data)
items.items.push(...next.items)
items.total = next.total
if (!this.search_parameters.offset) {
this.search_parameters.offset = 0
if (!this.parameters.offset) {
this.parameters.offset = 0
}
this.search_parameters.offset += next.limit
this.parameters.offset += next.limit
loaded(next.items.length, PAGE_SIZE_EXPANDED)
})
},
show(type) {
return this.search_types.includes(type)
return this.types.includes(type)
},
showAllButton(items) {
return items.total > items.items.length

View File

@ -46,84 +46,61 @@ const TOP_WITH_TABS = 100
export const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/:all(.*)*',
redirect: '/'
},
{
component: PageAbout,
name: 'about',
path: '/about'
},
{
component: PageAlbum,
meta: { show_progress: true },
name: 'music-album',
path: '/music/albums/:id'
},
{ path: '/:all(.*)*', redirect: '/' },
{ component: PageAbout, name: 'about', path: '/about' },
{ component: PageAlbum, name: 'music-album', path: '/music/albums/:id' },
{
component: PageAlbumSpotify,
meta: { show_progress: true },
name: 'music-spotify-album',
path: '/music/spotify/albums/:id'
},
{
component: PageAlbums,
meta: { has_index: true, show_progress: true },
name: 'music-albums',
path: '/music/albums'
},
{
component: PageArtist,
meta: { has_index: true, show_progress: true },
name: 'music-artist',
path: '/music/artists/:id'
},
{
component: PageArtistSpotify,
meta: { show_progress: true },
name: 'music-spotify-artist',
path: '/music/spotify/artists/:id'
},
{
component: PageArtists,
meta: { has_index: true, show_progress: true },
name: 'music-artists',
path: '/music/artists'
},
{
component: PageArtistTracks,
meta: { has_index: true, show_progress: true },
name: 'music-artist-tracks',
path: '/music/artists/:id/tracks'
},
{
component: PageAudiobooksAlbum,
meta: { show_progress: true },
name: 'audiobooks-album',
path: '/audiobooks/albums/:id'
},
{
component: PageAudiobooksAlbums,
meta: { has_index: true, show_progress: true },
name: 'audiobooks-albums',
path: '/audiobooks/albums'
},
{
component: PageAudiobooksArtist,
meta: { show_progress: true },
name: 'audiobooks-artist',
path: '/audiobooks/artists/:id'
},
{
component: PageAudiobooksArtists,
meta: { has_index: true, show_progress: true },
name: 'audiobooks-artists',
path: '/audiobooks/artists'
},
{
component: PageAudiobooksGenres,
meta: { has_index: true, show_progress: true },
name: 'audiobooks-genres',
path: '/audiobooks/genres'
},
@ -139,87 +116,66 @@ export const router = createRouter({
},
{
component: PageMusic,
meta: { show_progress: true },
name: 'music-history',
path: '/music/history'
},
{
component: PageMusicRecentlyAdded,
meta: { show_progress: true },
name: 'music-recently-added',
path: '/music/recently-added'
},
{
component: PageMusicRecentlyPlayed,
meta: { show_progress: true },
name: 'music-recently-played',
path: '/music/recently-played'
},
{
component: PageMusicSpotify,
meta: { show_progress: true },
name: 'music-spotify',
path: '/music/spotify'
},
{
component: PageMusicSpotifyFeaturedPlaylists,
meta: { show_progress: true },
name: 'music-spotify-featured-playlists',
path: '/music/spotify/featured-playlists'
},
{
component: PageMusicSpotifyNewReleases,
meta: { show_progress: true },
name: 'music-spotify-new-releases',
path: '/music/spotify/new-releases'
},
{
component: PageComposerAlbums,
meta: { show_progress: true },
name: 'music-composer-albums',
path: '/music/composers/:name/albums'
},
{
component: PageComposerTracks,
meta: { show_progress: true },
name: 'music-composer-tracks',
path: '/music/composers/:name/tracks'
},
{
component: PageComposers,
meta: { has_index: true, show_progress: true },
name: 'music-composers',
path: '/music/composers'
},
{
component: PageFiles,
meta: { show_progress: true },
name: 'files',
path: '/files'
},
{ component: PageFiles, name: 'files', path: '/files' },
{
component: PageGenreAlbums,
meta: { has_index: true, show_progress: true },
name: 'genre-albums',
path: '/genres/:name/albums'
},
{
component: PageGenreTracks,
meta: { has_index: true, show_progress: true },
name: 'genre-tracks',
path: '/genres/:name/tracks'
},
{
component: PageGenres,
meta: { has_index: true, show_progress: true },
name: 'music-genres',
path: '/music/genres'
},
{
component: PageNowPlaying,
name: 'now-playing',
path: '/now-playing'
},
{ component: PageNowPlaying, name: 'now-playing', path: '/now-playing' },
{
name: 'playlists',
path: '/playlists',
@ -227,37 +183,23 @@ export const router = createRouter({
},
{
component: PagePlaylistFolder,
meta: { show_progress: true },
name: 'playlist-folder',
path: '/playlists/:id'
},
{
component: PagePlaylistTracks,
meta: { show_progress: true },
name: 'playlist',
path: '/playlists/:id/tracks'
},
{
component: PagePlaylistTracksSpotify,
meta: { show_progress: true },
name: 'playlist-spotify',
path: '/playlists/spotify/:id/tracks'
},
{
component: PagePodcast,
meta: { show_progress: true },
name: 'podcast',
path: '/podcasts/:id'
},
{
component: PagePodcasts,
meta: { show_progress: true },
name: 'podcasts',
path: '/podcasts'
},
{ component: PagePodcast, name: 'podcast', path: '/podcasts/:id' },
{ component: PagePodcasts, name: 'podcasts', path: '/podcasts' },
{
component: PageRadioStreams,
meta: { show_progress: true },
name: 'radio',
path: '/radio'
},
@ -328,13 +270,13 @@ export const router = createRouter({
router.beforeEach((to, from, next) => {
const uiStore = useUIStore()
if (uiStore.show_burger_menu) {
uiStore.show_burger_menu = false
if (uiStore.showBurgerMenu) {
uiStore.showBurgerMenu = false
next(false)
return
}
if (uiStore.show_player_menu) {
uiStore.show_player_menu = false
if (uiStore.showPlayerMenu) {
uiStore.showPlayerMenu = false
next(false)
return
}

View File

@ -1,8 +1,13 @@
import { defineStore } from 'pinia'
export const useLyricsStore = defineStore('LyricsStore', {
actions: {
toggle() {
this.active = !this.active
}
},
state: () => ({
content: [],
pane: false
active: false
})
})

View File

@ -4,7 +4,7 @@ export const useNotificationsStore = defineStore('NotificationsStore', {
actions: {
add(notification) {
const newNotification = {
id: this.next_id++,
id: this.nextId++,
text: notification.text,
timeout: notification.timeout,
topic: notification.topic,
@ -33,8 +33,5 @@ export const useNotificationsStore = defineStore('NotificationsStore', {
}
}
},
state: () => ({
list: [],
next_id: 1
})
state: () => ({ list: [], nextId: 1 })
})

View File

@ -1,6 +1,13 @@
import { defineStore } from 'pinia'
export const usePlayerStore = defineStore('PlayerStore', {
getters: {
isPlaying: (state) => state.state === 'play',
isRepeatAll: (state) => state.repeat === 'all',
isRepeatOff: (state) => state.repeat === 'off',
isRepeatSingle: (state) => state.repeat === 'single',
isStopped: (state) => state.state === 'stop'
},
state: () => ({
consume: false,
item_id: 0,

View File

@ -1,4 +1,5 @@
import { defineStore } from 'pinia'
import { useConfigurationStore } from '@/stores/configuration'
import { usePlayerStore } from '@/stores/player'
export const useQueueStore = defineStore('QueueStore', {
@ -6,6 +7,19 @@ export const useQueueStore = defineStore('QueueStore', {
current(state) {
const player = usePlayerStore()
return state.items.find((item) => item.id === player.item_id) ?? {}
},
isEmpty(state) {
return state.items.length === 0
},
isPauseAllowed(state) {
return state.current && state.current.data_kind !== 'pipe'
},
isSavingAllowed(state) {
const configuration = useConfigurationStore()
return (
configuration.allow_modifying_stored_playlists &&
configuration.default_playlist_directory
)
}
},
state: () => ({

View File

@ -1,6 +1,11 @@
import { defineStore } from 'pinia'
export const useServicesStore = defineStore('ServicesStore', {
actions: {
isSpotifyEnabled() {
return this.spotify.webapi_token_valid
}
},
state: () => ({
lastfm: {},
spotify: {}

View File

@ -1,6 +1,23 @@
import { defineStore } from 'pinia'
export const useUIStore = defineStore('UIStore', {
actions: {
hideMenus() {
this.showBurgerMenu = false
this.showPlayerMenu = false
},
toggleBurgerMenu() {
this.showPlayerMenu = false
this.showBurgerMenu = !this.showBurgerMenu
},
togglePlayerMenu() {
this.showBurgerMenu = false
this.showPlayerMenu = !this.showPlayerMenu
},
toggleHideReadItems() {
this.hideReadItems = !this.hideReadItems
}
},
state: () => ({
albums_sort: 1,
artist_albums_sort: 1,
@ -8,11 +25,11 @@ export const useUIStore = defineStore('UIStore', {
artists_sort: 1,
composer_tracks_sort: 1,
genre_tracks_sort: 1,
hide_singles: false,
hide_spotify: false,
show_burger_menu: false,
show_only_next_items: false,
show_player_menu: false,
show_update_dialog: false
hideReadItems: false,
hideSingles: false,
hideSpotify: false,
showBurgerMenu: false,
showPlayerMenu: false,
showUpdateDialog: false
})
})