[web] Change to Pinia store
This commit is contained in:
parent
ed16cc7928
commit
8b586728b6
File diff suppressed because it is too large
Load Diff
|
@ -20,6 +20,7 @@
|
||||||
"bulma-switch": "^2.0.4",
|
"bulma-switch": "^2.0.4",
|
||||||
"luxon": "^3.4.4",
|
"luxon": "^3.4.4",
|
||||||
"mdi-vue": "^3.0.13",
|
"mdi-vue": "^3.0.13",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
"reconnectingwebsocket": "^1.0.0",
|
"reconnectingwebsocket": "^1.0.0",
|
||||||
"spotify-web-api-js": "^1.5.2",
|
"spotify-web-api-js": "^1.5.2",
|
||||||
"vue": "^3.4.23",
|
"vue": "^3.4.23",
|
||||||
|
@ -27,8 +28,7 @@
|
||||||
"vue-router": "^4.3.2",
|
"vue-router": "^4.3.2",
|
||||||
"vue3-click-away": "^1.2.4",
|
"vue3-click-away": "^1.2.4",
|
||||||
"vue3-lazyload": "^0.3.8",
|
"vue3-lazyload": "^0.3.8",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0"
|
||||||
"vuex": "^4.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||||
|
|
|
@ -25,13 +25,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ModalDialogRemotePairing from '@/components/ModalDialogRemotePairing.vue'
|
import ModalDialogRemotePairing from '@/components/ModalDialogRemotePairing.vue'
|
||||||
import ModalDialogUpdate from '@/components/ModalDialogUpdate.vue'
|
import ModalDialogUpdate from '@/components/ModalDialogUpdate.vue'
|
||||||
import NavbarBottom from '@/components/NavbarBottom.vue'
|
import NavbarBottom from '@/components/NavbarBottom.vue'
|
||||||
import NavbarTop from '@/components/NavbarTop.vue'
|
import NavbarTop from '@/components/NavbarTop.vue'
|
||||||
import NotificationList from '@/components/NotificationList.vue'
|
import NotificationList from '@/components/NotificationList.vue'
|
||||||
import ReconnectingWebSocket from 'reconnectingwebsocket'
|
import ReconnectingWebSocket from 'reconnectingwebsocket'
|
||||||
|
import { useConfigurationStore } from '@/stores/configuration'
|
||||||
|
import { useLibraryStore } from '@/stores/library'
|
||||||
|
import { useLyricsStore } from '@/stores/lyrics'
|
||||||
|
import { useNotificationsStore } from '@/stores/notifications'
|
||||||
|
import { useOutputsStore } from './stores/outputs'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
|
import { useRemotesStore } from './stores/remotes'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
|
import { useUIStore } from './stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -44,6 +54,22 @@ export default {
|
||||||
NotificationList
|
NotificationList
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
configurationStore: useConfigurationStore(),
|
||||||
|
libraryStore: useLibraryStore(),
|
||||||
|
lyricsStore: useLyricsStore(),
|
||||||
|
notificationsStore: useNotificationsStore(),
|
||||||
|
outputsStore: useOutputsStore(),
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore(),
|
||||||
|
remotesStore: useRemotesStore(),
|
||||||
|
servicesStore: useServicesStore(),
|
||||||
|
settingsStore: useSettingsStore(),
|
||||||
|
uiStore: useUIStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pairing_active: false,
|
pairing_active: false,
|
||||||
|
@ -55,26 +81,26 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
show_burger_menu: {
|
show_burger_menu: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.show_burger_menu
|
return this.uiStore.show_burger_menu
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.SHOW_BURGER_MENU, value)
|
this.uiStore.show_burger_menu = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show_player_menu: {
|
show_player_menu: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.show_player_menu
|
return this.uiStore.show_player_menu
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.SHOW_PLAYER_MENU, value)
|
this.uiStore.show_player_menu = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show_update_dialog: {
|
show_update_dialog: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.show_update_dialog
|
return this.uiStore.show_update_dialog
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.SHOW_UPDATE_DIALOG, value)
|
this.uiStore.show_update_dialog = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -115,15 +141,14 @@ export default {
|
||||||
webapi
|
webapi
|
||||||
.config()
|
.config()
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_CONFIG, data)
|
this.configurationStore.$state = data
|
||||||
this.$store.commit(types.HIDE_SINGLES, data.hide_singles)
|
this.uiStore.hide_singles = data.hide_singles
|
||||||
document.title = data.library_name
|
document.title = data.library_name
|
||||||
|
|
||||||
this.open_ws()
|
this.open_ws()
|
||||||
this.$Progress.finish()
|
this.$Progress.finish()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.$store.dispatch('add_notification', {
|
this.notificationsStore.add({
|
||||||
text: this.$t('server.connection-failed'),
|
text: this.$t('server.connection-failed'),
|
||||||
topic: 'connection',
|
topic: 'connection',
|
||||||
type: 'danger'
|
type: 'danger'
|
||||||
|
@ -131,8 +156,8 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
open_ws() {
|
open_ws() {
|
||||||
if (this.$store.state.config.websocket_port <= 0) {
|
if (this.configurationStore.websocket_port <= 0) {
|
||||||
this.$store.dispatch('add_notification', {
|
this.notificationsStore.add({
|
||||||
text: this.$t('server.missing-port'),
|
text: this.$t('server.missing-port'),
|
||||||
type: 'danger'
|
type: 'danger'
|
||||||
})
|
})
|
||||||
|
@ -144,7 +169,7 @@ export default {
|
||||||
protocol = 'wss://'
|
protocol = 'wss://'
|
||||||
}
|
}
|
||||||
|
|
||||||
let wsUrl = `${protocol}${window.location.hostname}:${this.$store.state.config.websocket_port}`
|
let wsUrl = `${protocol}${window.location.hostname}:${this.configurationStore.websocket_port}`
|
||||||
|
|
||||||
if (import.meta.env.DEV && import.meta.env.VITE_OWNTONE_URL) {
|
if (import.meta.env.DEV && import.meta.env.VITE_OWNTONE_URL) {
|
||||||
/*
|
/*
|
||||||
|
@ -152,7 +177,7 @@ export default {
|
||||||
* url from the host of the environment variable VITE_OWNTONE_URL
|
* url from the host of the environment variable VITE_OWNTONE_URL
|
||||||
*/
|
*/
|
||||||
const url = new URL(import.meta.env.VITE_OWNTONE_URL)
|
const url = new URL(import.meta.env.VITE_OWNTONE_URL)
|
||||||
wsUrl = `${protocol}${url.hostname}:${this.$store.state.config.websocket_port}`
|
wsUrl = `${protocol}${url.hostname}:${this.configurationStore.websocket_port}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const socket = new ReconnectingWebSocket(wsUrl, 'notify', {
|
const socket = new ReconnectingWebSocket(wsUrl, 'notify', {
|
||||||
|
@ -267,59 +292,58 @@ export default {
|
||||||
},
|
},
|
||||||
update_lastfm() {
|
update_lastfm() {
|
||||||
webapi.lastfm().then(({ data }) => {
|
webapi.lastfm().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_LASTFM, data)
|
this.servicesStore.lastfm = data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_library_stats() {
|
update_library_stats() {
|
||||||
webapi.library_stats().then(({ data }) => {
|
webapi.library_stats().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_LIBRARY_STATS, data)
|
this.libraryStore.$state = data
|
||||||
})
|
})
|
||||||
webapi.library_count('scan_kind is rss').then(({ data }) => {
|
webapi.library_count('scan_kind is rss').then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_LIBRARY_RSS_COUNT, data)
|
this.libraryStore.rss = data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_lyrics() {
|
update_lyrics() {
|
||||||
const track = this.$store.getters.now_playing
|
const track = this.queueStore.current
|
||||||
if (track && track.track_id) {
|
if (track?.track_id) {
|
||||||
webapi.library_track(track.track_id).then(({ data }) => {
|
webapi.library_track(track.track_id).then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_LYRICS, data.lyrics)
|
this.lyricsStore.lyrics = data.lyrics
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$store.commit(types.UPDATE_LYRICS)
|
this.lyricsStore.$reset()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update_outputs() {
|
update_outputs() {
|
||||||
webapi.outputs().then(({ data }) => {
|
webapi.outputs().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_OUTPUTS, data.outputs)
|
this.outputsStore.outputs = data.outputs
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_pairing() {
|
update_pairing() {
|
||||||
webapi.pairing().then(({ data }) => {
|
webapi.pairing().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_PAIRING, data)
|
this.remotesStore.$state = data
|
||||||
this.pairing_active = data.active
|
this.pairing_active = data.active
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_player_status() {
|
update_player_status() {
|
||||||
webapi.player_status().then(({ data }) => {
|
webapi.player_status().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_PLAYER_STATUS, data)
|
this.playerStore.$state = data
|
||||||
this.update_lyrics()
|
this.update_lyrics()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_queue() {
|
update_queue() {
|
||||||
webapi.queue().then(({ data }) => {
|
webapi.queue().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_QUEUE, data)
|
this.queueStore.$state = data
|
||||||
this.update_lyrics()
|
this.update_lyrics()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_settings() {
|
update_settings() {
|
||||||
webapi.settings().then(({ data }) => {
|
webapi.settings().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_SETTINGS, data)
|
this.settingsStore.$state = data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
update_spotify() {
|
update_spotify() {
|
||||||
webapi.spotify().then(({ data }) => {
|
webapi.spotify().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_SPOTIFY, data)
|
this.servicesStore.spotify = data
|
||||||
|
|
||||||
if (this.token_timer_id > 0) {
|
if (this.token_timer_id > 0) {
|
||||||
window.clearTimeout(this.token_timer_id)
|
window.clearTimeout(this.token_timer_id)
|
||||||
this.token_timer_id = 0
|
this.token_timer_id = 0
|
||||||
|
|
|
@ -8,7 +8,10 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="media is-align-items-center" @click="open(item.item)">
|
<div v-else class="media is-align-items-center" @click="open(item.item)">
|
||||||
<div v-if="show_artwork" class="media-left">
|
<div
|
||||||
|
v-if="settingsStore.show_cover_artwork_in_album_lists"
|
||||||
|
class="media-left"
|
||||||
|
>
|
||||||
<cover-artwork
|
<cover-artwork
|
||||||
:url="item.item.artwork_url"
|
:url="item.item.artwork_url"
|
||||||
:artist="item.item.artist"
|
:artist="item.item.artist"
|
||||||
|
@ -69,6 +72,7 @@
|
||||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import ModalDialog from '@/components/ModalDialog.vue'
|
import ModalDialog from '@/components/ModalDialog.vue'
|
||||||
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -80,6 +84,10 @@ export default {
|
||||||
},
|
},
|
||||||
emits: ['play-count-changed', 'podcast-deleted'],
|
emits: ['play-count-changed', 'podcast-deleted'],
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { settingsStore: useSettingsStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
rss_playlist_to_remove: {},
|
rss_playlist_to_remove: {},
|
||||||
|
@ -92,12 +100,6 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
media_kind_resolved() {
|
media_kind_resolved() {
|
||||||
return this.media_kind || this.selected_item.media_kind
|
return this.media_kind || this.selected_item.media_kind
|
||||||
},
|
|
||||||
show_artwork() {
|
|
||||||
return this.$store.getters.setting(
|
|
||||||
'webinterface',
|
|
||||||
'show_cover_artwork_in_album_lists'
|
|
||||||
).value
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<template v-for="item in items" :key="item.id">
|
<template v-for="item in items" :key="item.id">
|
||||||
<div class="media is-align-items-center" @click="open(item)">
|
<div class="media is-align-items-center" @click="open(item)">
|
||||||
<div v-if="show_artwork" class="media-left is-clickable">
|
<div
|
||||||
|
v-if="settingsStore.show_cover_artwork_in_album_lists"
|
||||||
|
class="media-left is-clickable"
|
||||||
|
>
|
||||||
<cover-artwork
|
<cover-artwork
|
||||||
:url="artwork_url(item)"
|
:url="artwork_url(item)"
|
||||||
:artist="item.artist"
|
:artist="item.artist"
|
||||||
|
@ -41,23 +44,19 @@
|
||||||
<script>
|
<script>
|
||||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ListAlbumsSpotify',
|
name: 'ListAlbumsSpotify',
|
||||||
components: { CoverArtwork, ModalDialogAlbumSpotify },
|
components: { CoverArtwork, ModalDialogAlbumSpotify },
|
||||||
props: { items: { required: true, type: Object } },
|
props: { items: { required: true, type: Object } },
|
||||||
|
|
||||||
data() {
|
setup() {
|
||||||
return { selected_item: {}, show_details_modal: false }
|
return { settingsStore: useSettingsStore() }
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
data() {
|
||||||
show_artwork() {
|
return { selected_item: {}, show_details_modal: false }
|
||||||
return this.$store.getters.setting(
|
|
||||||
'webinterface',
|
|
||||||
'show_cover_artwork_in_album_lists'
|
|
||||||
).value
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<h1
|
<h1
|
||||||
class="title is-6"
|
class="title is-6"
|
||||||
:class="{
|
:class="{
|
||||||
'has-text-primary': item.id === state.item_id,
|
'has-text-primary': item.id === player.item_id,
|
||||||
'has-text-grey-light': !is_next
|
'has-text-grey-light': !is_next
|
||||||
}"
|
}"
|
||||||
v-text="item.title"
|
v-text="item.title"
|
||||||
|
@ -22,18 +22,18 @@
|
||||||
<h2
|
<h2
|
||||||
class="subtitle is-7 has-text-weight-bold"
|
class="subtitle is-7 has-text-weight-bold"
|
||||||
:class="{
|
:class="{
|
||||||
'has-text-primary': item.id === state.item_id,
|
'has-text-primary': item.id === player.item_id,
|
||||||
'has-text-grey-light': !is_next,
|
'has-text-grey-light': !is_next,
|
||||||
'has-text-grey': is_next && item.id !== state.item_id
|
'has-text-grey': is_next && item.id !== player.item_id
|
||||||
}"
|
}"
|
||||||
v-text="item.artist"
|
v-text="item.artist"
|
||||||
/>
|
/>
|
||||||
<h2
|
<h2
|
||||||
class="subtitle is-7"
|
class="subtitle is-7"
|
||||||
:class="{
|
:class="{
|
||||||
'has-text-primary': item.id === state.item_id,
|
'has-text-primary': item.id === player.item_id,
|
||||||
'has-text-grey-light': !is_next,
|
'has-text-grey-light': !is_next,
|
||||||
'has-text-grey': is_next && item.id !== state.item_id
|
'has-text-grey': is_next && item.id !== player.item_id
|
||||||
}"
|
}"
|
||||||
v-text="item.album"
|
v-text="item.album"
|
||||||
/>
|
/>
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -57,12 +58,18 @@ export default {
|
||||||
show_only_next_items: Boolean
|
show_only_next_items: Boolean
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
playerStore: usePlayerStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
is_next() {
|
is_next() {
|
||||||
return this.current_position < 0 || this.position >= this.current_position
|
return this.current_position < 0 || this.position >= this.current_position
|
||||||
},
|
},
|
||||||
state() {
|
player() {
|
||||||
return this.$store.state.player
|
return this.playerStore
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<h2 v-if="!item.is_playable" class="subtitle is-7">
|
<h2 v-if="!item.is_playable" class="subtitle is-7">
|
||||||
(<span v-text="$t('list.spotify.not-playable-track')" />
|
(<span v-text="$t('list.spotify.not-playable-track')" />
|
||||||
<span
|
<span
|
||||||
v-if="item.restrictions && item.restrictions.reason"
|
v-if="item.restrictions?.reason"
|
||||||
v-text="
|
v-text="
|
||||||
$t('list.spotify.restriction-reason', {
|
$t('list.spotify.restriction-reason', {
|
||||||
reason: item.restrictions.reason
|
reason: item.restrictions.reason
|
||||||
|
|
|
@ -31,8 +31,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useLyricsStore } from '@/stores/lyrics'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LyricsPane',
|
name: 'LyricsPane',
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { lyricsStore: useLyricsStore(), playerStore: usePlayerStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
/*
|
/*
|
||||||
* Non reactive. Used as a cache to speed up the finding of lyrics
|
* Non reactive. Used as a cache to speed up the finding of lyrics
|
||||||
|
@ -46,14 +54,15 @@ export default {
|
||||||
autoScrolling: true
|
autoScrolling: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
is_playing() {
|
is_playing() {
|
||||||
return this.player.state === 'play'
|
return this.playerStore.state === 'play'
|
||||||
},
|
},
|
||||||
lyrics() {
|
lyrics() {
|
||||||
const raw = this.$store.state.lyrics.content
|
const raw = this.lyricsStore.content
|
||||||
const parsed = []
|
const parsed = []
|
||||||
if (raw) {
|
if (raw.length > 0) {
|
||||||
// Parse the lyrics
|
// Parse the lyrics
|
||||||
const regex =
|
const regex =
|
||||||
/\[(?<minutes>\d+):(?<seconds>\d+)(?:\.(?<hundredths>\d+))?\] ?(?<text>.*)/u
|
/\[(?<minutes>\d+):(?<seconds>\d+)(?:\.(?<hundredths>\d+))?\] ?(?<text>.*)/u
|
||||||
|
@ -82,14 +91,11 @@ export default {
|
||||||
}
|
}
|
||||||
return parsed
|
return parsed
|
||||||
},
|
},
|
||||||
player() {
|
|
||||||
return this.$store.state.player
|
|
||||||
},
|
|
||||||
verse_index() {
|
verse_index() {
|
||||||
if (this.lyrics.length && this.lyrics[0].time) {
|
if (this.lyrics.length && this.lyrics[0].time) {
|
||||||
const currentTime = this.player.item_progress_ms / 1000,
|
const currentTime = this.playerStore.item_progress_ms / 1000,
|
||||||
la = this.lyrics,
|
la = this.lyrics,
|
||||||
trackChanged = this.player.item_id !== this.lastItemId,
|
trackChanged = this.playerStore.item_id !== this.lastItemId,
|
||||||
trackSeeked =
|
trackSeeked =
|
||||||
this.lastIndex >= 0 &&
|
this.lastIndex >= 0 &&
|
||||||
this.lastIndex < la.length &&
|
this.lastIndex < la.length &&
|
||||||
|
@ -149,10 +155,10 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
reset_scrolling() {
|
reset_scrolling() {
|
||||||
// Scroll to the start of the lyrics in all cases
|
// Scroll to the start of the lyrics in all cases
|
||||||
if (this.player.item_id !== this.lastItemId && this.$refs.lyrics) {
|
if (this.playerStore.item_id !== this.lastItemId && this.$refs.lyrics) {
|
||||||
this.$refs.lyrics.scrollTo(0, 0)
|
this.$refs.lyrics.scrollTo(0, 0)
|
||||||
}
|
}
|
||||||
this.lastItemId = this.player.item_id
|
this.lastItemId = this.playerStore.item_id
|
||||||
this.lastIndex = -1
|
this.lastIndex = -1
|
||||||
},
|
},
|
||||||
scroll_to_verse() {
|
scroll_to_verse() {
|
||||||
|
|
|
@ -136,6 +136,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -143,6 +144,10 @@ export default {
|
||||||
props: { item: { required: true, type: Object }, show: Boolean },
|
props: { item: { required: true, type: Object }, show: Boolean },
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
spotify_track: {}
|
spotify_track: {}
|
||||||
|
@ -151,9 +156,9 @@ export default {
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
item() {
|
item() {
|
||||||
if (this.item && this.item.data_kind === 'spotify') {
|
if (this.item?.data_kind === 'spotify') {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(this.$store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
|
||||||
spotifyApi
|
spotifyApi
|
||||||
.getTrack(this.item.path.slice(this.item.path.lastIndexOf(':') + 1))
|
.getTrack(this.item.path.slice(this.item.path.lastIndexOf(':') + 1))
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useRemotesStore } from '@/stores/remotes'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -60,6 +61,10 @@ export default {
|
||||||
props: { show: Boolean },
|
props: { show: Boolean },
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { remoteStore: useRemotesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pairing_req: { pin: '' }
|
pairing_req: { pin: '' }
|
||||||
|
@ -68,7 +73,7 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
pairing() {
|
pairing() {
|
||||||
return this.$store.state.pairing
|
return this.remoteStore.pairing
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -179,6 +180,10 @@ export default {
|
||||||
props: { item: { required: true, type: Object }, show: Boolean },
|
props: { item: { required: true, type: Object }, show: Boolean },
|
||||||
emits: ['close', 'play-count-changed'],
|
emits: ['close', 'play-count-changed'],
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
spotify_track: {}
|
spotify_track: {}
|
||||||
|
@ -193,7 +198,7 @@ export default {
|
||||||
this.item.media_kind !== 'podcast'
|
this.item.media_kind !== 'podcast'
|
||||||
) {
|
) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(this.$store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
|
||||||
spotifyApi
|
spotifyApi
|
||||||
.getTrack(this.item.path.slice(this.item.path.lastIndexOf(':') + 1))
|
.getTrack(this.item.path.slice(this.item.path.lastIndexOf(':') + 1))
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
|
@ -48,8 +48,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ModalDialog from '@/components/ModalDialog.vue'
|
import ModalDialog from '@/components/ModalDialog.vue'
|
||||||
|
import { useLibraryStore } from '@/stores/library'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -58,6 +59,13 @@ export default {
|
||||||
props: { show: Boolean },
|
props: { show: Boolean },
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
libraryStore: useLibraryStore(),
|
||||||
|
servicesStore: useServicesStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
rescan_metadata: false
|
rescan_metadata: false
|
||||||
|
@ -66,23 +74,23 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
library() {
|
library() {
|
||||||
return this.$store.state.library
|
return this.libraryStore.$state
|
||||||
},
|
},
|
||||||
|
|
||||||
rss() {
|
rss() {
|
||||||
return this.$store.state.rss_count
|
return this.libraryStore.rss
|
||||||
},
|
},
|
||||||
|
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
},
|
},
|
||||||
|
|
||||||
update_dialog_scan_kind: {
|
update_dialog_scan_kind: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.update_dialog_scan_kind
|
return this.library.update_dialog_scan_kind
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.UPDATE_DIALOG_SCAN_KIND, value)
|
this.library.update_dialog_scan_kind = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -113,12 +113,12 @@
|
||||||
class="is-expanded is-clipped is-size-7"
|
class="is-expanded is-clipped is-size-7"
|
||||||
>
|
>
|
||||||
<div class="fd-is-text-clipped">
|
<div class="fd-is-text-clipped">
|
||||||
<strong v-text="now_playing.title" />
|
<strong v-text="current.title" />
|
||||||
<br />
|
<br />
|
||||||
<span v-text="now_playing.artist" />
|
<span v-text="current.artist" />
|
||||||
<span
|
<span
|
||||||
v-if="now_playing.album"
|
v-if="current.album"
|
||||||
v-text="$t('navigation.now-playing', { album: now_playing.album })"
|
v-text="$t('navigation.now-playing', { album: current.album })"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
|
@ -255,7 +255,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ControlSlider from '@/components/ControlSlider.vue'
|
import ControlSlider from '@/components/ControlSlider.vue'
|
||||||
import NavbarItemLink from '@/components/NavbarItemLink.vue'
|
import NavbarItemLink from '@/components/NavbarItemLink.vue'
|
||||||
import NavbarItemOutput from '@/components/NavbarItemOutput.vue'
|
import NavbarItemOutput from '@/components/NavbarItemOutput.vue'
|
||||||
|
@ -270,6 +269,11 @@ import PlayerButtonSeekForward from '@/components/PlayerButtonSeekForward.vue'
|
||||||
import PlayerButtonShuffle from '@/components/PlayerButtonShuffle.vue'
|
import PlayerButtonShuffle from '@/components/PlayerButtonShuffle.vue'
|
||||||
import audio from '@/lib/Audio'
|
import audio from '@/lib/Audio'
|
||||||
import { mdiCancel } from '@mdi/js'
|
import { mdiCancel } from '@mdi/js'
|
||||||
|
import { useNotificationsStore } from '@/stores/notifications'
|
||||||
|
import { useOutputsStore } from '@/stores/outputs'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -289,6 +293,16 @@ export default {
|
||||||
PlayerButtonShuffle
|
PlayerButtonShuffle
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
notificationsStore: useNotificationsStore(),
|
||||||
|
outputsStore: useOutputsStore(),
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore(),
|
||||||
|
uiStore: useUIStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
cursor: mdiCancel,
|
cursor: mdiCancel,
|
||||||
|
@ -302,33 +316,30 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
config() {
|
|
||||||
return this.$store.state.config
|
|
||||||
},
|
|
||||||
is_now_playing_page() {
|
is_now_playing_page() {
|
||||||
return this.$route.name === 'now-playing'
|
return this.$route.name === 'now-playing'
|
||||||
},
|
},
|
||||||
now_playing() {
|
current() {
|
||||||
return this.$store.getters.now_playing
|
return this.queueStore.current
|
||||||
},
|
},
|
||||||
outputs() {
|
outputs() {
|
||||||
return this.$store.state.outputs
|
return this.outputsStore.outputs
|
||||||
},
|
},
|
||||||
player() {
|
player() {
|
||||||
return this.$store.state.player
|
return this.playerStore
|
||||||
},
|
},
|
||||||
show_player_menu: {
|
show_player_menu: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.show_player_menu
|
return this.uiStore.show_player_menu
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.SHOW_PLAYER_MENU, value)
|
this.uiStore.show_player_menu = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'$store.state.player.volume'() {
|
'playerStore.volume'() {
|
||||||
if (this.player.volume > 0) {
|
if (this.player.volume > 0) {
|
||||||
this.old_volume = this.player.volume
|
this.old_volume = this.player.volume
|
||||||
}
|
}
|
||||||
|
@ -383,7 +394,7 @@ export default {
|
||||||
})
|
})
|
||||||
a.addEventListener('error', () => {
|
a.addEventListener('error', () => {
|
||||||
this.closeAudio()
|
this.closeAudio()
|
||||||
this.$store.dispatch('add_notification', {
|
this.notificationsStore.add({
|
||||||
text: this.$t('navigation.stream-error'),
|
text: this.$t('navigation.stream-error'),
|
||||||
type: 'danger'
|
type: 'danger'
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
import { useUIStore } from '@/stores/ui'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NavbarItemLink',
|
name: 'NavbarItemLink',
|
||||||
|
@ -13,6 +13,10 @@ export default {
|
||||||
to: { required: true, type: Object }
|
to: { required: true, type: Object }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
href() {
|
href() {
|
||||||
return this.$router.resolve(this.to).href
|
return this.$router.resolve(this.to).href
|
||||||
|
@ -21,11 +25,11 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
open() {
|
open() {
|
||||||
if (this.$store.state.show_burger_menu) {
|
if (this.uiStore.show_burger_menu) {
|
||||||
this.$store.commit(types.SHOW_BURGER_MENU, false)
|
this.uiStore.show_burger_menu = false
|
||||||
}
|
}
|
||||||
if (this.$store.state.show_player_menu) {
|
if (this.uiStore.show_player_menu) {
|
||||||
this.$store.commit(types.SHOW_PLAYER_MENU, false)
|
this.uiStore.show_player_menu = false
|
||||||
}
|
}
|
||||||
this.$router.push(this.to)
|
this.$router.push(this.to)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,25 +6,46 @@
|
||||||
aria-label="main navigation"
|
aria-label="main navigation"
|
||||||
>
|
>
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<navbar-item-link v-if="show_playlists" :to="{ name: 'playlists' }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_playlists"
|
||||||
|
:to="{ name: 'playlists' }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="music-box-multiple" size="16" />
|
<mdicon class="icon" name="music-box-multiple" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link v-if="show_music" :to="{ name: 'music' }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_music"
|
||||||
|
:to="{ name: 'music' }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="music" size="16" />
|
<mdicon class="icon" name="music" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link v-if="show_podcasts" :to="{ name: 'podcasts' }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_podcasts"
|
||||||
|
:to="{ name: 'podcasts' }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="microphone" size="16" />
|
<mdicon class="icon" name="microphone" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link v-if="show_audiobooks" :to="{ name: 'audiobooks' }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_audiobooks"
|
||||||
|
:to="{ name: 'audiobooks' }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="book-open-variant" size="16" />
|
<mdicon class="icon" name="book-open-variant" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link v-if="show_radio" :to="{ name: 'radio' }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_radio"
|
||||||
|
:to="{ name: 'radio' }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="radio" size="16" />
|
<mdicon class="icon" name="radio" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link v-if="show_files" :to="{ name: 'files' }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_files"
|
||||||
|
:to="{ name: 'files' }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="folder-open" size="16" />
|
<mdicon class="icon" name="folder-open" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link v-if="show_search" :to="{ name: search_name }">
|
<navbar-item-link
|
||||||
|
v-if="settingsStore.show_menu_item_search"
|
||||||
|
:to="{ name: searchStore.search_source }"
|
||||||
|
>
|
||||||
<mdicon class="icon" name="magnify" size="16" />
|
<mdicon class="icon" name="magnify" size="16" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<div
|
<div
|
||||||
|
@ -89,7 +110,7 @@
|
||||||
<mdicon class="icon" name="folder-open" size="16" />
|
<mdicon class="icon" name="folder-open" size="16" />
|
||||||
<b v-text="$t('navigation.files')" />
|
<b v-text="$t('navigation.files')" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
<navbar-item-link :to="{ name: search_name }">
|
<navbar-item-link :to="{ name: searchStore.search_source }">
|
||||||
<mdicon class="icon" name="magnify" size="16" />
|
<mdicon class="icon" name="magnify" size="16" />
|
||||||
<b v-text="$t('navigation.search')" />
|
<b v-text="$t('navigation.search')" />
|
||||||
</navbar-item-link>
|
</navbar-item-link>
|
||||||
|
@ -118,13 +139,25 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import NavbarItemLink from '@/components/NavbarItemLink.vue'
|
import NavbarItemLink from '@/components/NavbarItemLink.vue'
|
||||||
|
import { useSearchStore } from '@/stores/search'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NavbarTop',
|
name: 'NavbarTop',
|
||||||
components: { NavbarItemLink },
|
components: { NavbarItemLink },
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
searchStore: useSearchStore(),
|
||||||
|
servicesStore: useServicesStore(),
|
||||||
|
settingsStore: useSettingsStore(),
|
||||||
|
uiStore: useUIStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
show_settings_menu: false
|
show_settings_menu: false
|
||||||
|
@ -132,71 +165,27 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
search_name: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.search_source
|
|
||||||
}
|
|
||||||
},
|
|
||||||
show_audiobooks() {
|
|
||||||
return this.$store.getters.setting(
|
|
||||||
'webinterface',
|
|
||||||
'show_menu_item_audiobooks'
|
|
||||||
).value
|
|
||||||
},
|
|
||||||
show_burger_menu: {
|
show_burger_menu: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.show_burger_menu
|
return this.uiStore.show_burger_menu
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.SHOW_BURGER_MENU, value)
|
this.uiStore.show_burger_menu = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show_files() {
|
|
||||||
return this.$store.getters.setting('webinterface', 'show_menu_item_files')
|
|
||||||
.value
|
|
||||||
},
|
|
||||||
show_music() {
|
|
||||||
return this.$store.getters.setting('webinterface', 'show_menu_item_music')
|
|
||||||
.value
|
|
||||||
},
|
|
||||||
show_player_menu() {
|
|
||||||
return this.$store.state.show_player_menu
|
|
||||||
},
|
|
||||||
show_playlists() {
|
|
||||||
return this.$store.getters.setting(
|
|
||||||
'webinterface',
|
|
||||||
'show_menu_item_playlists'
|
|
||||||
).value
|
|
||||||
},
|
|
||||||
show_podcasts() {
|
|
||||||
return this.$store.getters.setting(
|
|
||||||
'webinterface',
|
|
||||||
'show_menu_item_podcasts'
|
|
||||||
).value
|
|
||||||
},
|
|
||||||
show_radio() {
|
|
||||||
return this.$store.getters.setting('webinterface', 'show_menu_item_radio')
|
|
||||||
.value
|
|
||||||
},
|
|
||||||
show_search() {
|
|
||||||
return this.$store.getters.setting(
|
|
||||||
'webinterface',
|
|
||||||
'show_menu_item_search'
|
|
||||||
).value
|
|
||||||
},
|
|
||||||
show_update_dialog: {
|
show_update_dialog: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.show_update_dialog
|
return this.uiStore.show_update_dialog
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.SHOW_UPDATE_DIALOG, value)
|
this.uiStore.show_update_dialog = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
},
|
},
|
||||||
zindex() {
|
zindex() {
|
||||||
if (this.show_player_menu) {
|
if (this.uiStore.show_player_menu) {
|
||||||
return 'z-index: 21'
|
return 'z-index: 21'
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
|
|
|
@ -17,18 +17,26 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useNotificationsStore } from '@/stores/notifications'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NotificationList',
|
name: 'NotificationList',
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
notificationsStore: useNotificationsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
notifications() {
|
notifications() {
|
||||||
return this.$store.state.notifications.list
|
return this.notificationsStore.list
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
remove(notification) {
|
remove(notification) {
|
||||||
this.$store.dispatch('delete_notification', notification)
|
this.notificationsStore.remove(notification)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,9 +19,15 @@ export default {
|
||||||
icon_size: { default: 16, type: Number }
|
icon_size: { default: 16, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
playerStore: usePlayerStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
is_consume() {
|
is_consume() {
|
||||||
return this.$store.state.player.consume
|
return this.playerStore.consume
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -10,24 +10,32 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useLyricsStore } from '@/stores/lyrics'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PlayerButtonLyrics',
|
name: 'PlayerButtonLyrics',
|
||||||
props: {
|
props: {
|
||||||
icon_size: { default: 16, type: Number }
|
icon_size: { default: 16, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
lyricsStore: useLyricsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
icon_name() {
|
icon_name() {
|
||||||
return this.is_active ? 'script-text-play' : 'script-text-outline'
|
return this.is_active ? 'script-text-play' : 'script-text-outline'
|
||||||
},
|
},
|
||||||
is_active() {
|
is_active() {
|
||||||
return this.$store.state.lyrics.pane
|
return this.lyricsStore.pane
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
toggle_lyrics() {
|
toggle_lyrics() {
|
||||||
this.$store.state.lyrics.pane = !this.$store.state.lyrics.pane
|
this.lyricsStore.pane = !this.lyricsStore.pane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -19,7 +20,7 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
disabled() {
|
disabled() {
|
||||||
return !this.$store.state.queue || this.$store.state.queue.count <= 0
|
return useQueueStore()?.count <= 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useNotificationsStore } from '@/stores/notifications'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,9 +21,17 @@ export default {
|
||||||
show_disabled_message: Boolean
|
show_disabled_message: Boolean
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
notificationsStore: useNotificationsStore(),
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
disabled() {
|
disabled() {
|
||||||
return !this.$store.state.queue || this.$store.state.queue.count <= 0
|
return this.queueStore?.count <= 0
|
||||||
},
|
},
|
||||||
icon_name() {
|
icon_name() {
|
||||||
if (!this.is_playing) {
|
if (!this.is_playing) {
|
||||||
|
@ -31,13 +42,11 @@ export default {
|
||||||
return 'stop'
|
return 'stop'
|
||||||
},
|
},
|
||||||
is_pause_allowed() {
|
is_pause_allowed() {
|
||||||
return (
|
const { current } = this.queueStore
|
||||||
this.$store.getters.now_playing &&
|
return current && current.data_kind !== 'pipe'
|
||||||
this.$store.getters.now_playing.data_kind !== 'pipe'
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
is_playing() {
|
is_playing() {
|
||||||
return this.$store.state.player.state === 'play'
|
return this.playerStore.state === 'play'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -45,7 +54,7 @@ export default {
|
||||||
toggle_play_pause() {
|
toggle_play_pause() {
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
if (this.show_disabled_message) {
|
if (this.show_disabled_message) {
|
||||||
this.$store.dispatch('add_notification', {
|
this.notificationsStore.add({
|
||||||
text: this.$t('server.empty-queue'),
|
text: this.$t('server.empty-queue'),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
topic: 'connection',
|
topic: 'connection',
|
||||||
|
@ -54,7 +63,6 @@ export default {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.is_playing && this.is_pause_allowed) {
|
if (this.is_playing && this.is_pause_allowed) {
|
||||||
webapi.player_pause()
|
webapi.player_pause()
|
||||||
} else if (this.is_playing && !this.is_pause_allowed) {
|
} else if (this.is_playing && !this.is_pause_allowed) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -17,9 +18,15 @@ export default {
|
||||||
icon_size: { default: 16, type: Number }
|
icon_size: { default: 16, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
queueStore: useQueueStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
disabled() {
|
disabled() {
|
||||||
return !this.$store.state.queue || this.$store.state.queue.count <= 0
|
return this.queueStore.count <= 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -28,7 +35,6 @@ export default {
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
webapi.player_previous()
|
webapi.player_previous()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,6 +19,12 @@ export default {
|
||||||
icon_size: { default: 16, type: Number }
|
icon_size: { default: 16, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
playerStore: usePlayerStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
icon_name() {
|
icon_name() {
|
||||||
if (this.is_repeat_all) {
|
if (this.is_repeat_all) {
|
||||||
|
@ -28,13 +35,13 @@ export default {
|
||||||
return 'repeat-off'
|
return 'repeat-off'
|
||||||
},
|
},
|
||||||
is_repeat_all() {
|
is_repeat_all() {
|
||||||
return this.$store.state.player.repeat === 'all'
|
return this.playerStore.repeat === 'all'
|
||||||
},
|
},
|
||||||
is_repeat_off() {
|
is_repeat_off() {
|
||||||
return !this.is_repeat_all && !this.is_repeat_single
|
return !this.is_repeat_all && !this.is_repeat_single
|
||||||
},
|
},
|
||||||
is_repeat_single() {
|
is_repeat_single() {
|
||||||
return this.$store.state.player.repeat === 'single'
|
return this.playerStore.repeat === 'single'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,23 +20,32 @@ export default {
|
||||||
seek_ms: { required: true, type: Number }
|
seek_ms: { required: true, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
disabled() {
|
disabled() {
|
||||||
return (
|
return (
|
||||||
!this.$store.state.queue ||
|
this.queueStore?.count <= 0 ||
|
||||||
this.$store.state.queue.count <= 0 ||
|
|
||||||
this.is_stopped ||
|
this.is_stopped ||
|
||||||
this.now_playing.data_kind === 'pipe'
|
this.current.data_kind === 'pipe'
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
is_stopped() {
|
is_stopped() {
|
||||||
return this.$store.state.player.state === 'stop'
|
return this.player.state === 'stop'
|
||||||
},
|
},
|
||||||
now_playing() {
|
current() {
|
||||||
return this.$store.getters.now_playing
|
return this.queueStore.current
|
||||||
|
},
|
||||||
|
player() {
|
||||||
|
return this.playerStore
|
||||||
},
|
},
|
||||||
visible() {
|
visible() {
|
||||||
return ['podcast', 'audiobook'].includes(this.now_playing.media_kind)
|
return ['podcast', 'audiobook'].includes(this.current.media_kind)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,23 +20,32 @@ export default {
|
||||||
seek_ms: { required: true, type: Number }
|
seek_ms: { required: true, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
disabled() {
|
disabled() {
|
||||||
return (
|
return (
|
||||||
!this.$store.state.queue ||
|
this.queueStore?.count <= 0 ||
|
||||||
this.$store.state.queue.count <= 0 ||
|
|
||||||
this.is_stopped ||
|
this.is_stopped ||
|
||||||
this.now_playing.data_kind === 'pipe'
|
this.current.data_kind === 'pipe'
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
is_stopped() {
|
is_stopped() {
|
||||||
return this.$store.state.player.state === 'stop'
|
return this.player.state === 'stop'
|
||||||
},
|
},
|
||||||
now_playing() {
|
current() {
|
||||||
return this.$store.getters.now_playing
|
return this.queueStore.current
|
||||||
|
},
|
||||||
|
player() {
|
||||||
|
return this.playerStore
|
||||||
},
|
},
|
||||||
visible() {
|
visible() {
|
||||||
return ['podcast', 'audiobook'].includes(this.now_playing.media_kind)
|
return ['podcast', 'audiobook'].includes(this.current.media_kind)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -19,6 +20,12 @@ export default {
|
||||||
icon_size: { default: 16, type: Number }
|
icon_size: { default: 16, type: Number }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
playerStore: usePlayerStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
icon_name() {
|
icon_name() {
|
||||||
if (this.is_shuffle) {
|
if (this.is_shuffle) {
|
||||||
|
@ -27,7 +34,7 @@ export default {
|
||||||
return 'shuffle-disabled'
|
return 'shuffle-disabled'
|
||||||
},
|
},
|
||||||
is_shuffle() {
|
is_shuffle() {
|
||||||
return this.$store.state.player.shuffle
|
return this.playerStore.shuffle
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -31,6 +32,12 @@ export default {
|
||||||
name: { required: true, type: String }
|
name: { required: true, type: String }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
settingsStore: useSettingsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
statusUpdate: '',
|
statusUpdate: '',
|
||||||
|
@ -55,7 +62,7 @@ export default {
|
||||||
return this.statusUpdate === 'success'
|
return this.statusUpdate === 'success'
|
||||||
},
|
},
|
||||||
setting() {
|
setting() {
|
||||||
const setting = this.$store.getters.setting(this.category, this.name)
|
const setting = this.settingsStore.setting(this.category, this.name)
|
||||||
if (!setting) {
|
if (!setting) {
|
||||||
return {
|
return {
|
||||||
category: this.category,
|
category: this.category,
|
||||||
|
@ -84,7 +91,7 @@ export default {
|
||||||
webapi
|
webapi
|
||||||
.settings_update(this.category, setting)
|
.settings_update(this.category, setting)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.dispatch('update_setting', setting)
|
this.settingsStore.update(setting)
|
||||||
this.statusUpdate = 'success'
|
this.statusUpdate = 'success'
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -39,6 +40,12 @@ export default {
|
||||||
placeholder: { default: '', type: String }
|
placeholder: { default: '', type: String }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
settingsStore: useSettingsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
statusUpdate: '',
|
statusUpdate: '',
|
||||||
|
@ -63,7 +70,7 @@ export default {
|
||||||
return this.statusUpdate === 'success'
|
return this.statusUpdate === 'success'
|
||||||
},
|
},
|
||||||
setting() {
|
setting() {
|
||||||
return this.$store.getters.setting(this.category, this.name)
|
return this.settingsStore.setting(this.category, this.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -95,7 +102,7 @@ export default {
|
||||||
webapi
|
webapi
|
||||||
.settings_update(this.category, setting)
|
.settings_update(this.category, setting)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.dispatch('update_setting', setting)
|
this.settingsStore.update(setting)
|
||||||
this.statusUpdate = 'success'
|
this.statusUpdate = 'success'
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -38,6 +39,12 @@ export default {
|
||||||
placeholder: { default: '', type: String }
|
placeholder: { default: '', type: String }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
settingsStore: useSettingsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
statusUpdate: '',
|
statusUpdate: '',
|
||||||
|
@ -62,7 +69,7 @@ export default {
|
||||||
return this.statusUpdate === 'success'
|
return this.statusUpdate === 'success'
|
||||||
},
|
},
|
||||||
setting() {
|
setting() {
|
||||||
return this.$store.getters.setting(this.category, this.name)
|
return this.settingsStore.setting(this.category, this.name)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -96,7 +103,7 @@ export default {
|
||||||
webapi
|
webapi
|
||||||
.settings_update(this.category, setting)
|
.settings_update(this.category, setting)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.dispatch('update_setting', setting)
|
this.settingsStore.update(setting)
|
||||||
this.statusUpdate = 'success'
|
this.statusUpdate = 'success'
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
|
@ -113,12 +113,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TabsMusic',
|
name: 'TabsMusic',
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,13 +34,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TabsSearch',
|
name: 'TabsSearch',
|
||||||
emits: ['search-library', 'search-spotify'],
|
emits: ['search-library', 'search-spotify'],
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
servicesStore: useServicesStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@ import VueClickAway from 'vue3-click-away'
|
||||||
import VueLazyLoad from 'vue3-lazyload'
|
import VueLazyLoad from 'vue3-lazyload'
|
||||||
import VueProgressBar from '@aacassandra/vue3-progressbar'
|
import VueProgressBar from '@aacassandra/vue3-progressbar'
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
import { filters } from './filter'
|
import { filters } from './filter'
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
import { icons } from './icons'
|
import { icons } from './icons'
|
||||||
import mdiVue from 'mdi-vue/v3'
|
import mdiVue from 'mdi-vue/v3'
|
||||||
import { router } from './router'
|
import { router } from './router'
|
||||||
import store from './store'
|
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
.use(store)
|
.use(createPinia())
|
||||||
.use(router)
|
.use(router)
|
||||||
.use(VueProgressBar)
|
.use(VueProgressBar)
|
||||||
.use(VueClickAway)
|
.use(VueClickAway)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="columns is-centered">
|
<div class="columns is-centered">
|
||||||
<div class="column is-four-fifths has-text-centered-mobile">
|
<div class="column is-four-fifths has-text-centered-mobile">
|
||||||
<h1 class="title is-4" v-text="config.library_name" />
|
<h1 class="title is-4" v-text="configuration.library_name" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -130,13 +130,15 @@
|
||||||
<div class="content has-text-centered-mobile">
|
<div class="content has-text-centered-mobile">
|
||||||
<p
|
<p
|
||||||
class="is-size-7"
|
class="is-size-7"
|
||||||
v-text="$t('page.about.version', { version: config.version })"
|
v-text="
|
||||||
|
$t('page.about.version', { version: configuration.version })
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<p
|
<p
|
||||||
class="is-size-7"
|
class="is-size-7"
|
||||||
v-text="
|
v-text="
|
||||||
$t('page.about.compiled-with', {
|
$t('page.about.compiled-with', {
|
||||||
options: config.buildoptions.join(', ')
|
options: configuration.buildoptions.join(', ')
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
|
@ -176,23 +178,33 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
import { useConfigurationStore } from '@/stores/configuration'
|
||||||
|
import { useLibraryStore } from '@/stores/library'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageAbout',
|
name: 'PageAbout',
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
configurationStore: useConfigurationStore(),
|
||||||
|
libraryStore: useLibraryStore(),
|
||||||
|
uiStore: useUIStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
config() {
|
configuration() {
|
||||||
return this.$store.state.config
|
return this.configurationStore.$state
|
||||||
},
|
},
|
||||||
library() {
|
library() {
|
||||||
return this.$store.state.library
|
return this.libraryStore.$state
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
showUpdateDialog() {
|
showUpdateDialog() {
|
||||||
this.$store.commit(types.SHOW_UPDATE_DIALOG, true)
|
this.uiStore.show_update_dialog = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,15 +56,15 @@ import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
||||||
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import store from '@/store'
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load(to) {
|
load(to) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(useServicesStore().spotify.webapi_token)
|
||||||
return spotifyApi.getAlbum(to.params.id, {
|
return spotifyApi.getAlbum(to.params.id, {
|
||||||
market: store.state.spotify.webapi_country
|
market: useServicesStore().spotify.webapi_country
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -88,6 +88,12 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
servicesStore: useServicesStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
album: { artists: [{}], tracks: {} },
|
album: { artists: [{}], tracks: {} },
|
||||||
|
|
|
@ -63,13 +63,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ControlDropdown from '@/components/ControlDropdown.vue'
|
import ControlDropdown from '@/components/ControlDropdown.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListAlbums from '@/components/ListAlbums.vue'
|
import ListAlbums from '@/components/ListAlbums.vue'
|
||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -98,6 +99,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { uiStore: useUIStore(), servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums_list: new GroupedList(),
|
albums_list: new GroupedList(),
|
||||||
|
@ -162,30 +167,30 @@ export default {
|
||||||
},
|
},
|
||||||
hide_singles: {
|
hide_singles: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.hide_singles
|
return this.uiStore.hide_singles
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.HIDE_SINGLES, value)
|
this.uiStore.hide_singles = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hide_spotify: {
|
hide_spotify: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.hide_spotify
|
return this.uiStore.hide_spotify
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.HIDE_SPOTIFY, value)
|
this.uiStore.hide_spotify = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selected_grouping_id: {
|
selected_grouping_id: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.albums_sort
|
return this.uiStore.albums_sort
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.ALBUMS_SORT, value)
|
this.uiStore.albums_sort = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,12 +71,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ControlDropdown from '@/components/ControlDropdown.vue'
|
import ControlDropdown from '@/components/ControlDropdown.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import ListAlbums from '@/components/ListAlbums.vue'
|
import ListAlbums from '@/components/ListAlbums.vue'
|
||||||
import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -108,6 +109,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore(), uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums_list: new GroupedList(),
|
albums_list: new GroupedList(),
|
||||||
|
@ -140,22 +145,22 @@ export default {
|
||||||
},
|
},
|
||||||
hide_spotify: {
|
hide_spotify: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.hide_spotify
|
return this.uiStore.hide_spotify
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.HIDE_SPOTIFY, value)
|
this.uiStore.hide_spotify = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selected_grouping_id: {
|
selected_grouping_id: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.artist_albums_sort
|
return this.uiStore.artist_albums_sort
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.ARTIST_ALBUMS_SORT, value)
|
this.uiStore.artist_albums_sort = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
},
|
},
|
||||||
track_count() {
|
track_count() {
|
||||||
// The count of tracks is incorrect when albums have Spotify tracks.
|
// The count of tracks is incorrect when albums have Spotify tracks.
|
||||||
|
|
|
@ -52,7 +52,7 @@ import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
||||||
import ModalDialogArtistSpotify from '@/components/ModalDialogArtistSpotify.vue'
|
import ModalDialogArtistSpotify from '@/components/ModalDialogArtistSpotify.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
||||||
import store from '@/store'
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const PAGE_SIZE = 50
|
const PAGE_SIZE = 50
|
||||||
|
@ -60,13 +60,13 @@ const PAGE_SIZE = 50
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load(to) {
|
load(to) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(useServicesStore().spotify.webapi_token)
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
spotifyApi.getArtist(to.params.id),
|
spotifyApi.getArtist(to.params.id),
|
||||||
spotifyApi.getArtistAlbums(to.params.id, {
|
spotifyApi.getArtistAlbums(to.params.id, {
|
||||||
include_groups: 'album,single',
|
include_groups: 'album,single',
|
||||||
limit: PAGE_SIZE,
|
limit: PAGE_SIZE,
|
||||||
market: store.state.spotify.webapi_country,
|
market: useServicesStore().spotify.webapi_country,
|
||||||
offset: 0
|
offset: 0
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
@ -96,6 +96,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: [],
|
albums: [],
|
||||||
|
@ -114,7 +118,7 @@ export default {
|
||||||
},
|
},
|
||||||
load_next({ loaded }) {
|
load_next({ loaded }) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(this.$store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
|
||||||
spotifyApi
|
spotifyApi
|
||||||
.getArtistAlbums(this.artist.id, {
|
.getArtistAlbums(this.artist.id, {
|
||||||
include_groups: 'album,single',
|
include_groups: 'album,single',
|
||||||
|
|
|
@ -72,13 +72,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ControlDropdown from '@/components/ControlDropdown.vue'
|
import ControlDropdown from '@/components/ControlDropdown.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -111,6 +112,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore(), uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
artist: {},
|
artist: {},
|
||||||
|
@ -144,22 +149,22 @@ export default {
|
||||||
},
|
},
|
||||||
hide_spotify: {
|
hide_spotify: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.hide_spotify
|
return this.uiStore.hide_spotify
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.HIDE_SPOTIFY, value)
|
this.uiStore.hide_spotify = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selected_grouping_id: {
|
selected_grouping_id: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.artist_tracks_sort
|
return this.uiStore.artist_tracks_sort
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.ARTIST_TRACKS_SORT, value)
|
this.uiStore.artist_tracks_sort = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
},
|
},
|
||||||
track_uris() {
|
track_uris() {
|
||||||
return this.tracks_list.items.map((item) => item.uri).join()
|
return this.tracks_list.items.map((item) => item.uri).join()
|
||||||
|
|
|
@ -63,13 +63,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ControlDropdown from '@/components/ControlDropdown.vue'
|
import ControlDropdown from '@/components/ControlDropdown.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListArtists from '@/components/ListArtists.vue'
|
import ListArtists from '@/components/ListArtists.vue'
|
||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -98,6 +99,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore(), uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
artists_list: new GroupedList(),
|
artists_list: new GroupedList(),
|
||||||
|
@ -134,30 +139,30 @@ export default {
|
||||||
},
|
},
|
||||||
hide_singles: {
|
hide_singles: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.hide_singles
|
return this.uiStore.hide_singles
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.HIDE_SINGLES, value)
|
this.uiStore.hide_singles = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hide_spotify: {
|
hide_spotify: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.hide_spotify
|
return this.uiStore.hide_spotify
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.HIDE_SPOTIFY, value)
|
this.uiStore.hide_spotify = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selected_grouping_id: {
|
selected_grouping_id: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.artists_sort
|
return this.uiStore.artists_sort
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.ARTISTS_SORT, value)
|
this.uiStore.artists_sort = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spotify_enabled() {
|
spotify_enabled() {
|
||||||
return this.$store.state.spotify.webapi_token_valid
|
return this.servicesStore.spotify.webapi_token_valid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,13 +60,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ControlDropdown from '@/components/ControlDropdown.vue'
|
import ControlDropdown from '@/components/ControlDropdown.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogComposer from '@/components/ModalDialogComposer.vue'
|
import ModalDialogComposer from '@/components/ModalDialogComposer.vue'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -99,6 +99,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
composer: {},
|
composer: {},
|
||||||
|
@ -128,10 +132,10 @@ export default {
|
||||||
},
|
},
|
||||||
selected_grouping_id: {
|
selected_grouping_id: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.composer_tracks_sort
|
return this.uiStore.composer_tracks_sort
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.COMPOSER_TRACKS_SORT, value)
|
this.uiStore.composer_tracks_sort = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tracks() {
|
tracks() {
|
||||||
|
|
|
@ -43,6 +43,7 @@ import ListDirectories from '@/components/ListDirectories.vue'
|
||||||
import ListPlaylists from '@/components/ListPlaylists.vue'
|
import ListPlaylists from '@/components/ListPlaylists.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogDirectory from '@/components/ModalDialogDirectory.vue'
|
import ModalDialogDirectory from '@/components/ModalDialogDirectory.vue'
|
||||||
|
import { useConfigurationStore } from '@/stores/configuration'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -57,8 +58,8 @@ const dataObject = {
|
||||||
vm.directories = response.data.directories.map((directory) =>
|
vm.directories = response.data.directories.map((directory) =>
|
||||||
vm.transform(directory.path)
|
vm.transform(directory.path)
|
||||||
)
|
)
|
||||||
} else if (vm.$store.state.config.directories) {
|
} else if (useConfigurationStore().directories) {
|
||||||
vm.directories = vm.$store.state.config.directories.map((path) =>
|
vm.directories = useConfigurationStore().directories.map((path) =>
|
||||||
vm.transform(path)
|
vm.transform(path)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,6 +97,12 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
configurationStore: useConfigurationStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
directories: [],
|
directories: [],
|
||||||
|
|
|
@ -55,13 +55,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ControlDropdown from '@/components/ControlDropdown.vue'
|
import ControlDropdown from '@/components/ControlDropdown.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogGenre from '@/components/ModalDialogGenre.vue'
|
import ModalDialogGenre from '@/components/ModalDialogGenre.vue'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -94,6 +94,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
genre: {},
|
genre: {},
|
||||||
|
@ -124,10 +128,10 @@ export default {
|
||||||
},
|
},
|
||||||
selected_grouping_id: {
|
selected_grouping_id: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.genre_tracks_sort
|
return this.uiStore.genre_tracks_sort
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit(types.GENRE_TRACKS_SORT, value)
|
this.uiStore.genre_tracks_sort = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tracks() {
|
tracks() {
|
||||||
|
|
|
@ -17,12 +17,12 @@ import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import ListAlbums from '@/components/ListAlbums.vue'
|
import ListAlbums from '@/components/ListAlbums.vue'
|
||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
import store from '@/store'
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load(to) {
|
load(to) {
|
||||||
const limit = store.getters.setting_recently_added_limit
|
const limit = useSettingsStore().recently_added_limit
|
||||||
return webapi.search({
|
return webapi.search({
|
||||||
expression:
|
expression:
|
||||||
'media_kind is music having track_count > 3 order by time_added desc',
|
'media_kind is music having track_count > 3 order by time_added desc',
|
||||||
|
@ -49,6 +49,12 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
settingsStore: useSettingsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: new GroupedList()
|
albums: new GroupedList()
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
:artist="track.artist"
|
:artist="track.artist"
|
||||||
:album="track.album"
|
:album="track.album"
|
||||||
class="is-clickable fd-has-shadow fd-cover-big-image"
|
class="is-clickable fd-has-shadow fd-cover-big-image"
|
||||||
:class="{ 'is-masked': lyrics_visible }"
|
:class="{ 'is-masked': lyricsStore.pane }"
|
||||||
@click="open_dialog(track)"
|
@click="open_dialog(track)"
|
||||||
/>
|
/>
|
||||||
<lyrics-pane v-if="lyrics_visible" />
|
<lyrics-pane v-if="lyricsStore.pane" />
|
||||||
<control-slider
|
<control-slider
|
||||||
v-model:value="track_progress"
|
v-model:value="track_progress"
|
||||||
class="mt-5"
|
class="mt-5"
|
||||||
|
@ -34,9 +34,9 @@
|
||||||
/>
|
/>
|
||||||
<p v-if="track.album" class="subtitle is-6" v-text="track.album" />
|
<p v-if="track.album" class="subtitle is-6" v-text="track.album" />
|
||||||
<p
|
<p
|
||||||
v-if="filepath"
|
v-if="settingsStore.show_filepath_now_playing"
|
||||||
class="subtitle is-6 has-text-grey"
|
class="subtitle is-6 has-text-grey"
|
||||||
v-text="filepath"
|
v-text="track.path"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,12 +55,15 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ControlSlider from '@/components/ControlSlider.vue'
|
import ControlSlider from '@/components/ControlSlider.vue'
|
||||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import LyricsPane from '@/components/LyricsPane.vue'
|
import LyricsPane from '@/components/LyricsPane.vue'
|
||||||
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem.vue'
|
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem.vue'
|
||||||
import { mdiCancel } from '@mdi/js'
|
import { mdiCancel } from '@mdi/js'
|
||||||
|
import { useLyricsStore } from '@/stores/lyrics'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const INTERVAL = 1000
|
const INTERVAL = 1000
|
||||||
|
@ -74,6 +77,15 @@ export default {
|
||||||
ModalDialogQueueItem
|
ModalDialogQueueItem
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
lyricsStore: useLyricsStore(),
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore(),
|
||||||
|
settingsStore: useSettingsStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
INTERVAL,
|
INTERVAL,
|
||||||
|
@ -87,11 +99,12 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
composer() {
|
composer() {
|
||||||
if (this.setting_show_composer_now_playing) {
|
if (this.settingsStore.show_composer_now_playing) {
|
||||||
|
const genres = this.settingsStore.show_composer_for_genre
|
||||||
if (
|
if (
|
||||||
!this.setting_show_composer_for_genre ||
|
!genres ||
|
||||||
(this.track.genre &&
|
(this.track.genre &&
|
||||||
this.setting_show_composer_for_genre
|
genres
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.split(',')
|
.split(',')
|
||||||
.findIndex(
|
.findIndex(
|
||||||
|
@ -104,42 +117,21 @@ export default {
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
filepath() {
|
|
||||||
if (this.setting_show_filepath_now_playing) {
|
|
||||||
return this.track.path
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
is_live() {
|
is_live() {
|
||||||
return this.track.length_ms === 0
|
return this.track.length_ms === 0
|
||||||
},
|
},
|
||||||
lyrics_visible() {
|
|
||||||
return this.$store.state.lyrics.pane
|
|
||||||
},
|
|
||||||
player() {
|
|
||||||
return this.$store.state.player
|
|
||||||
},
|
|
||||||
setting_show_composer_for_genre() {
|
|
||||||
return this.$store.getters.setting_show_composer_for_genre
|
|
||||||
},
|
|
||||||
setting_show_composer_now_playing() {
|
|
||||||
return this.$store.getters.setting_show_composer_now_playing
|
|
||||||
},
|
|
||||||
setting_show_filepath_now_playing() {
|
|
||||||
return this.$store.getters.setting_show_filepath_now_playing
|
|
||||||
},
|
|
||||||
track() {
|
track() {
|
||||||
return this.$store.getters.now_playing
|
return this.queueStore.current
|
||||||
},
|
},
|
||||||
track_elapsed_time() {
|
track_elapsed_time() {
|
||||||
return this.$filters.durationInHours(this.track_progress * INTERVAL)
|
return this.$filters.durationInHours(this.track_progress * INTERVAL)
|
||||||
},
|
},
|
||||||
track_progress: {
|
track_progress: {
|
||||||
get() {
|
get() {
|
||||||
return Math.floor(this.player.item_progress_ms / INTERVAL)
|
return Math.floor(this.playerStore.item_progress_ms / INTERVAL)
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.player.item_progress_ms = value * INTERVAL
|
this.playerStore.item_progress_ms = value * INTERVAL
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
track_progress_max() {
|
track_progress_max() {
|
||||||
|
@ -153,12 +145,12 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
player() {
|
playerStore() {
|
||||||
if (this.interval_id > 0) {
|
if (this.interval_id > 0) {
|
||||||
window.clearTimeout(this.interval_id)
|
window.clearTimeout(this.interval_id)
|
||||||
this.interval_id = 0
|
this.interval_id = 0
|
||||||
}
|
}
|
||||||
if (this.player.state === 'play') {
|
if (this.playerStore.state === 'play') {
|
||||||
this.interval_id = window.setInterval(this.tick, INTERVAL)
|
this.interval_id = window.setInterval(this.tick, INTERVAL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,8 +158,8 @@ export default {
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
webapi.player_status().then(({ data }) => {
|
webapi.player_status().then(({ data }) => {
|
||||||
this.$store.commit(types.UPDATE_PLAYER_STATUS, data)
|
this.playerStore.$state = data
|
||||||
if (this.player.state === 'play') {
|
if (this.playerStore.state === 'play') {
|
||||||
this.interval_id = window.setInterval(this.tick, INTERVAL)
|
this.interval_id = window.setInterval(this.tick, INTERVAL)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import ListPlaylists from '@/components/ListPlaylists.vue'
|
import ListPlaylists from '@/components/ListPlaylists.vue'
|
||||||
|
import { useConfigurationStore } from '@/stores/configuration'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -57,6 +58,12 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
configurationStore: useConfigurationStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
playlist: {},
|
playlist: {},
|
||||||
|
@ -77,7 +84,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
radio_playlists() {
|
radio_playlists() {
|
||||||
return this.$store.state.config.radio_playlists
|
return this.configurationStore.radio_playlists
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
||||||
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
|
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
||||||
import store from '@/store'
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const PAGE_SIZE = 50
|
const PAGE_SIZE = 50
|
||||||
|
@ -62,12 +62,12 @@ const PAGE_SIZE = 50
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load(to) {
|
load(to) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(useServicesStore().spotify.webapi_token)
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
spotifyApi.getPlaylist(to.params.id),
|
spotifyApi.getPlaylist(to.params.id),
|
||||||
spotifyApi.getPlaylistTracks(to.params.id, {
|
spotifyApi.getPlaylistTracks(to.params.id, {
|
||||||
limit: PAGE_SIZE,
|
limit: PAGE_SIZE,
|
||||||
market: store.state.spotify.webapi_country,
|
market: useServicesStore().state.spotify.webapi_country,
|
||||||
offset: 0
|
offset: 0
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
@ -97,6 +97,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
@ -128,11 +132,11 @@ export default {
|
||||||
},
|
},
|
||||||
load_next({ loaded }) {
|
load_next({ loaded }) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(this.$store.state.spotify.webapi_token)
|
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
|
||||||
spotifyApi
|
spotifyApi
|
||||||
.getPlaylistTracks(this.playlist.id, {
|
.getPlaylistTracks(this.playlist.id, {
|
||||||
limit: PAGE_SIZE,
|
limit: PAGE_SIZE,
|
||||||
market: store.state.spotify.webapi_country,
|
market: this.servicesStore.spotify.webapi_country,
|
||||||
offset: this.offset
|
offset: this.offset
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
|
|
@ -57,12 +57,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import ListAlbums from '@/components/ListAlbums.vue'
|
import ListAlbums from '@/components/ListAlbums.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogAddRss from '@/components/ModalDialogAddRss.vue'
|
import ModalDialogAddRss from '@/components/ModalDialogAddRss.vue'
|
||||||
|
import { useLibraryStore } from '@/stores/library'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
|
@ -94,6 +95,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { libraryStore: useLibraryStore(), uiStore: useUIStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: [],
|
albums: [],
|
||||||
|
@ -104,7 +109,7 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
rss() {
|
rss() {
|
||||||
return this.$store.state.rss_count
|
return this.libraryStore.rss
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -134,8 +139,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
update_rss() {
|
update_rss() {
|
||||||
this.$store.commit(types.UPDATE_DIALOG_SCAN_KIND, 'rss')
|
this.libraryStore.update_dialog_scan_kind = 'rss'
|
||||||
this.$store.commit(types.SHOW_UPDATE_DIALOG, true)
|
this.uiStore.show_update_dialog = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
v-if="element.id !== state.item_id && edit_mode"
|
v-if="element.id !== player.item_id && edit_mode"
|
||||||
@click.prevent.stop="remove(element)"
|
@click.prevent.stop="remove(element)"
|
||||||
>
|
>
|
||||||
<mdicon class="icon has-text-grey" name="delete" size="18" />
|
<mdicon class="icon has-text-grey" name="delete" size="18" />
|
||||||
|
@ -103,13 +103,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ListItemQueueItem from '@/components/ListItemQueueItem.vue'
|
import ListItemQueueItem from '@/components/ListItemQueueItem.vue'
|
||||||
import ModalDialogAddUrlStream from '@/components/ModalDialogAddUrlStream.vue'
|
import ModalDialogAddUrlStream from '@/components/ModalDialogAddUrlStream.vue'
|
||||||
import ModalDialogPlaylistSave from '@/components/ModalDialogPlaylistSave.vue'
|
import ModalDialogPlaylistSave from '@/components/ModalDialogPlaylistSave.vue'
|
||||||
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem.vue'
|
import ModalDialogQueueItem from '@/components/ModalDialogQueueItem.vue'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
import { useConfigurationStore } from '@/stores/configuration'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
|
import { useUIStore } from '@/stores/ui'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -123,6 +126,15 @@ export default {
|
||||||
draggable
|
draggable
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
configurationStore: useConfigurationStore(),
|
||||||
|
playerStore: usePlayerStore(),
|
||||||
|
queueStore: useQueueStore(),
|
||||||
|
uiStore: useUIStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
edit_mode: false,
|
edit_mode: false,
|
||||||
|
@ -135,30 +147,30 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
current_position() {
|
current_position() {
|
||||||
return this.$store.getters.now_playing?.position ?? -1
|
return this.queue.current?.position ?? -1
|
||||||
},
|
},
|
||||||
is_queue_save_allowed() {
|
is_queue_save_allowed() {
|
||||||
return (
|
return (
|
||||||
this.$store.state.config.allow_modifying_stored_playlists &&
|
this.configurationStore.allow_modifying_stored_playlists &&
|
||||||
this.$store.state.config.default_playlist_directory
|
this.configurationStore.default_playlist_directory
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
queue() {
|
queue() {
|
||||||
return this.$store.state.queue
|
return this.queueStore
|
||||||
},
|
},
|
||||||
queue_items: {
|
queue_items: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.queue.items
|
return this.queue.items
|
||||||
},
|
},
|
||||||
set() {
|
set() {
|
||||||
/* Do nothing? Send move request in @end event */
|
/* Do nothing? Send move request in @end event */
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show_only_next_items() {
|
show_only_next_items() {
|
||||||
return this.$store.state.show_only_next_items
|
return this.uiStore.show_only_next_items
|
||||||
},
|
},
|
||||||
state() {
|
player() {
|
||||||
return this.$store.state.player
|
return this.playerStore
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -191,7 +203,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update_show_next_items() {
|
update_show_next_items() {
|
||||||
this.$store.commit(types.SHOW_ONLY_NEXT_ITEMS, !this.show_only_next_items)
|
this.uiStore.show_only_next_items = !this.uiStore.show_only_next_items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import { GroupedList } from '@/lib/GroupedList'
|
import { GroupedList } from '@/lib/GroupedList'
|
||||||
import ListAlbums from '@/components/ListAlbums.vue'
|
import ListAlbums from '@/components/ListAlbums.vue'
|
||||||
|
@ -88,6 +87,7 @@ import ListComposers from '@/components/ListComposers.vue'
|
||||||
import ListPlaylists from '@/components/ListPlaylists.vue'
|
import ListPlaylists from '@/components/ListPlaylists.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import TabsSearch from '@/components/TabsSearch.vue'
|
import TabsSearch from '@/components/TabsSearch.vue'
|
||||||
|
import { useSearchStore } from '@/stores/search'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const PAGE_SIZE = 3,
|
const PAGE_SIZE = 3,
|
||||||
|
@ -113,6 +113,10 @@ export default {
|
||||||
TabsSearch
|
TabsSearch
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { searchStore: useSearchStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
components: {
|
components: {
|
||||||
|
@ -136,26 +140,26 @@ export default {
|
||||||
return this.search_types.length === 1
|
return this.search_types.length === 1
|
||||||
},
|
},
|
||||||
recent_searches() {
|
recent_searches() {
|
||||||
return this.$store.state.recent_searches
|
return this.searchStore.recent_searches
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
search_query() {
|
search_query() {
|
||||||
this.$store.commit(types.SEARCH_QUERY, this.search_query)
|
this.searchStore.search_query = this.search_query
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$store.commit(types.SEARCH_SOURCE, this.$route.name)
|
this.searchStore.search_source = this.$route.name
|
||||||
this.search_query = this.$store.state.search_query
|
this.search_query = this.searchStore.search_query
|
||||||
this.search_limit = PAGE_SIZE
|
this.search_limit = PAGE_SIZE
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
expand(type) {
|
expand(type) {
|
||||||
this.search_query = this.$store.state.search_query
|
this.search_query = this.searchStore.search_query
|
||||||
this.search_types = [type]
|
this.search_types = [type]
|
||||||
this.search_limit = -1
|
this.search_limit = -1
|
||||||
this.search()
|
this.search()
|
||||||
|
@ -167,7 +171,7 @@ export default {
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
remove_search(query) {
|
remove_search(query) {
|
||||||
this.$store.dispatch('remove_recent_search', query)
|
this.searchStore.remove(query)
|
||||||
},
|
},
|
||||||
reset() {
|
reset() {
|
||||||
this.results.clear()
|
this.results.clear()
|
||||||
|
@ -189,7 +193,7 @@ export default {
|
||||||
this.search_types.forEach((type) => {
|
this.search_types.forEach((type) => {
|
||||||
this.search_items(type)
|
this.search_items(type)
|
||||||
})
|
})
|
||||||
this.$store.dispatch('add_recent_search', this.search_query)
|
this.searchStore.add(this.search_query)
|
||||||
},
|
},
|
||||||
search_items(type) {
|
search_items(type) {
|
||||||
const music = type !== 'audiobook' && type !== 'podcast'
|
const music = type !== 'audiobook' && type !== 'podcast'
|
||||||
|
|
|
@ -74,7 +74,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
||||||
import ListArtistsSpotify from '@/components/ListArtistsSpotify.vue'
|
import ListArtistsSpotify from '@/components/ListArtistsSpotify.vue'
|
||||||
|
@ -83,6 +82,7 @@ import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import TabsSearch from '@/components/TabsSearch.vue'
|
import TabsSearch from '@/components/TabsSearch.vue'
|
||||||
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
||||||
|
import { useSearchStore } from '@/stores/search'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
const PAGE_SIZE = 3,
|
const PAGE_SIZE = 3,
|
||||||
|
@ -101,6 +101,10 @@ export default {
|
||||||
VueEternalLoading
|
VueEternalLoading
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { searchStore: useSearchStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
components: {
|
components: {
|
||||||
|
@ -121,7 +125,7 @@ export default {
|
||||||
return this.search_types.length === 1
|
return this.search_types.length === 1
|
||||||
},
|
},
|
||||||
recent_searches() {
|
recent_searches() {
|
||||||
return this.$store.state.recent_searches.filter(
|
return this.searchStore.recent_searches.filter(
|
||||||
(query) => !query.startsWith('query:')
|
(query) => !query.startsWith('query:')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -129,20 +133,20 @@ export default {
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
search_query() {
|
search_query() {
|
||||||
this.$store.commit(types.SEARCH_QUERY, this.search_query)
|
this.searchStore.search_query = this.search_query
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$store.commit(types.SEARCH_SOURCE, this.$route.name)
|
this.searchStore.search_source = this.$route.name
|
||||||
this.search_query = this.$store.state.search_query
|
this.search_query = this.searchStore.search_query
|
||||||
this.search_parameters.limit = PAGE_SIZE
|
this.search_parameters.limit = PAGE_SIZE
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
expand(type) {
|
expand(type) {
|
||||||
this.search_query = this.$store.state.search_query
|
this.search_query = this.searchStore.search_query
|
||||||
this.search_types = [type]
|
this.search_types = [type]
|
||||||
this.search_parameters.limit = PAGE_SIZE_EXPANDED
|
this.search_parameters.limit = PAGE_SIZE_EXPANDED
|
||||||
this.search_parameters.offset = 0
|
this.search_parameters.offset = 0
|
||||||
|
@ -156,7 +160,7 @@ export default {
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
remove_search(query) {
|
remove_search(query) {
|
||||||
this.$store.dispatch('remove_recent_search', query)
|
this.searchStore.remove(query)
|
||||||
},
|
},
|
||||||
reset() {
|
reset() {
|
||||||
this.results.clear()
|
this.results.clear()
|
||||||
|
@ -180,7 +184,7 @@ export default {
|
||||||
this.results.set(type, data[`${type}s`])
|
this.results.set(type, data[`${type}s`])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.$store.dispatch('add_recent_search', this.search_query)
|
this.searchStore.add(this.search_query)
|
||||||
},
|
},
|
||||||
search_items() {
|
search_items() {
|
||||||
return webapi.spotify().then(({ data }) => {
|
return webapi.spotify().then(({ data }) => {
|
||||||
|
|
|
@ -54,14 +54,19 @@
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import SettingsCheckbox from '@/components/SettingsCheckbox.vue'
|
import SettingsCheckbox from '@/components/SettingsCheckbox.vue'
|
||||||
import TabsSettings from '@/components/TabsSettings.vue'
|
import TabsSettings from '@/components/TabsSettings.vue'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageSettingsArtwork',
|
name: 'PageSettingsArtwork',
|
||||||
components: { ContentWithHeading, SettingsCheckbox, TabsSettings },
|
components: { ContentWithHeading, SettingsCheckbox, TabsSettings },
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
spotify() {
|
spotify() {
|
||||||
return this.$store.state.spotify
|
return this.servicesStore.spotify
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,12 +131,17 @@
|
||||||
<script>
|
<script>
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import TabsSettings from '@/components/TabsSettings.vue'
|
import TabsSettings from '@/components/TabsSettings.vue'
|
||||||
|
import { useServicesStore } from '@/stores/services'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageSettingsOnlineServices',
|
name: 'PageSettingsOnlineServices',
|
||||||
components: { ContentWithHeading, TabsSettings },
|
components: { ContentWithHeading, TabsSettings },
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { servicesStore: useServicesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
lastfm_login: {
|
lastfm_login: {
|
||||||
|
@ -149,10 +154,10 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
lastfm() {
|
lastfm() {
|
||||||
return this.$store.state.lastfm
|
return this.servicesStore.lastfm
|
||||||
},
|
},
|
||||||
spotify() {
|
spotify() {
|
||||||
return this.$store.state.spotify
|
return this.servicesStore.spotify
|
||||||
},
|
},
|
||||||
spotify_missing_scope() {
|
spotify_missing_scope() {
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -95,12 +95,18 @@
|
||||||
<script>
|
<script>
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import TabsSettings from '@/components/TabsSettings.vue'
|
import TabsSettings from '@/components/TabsSettings.vue'
|
||||||
|
import { useOutputsStore } from '@/stores/outputs'
|
||||||
|
import { useRemotesStore } from '@/stores/remotes'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageSettingsRemotesOutputs',
|
name: 'PageSettingsRemotesOutputs',
|
||||||
components: { ContentWithHeading, TabsSettings },
|
components: { ContentWithHeading, TabsSettings },
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { outputsStore: useOutputsStore(), remotesStore: useRemotesStore() }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pairing_req: { pin: '' },
|
pairing_req: { pin: '' },
|
||||||
|
@ -110,10 +116,10 @@ export default {
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
outputs() {
|
outputs() {
|
||||||
return this.$store.state.outputs
|
return this.outputsStore.outputs
|
||||||
},
|
},
|
||||||
pairing() {
|
pairing() {
|
||||||
return this.$store.state.pairing
|
return this.remotesStore.pairing
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@
|
||||||
<settings-textfield
|
<settings-textfield
|
||||||
category="webinterface"
|
category="webinterface"
|
||||||
name="show_composer_for_genre"
|
name="show_composer_for_genre"
|
||||||
:disabled="!setting_show_composer_now_playing"
|
:disabled="!settingsStore.show_composer_now_playing"
|
||||||
:placeholder="$t('page.settings.general.genres')"
|
:placeholder="$t('page.settings.general.genres')"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
|
@ -169,6 +169,7 @@ import SettingsCheckbox from '@/components/SettingsCheckbox.vue'
|
||||||
import SettingsIntfield from '@/components/SettingsIntfield.vue'
|
import SettingsIntfield from '@/components/SettingsIntfield.vue'
|
||||||
import SettingsTextfield from '@/components/SettingsTextfield.vue'
|
import SettingsTextfield from '@/components/SettingsTextfield.vue'
|
||||||
import TabsSettings from '@/components/TabsSettings.vue'
|
import TabsSettings from '@/components/TabsSettings.vue'
|
||||||
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PageSettingsWebinterface',
|
name: 'PageSettingsWebinterface',
|
||||||
|
@ -181,6 +182,10 @@ export default {
|
||||||
TabsSettings
|
TabsSettings
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return { settingsStore: useSettingsStore() }
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
locale: {
|
locale: {
|
||||||
get() {
|
get() {
|
||||||
|
@ -209,12 +214,6 @@ export default {
|
||||||
name: this.$t(`language.${item}`)
|
name: this.$t(`language.${item}`)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
},
|
|
||||||
setting_show_composer_now_playing() {
|
|
||||||
return this.$store.getters.setting_show_composer_now_playing
|
|
||||||
},
|
|
||||||
setting_show_filepath_now_playing() {
|
|
||||||
return this.$store.getters.setting_show_filepath_now_playing
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as types from '@/store/mutation_types'
|
|
||||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
import PageAbout from '@/pages/PageAbout.vue'
|
import PageAbout from '@/pages/PageAbout.vue'
|
||||||
import PageAlbum from '@/pages/PageAlbum.vue'
|
import PageAlbum from '@/pages/PageAlbum.vue'
|
||||||
|
@ -40,7 +39,7 @@ import PageSettingsArtwork from '@/pages/PageSettingsArtwork.vue'
|
||||||
import PageSettingsOnlineServices from '@/pages/PageSettingsOnlineServices.vue'
|
import PageSettingsOnlineServices from '@/pages/PageSettingsOnlineServices.vue'
|
||||||
import PageSettingsRemotesOutputs from '@/pages/PageSettingsRemotesOutputs.vue'
|
import PageSettingsRemotesOutputs from '@/pages/PageSettingsRemotesOutputs.vue'
|
||||||
import PageSettingsWebinterface from '@/pages/PageSettingsWebinterface.vue'
|
import PageSettingsWebinterface from '@/pages/PageSettingsWebinterface.vue'
|
||||||
import store from '@/store'
|
import { useUIStore } from '@/stores/ui'
|
||||||
|
|
||||||
const TOP_WITH_TABS = 140
|
const TOP_WITH_TABS = 140
|
||||||
const TOP_WITHOUT_TABS = 110
|
const TOP_WITHOUT_TABS = 110
|
||||||
|
@ -343,13 +342,14 @@ export const router = createRouter({
|
||||||
})
|
})
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
if (store.state.show_burger_menu) {
|
const uiStore = useUIStore()
|
||||||
store.commit(types.SHOW_BURGER_MENU, false)
|
if (uiStore.show_burger_menu) {
|
||||||
|
uiStore.show_burger_menu = false
|
||||||
next(false)
|
next(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (store.state.show_player_menu) {
|
if (uiStore.show_player_menu) {
|
||||||
store.commit(types.SHOW_PLAYER_MENU, false)
|
uiStore.show_player_menu = false
|
||||||
next(false)
|
next(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,238 +0,0 @@
|
||||||
import * as types from './mutation_types'
|
|
||||||
import { createStore } from 'vuex'
|
|
||||||
|
|
||||||
export default createStore({
|
|
||||||
state() {
|
|
||||||
return {
|
|
||||||
albums_sort: 1,
|
|
||||||
artist_albums_sort: 1,
|
|
||||||
artist_tracks_sort: 1,
|
|
||||||
artists_sort: 1,
|
|
||||||
composer_tracks_sort: 1,
|
|
||||||
config: {
|
|
||||||
buildoptions: [],
|
|
||||||
version: '',
|
|
||||||
websocket_port: 0
|
|
||||||
},
|
|
||||||
genre_tracks_sort: 1,
|
|
||||||
hide_singles: false,
|
|
||||||
hide_spotify: false,
|
|
||||||
lastfm: {},
|
|
||||||
library: {
|
|
||||||
albums: 0,
|
|
||||||
artists: 0,
|
|
||||||
db_playtime: 0,
|
|
||||||
songs: 0,
|
|
||||||
started_at: '01',
|
|
||||||
updated_at: '01',
|
|
||||||
updating: false
|
|
||||||
},
|
|
||||||
lyrics: {
|
|
||||||
content: [],
|
|
||||||
pane: false
|
|
||||||
},
|
|
||||||
notifications: {
|
|
||||||
list: [],
|
|
||||||
next_id: 1
|
|
||||||
},
|
|
||||||
outputs: [],
|
|
||||||
pairing: {},
|
|
||||||
player: {
|
|
||||||
consume: false,
|
|
||||||
item_id: 0,
|
|
||||||
item_length_ms: 0,
|
|
||||||
item_progress_ms: 0,
|
|
||||||
repeat: 'off',
|
|
||||||
shuffle: false,
|
|
||||||
state: 'stop',
|
|
||||||
volume: 0
|
|
||||||
},
|
|
||||||
queue: {
|
|
||||||
count: 0,
|
|
||||||
items: [],
|
|
||||||
version: 0
|
|
||||||
},
|
|
||||||
recent_searches: [],
|
|
||||||
rss_count: {},
|
|
||||||
search_query: '',
|
|
||||||
search_source: 'search-library',
|
|
||||||
settings: {
|
|
||||||
categories: []
|
|
||||||
},
|
|
||||||
show_burger_menu: false,
|
|
||||||
show_only_next_items: false,
|
|
||||||
show_player_menu: false,
|
|
||||||
show_update_dialog: false,
|
|
||||||
spotify: {},
|
|
||||||
update_dialog_scan_kind: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getters: {
|
|
||||||
now_playing: (state) =>
|
|
||||||
state.queue.items.find((item) => item.id === state.player.item_id) ?? {},
|
|
||||||
setting: (state) => (categoryName, optionName) =>
|
|
||||||
state.settings.categories
|
|
||||||
.find((category) => category.name === categoryName)
|
|
||||||
?.options.find((option) => option.name === optionName) ?? {},
|
|
||||||
setting_recently_added_limit: (state, getters) =>
|
|
||||||
getters.settings_webinterface?.options.find(
|
|
||||||
(option) => option.name === 'recently_added_limit'
|
|
||||||
)?.value ?? 100,
|
|
||||||
setting_show_composer_for_genre: (state, getters) =>
|
|
||||||
getters.settings_webinterface?.options.find(
|
|
||||||
(option) => option.name === 'show_composer_for_genre'
|
|
||||||
)?.value ?? null,
|
|
||||||
setting_show_composer_now_playing: (state, getters) =>
|
|
||||||
getters.settings_webinterface?.options.find(
|
|
||||||
(option) => option.name === 'show_composer_now_playing'
|
|
||||||
)?.value ?? false,
|
|
||||||
setting_show_filepath_now_playing: (state, getters) =>
|
|
||||||
getters.settings_webinterface?.options.find(
|
|
||||||
(option) => option.name === 'show_filepath_now_playing'
|
|
||||||
)?.value ?? false,
|
|
||||||
settings_webinterface: (state) =>
|
|
||||||
state.settings?.categories.find(
|
|
||||||
(category) => category.name === 'webinterface'
|
|
||||||
) ?? null
|
|
||||||
},
|
|
||||||
|
|
||||||
mutations: {
|
|
||||||
[types.UPDATE_CONFIG](state, config) {
|
|
||||||
state.config = config
|
|
||||||
},
|
|
||||||
[types.UPDATE_SETTINGS](state, settings) {
|
|
||||||
state.settings = settings
|
|
||||||
},
|
|
||||||
[types.UPDATE_LIBRARY_STATS](state, libraryStats) {
|
|
||||||
state.library = libraryStats
|
|
||||||
},
|
|
||||||
[types.UPDATE_LIBRARY_RSS_COUNT](state, count) {
|
|
||||||
state.rss_count = count
|
|
||||||
},
|
|
||||||
[types.UPDATE_OUTPUTS](state, outputs) {
|
|
||||||
state.outputs = outputs
|
|
||||||
},
|
|
||||||
[types.UPDATE_PLAYER_STATUS](state, playerStatus) {
|
|
||||||
state.player = playerStatus
|
|
||||||
},
|
|
||||||
[types.UPDATE_QUEUE](state, queue) {
|
|
||||||
state.queue = queue
|
|
||||||
},
|
|
||||||
[types.UPDATE_LYRICS](state, lyrics) {
|
|
||||||
state.lyrics.content = lyrics
|
|
||||||
},
|
|
||||||
[types.UPDATE_LASTFM](state, lastfm) {
|
|
||||||
state.lastfm = lastfm
|
|
||||||
},
|
|
||||||
[types.UPDATE_SPOTIFY](state, spotify) {
|
|
||||||
state.spotify = spotify
|
|
||||||
},
|
|
||||||
[types.UPDATE_PAIRING](state, pairing) {
|
|
||||||
state.pairing = pairing
|
|
||||||
},
|
|
||||||
[types.SEARCH_QUERY](state, query) {
|
|
||||||
state.search_query = query
|
|
||||||
},
|
|
||||||
[types.SEARCH_SOURCE](state, searchSource) {
|
|
||||||
state.search_source = searchSource
|
|
||||||
},
|
|
||||||
[types.COMPOSER_TRACKS_SORT](state, sort) {
|
|
||||||
state.composer_tracks_sort = sort
|
|
||||||
},
|
|
||||||
[types.GENRE_TRACKS_SORT](state, sort) {
|
|
||||||
state.genre_tracks_sort = sort
|
|
||||||
},
|
|
||||||
[types.HIDE_SINGLES](state, hideSingles) {
|
|
||||||
state.hide_singles = hideSingles
|
|
||||||
},
|
|
||||||
[types.HIDE_SPOTIFY](state, hideSpotify) {
|
|
||||||
state.hide_spotify = hideSpotify
|
|
||||||
},
|
|
||||||
[types.ARTISTS_SORT](state, sort) {
|
|
||||||
state.artists_sort = sort
|
|
||||||
},
|
|
||||||
[types.ARTIST_ALBUMS_SORT](state, sort) {
|
|
||||||
state.artist_albums_sort = sort
|
|
||||||
},
|
|
||||||
[types.ARTIST_TRACKS_SORT](state, sort) {
|
|
||||||
state.artist_tracks_sort = sort
|
|
||||||
},
|
|
||||||
[types.ALBUMS_SORT](state, sort) {
|
|
||||||
state.albums_sort = sort
|
|
||||||
},
|
|
||||||
[types.SHOW_ONLY_NEXT_ITEMS](state, showOnlyNextItems) {
|
|
||||||
state.show_only_next_items = showOnlyNextItems
|
|
||||||
},
|
|
||||||
[types.SHOW_BURGER_MENU](state, showBurgerMenu) {
|
|
||||||
state.show_burger_menu = showBurgerMenu
|
|
||||||
},
|
|
||||||
[types.SHOW_PLAYER_MENU](state, showPlayerMenu) {
|
|
||||||
state.show_player_menu = showPlayerMenu
|
|
||||||
},
|
|
||||||
[types.SHOW_UPDATE_DIALOG](state, showUpdateDialog) {
|
|
||||||
state.show_update_dialog = showUpdateDialog
|
|
||||||
},
|
|
||||||
[types.UPDATE_DIALOG_SCAN_KIND](state, scanKind) {
|
|
||||||
state.update_dialog_scan_kind = scanKind
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
add_notification({ state }, notification) {
|
|
||||||
const newNotification = {
|
|
||||||
id: state.notifications.next_id++,
|
|
||||||
text: notification.text,
|
|
||||||
timeout: notification.timeout,
|
|
||||||
topic: notification.topic,
|
|
||||||
type: notification.type
|
|
||||||
}
|
|
||||||
if (newNotification.topic) {
|
|
||||||
const index = state.notifications.list.findIndex(
|
|
||||||
(elem) => elem.topic === newNotification.topic
|
|
||||||
)
|
|
||||||
if (index >= 0) {
|
|
||||||
state.notifications.list.splice(index, 1, newNotification)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.notifications.list.push(newNotification)
|
|
||||||
if (notification.timeout > 0) {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.dispatch('delete_notification', newNotification)
|
|
||||||
}, notification.timeout)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
add_recent_search({ state }, query) {
|
|
||||||
const index = state.recent_searches.indexOf(query)
|
|
||||||
if (index !== -1) {
|
|
||||||
state.recent_searches.splice(index, 1)
|
|
||||||
}
|
|
||||||
state.recent_searches.splice(0, 0, query)
|
|
||||||
if (state.recent_searches.length > 5) {
|
|
||||||
state.recent_searches.pop()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
delete_notification({ state }, notification) {
|
|
||||||
const index = state.notifications.list.indexOf(notification)
|
|
||||||
if (index !== -1) {
|
|
||||||
state.notifications.list.splice(index, 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove_recent_search({ state }, query) {
|
|
||||||
const index = state.recent_searches.indexOf(query)
|
|
||||||
if (index !== -1) {
|
|
||||||
state.recent_searches.splice(index, 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update_setting({ state }, option) {
|
|
||||||
const settingCategory = state.settings.categories.find(
|
|
||||||
(category) => category.name === option.category
|
|
||||||
),
|
|
||||||
settingOption = settingCategory.options.find(
|
|
||||||
(setting) => setting.name === option.name
|
|
||||||
)
|
|
||||||
settingOption.value = option.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -1,26 +0,0 @@
|
||||||
export const ALBUMS_SORT = 'ALBUMS_SORT',
|
|
||||||
ARTISTS_SORT = 'ARTISTS_SORT',
|
|
||||||
ARTIST_ALBUMS_SORT = 'ARTIST_ALBUMS_SORT',
|
|
||||||
ARTIST_TRACKS_SORT = 'ARTIST_TRACKS_SORT',
|
|
||||||
COMPOSER_TRACKS_SORT = 'COMPOSER_TRACKS_SORT',
|
|
||||||
GENRE_TRACKS_SORT = 'GENRE_TRACKS_SORT',
|
|
||||||
HIDE_SINGLES = 'HIDE_SINGLES',
|
|
||||||
HIDE_SPOTIFY = 'HIDE_SPOTIFY',
|
|
||||||
SEARCH_QUERY = 'SEARCH_QUERY',
|
|
||||||
SEARCH_SOURCE = 'SEARCH_SOURCE',
|
|
||||||
SHOW_BURGER_MENU = 'SHOW_BURGER_MENU',
|
|
||||||
SHOW_ONLY_NEXT_ITEMS = 'SHOW_ONLY_NEXT_ITEMS',
|
|
||||||
SHOW_PLAYER_MENU = 'SHOW_PLAYER_MENU',
|
|
||||||
SHOW_UPDATE_DIALOG = 'SHOW_UPDATE_DIALOG',
|
|
||||||
UPDATE_CONFIG = 'UPDATE_CONFIG',
|
|
||||||
UPDATE_DIALOG_SCAN_KIND = 'UPDATE_DIALOG_SCAN_KIND',
|
|
||||||
UPDATE_LASTFM = 'UPDATE_LASTFM',
|
|
||||||
UPDATE_LIBRARY_RSS_COUNT = 'UPDATE_LIBRARY_RSS_COUNT',
|
|
||||||
UPDATE_LIBRARY_STATS = 'UPDATE_LIBRARY_STATS',
|
|
||||||
UPDATE_LYRICS = 'UPDATE_LYRICS',
|
|
||||||
UPDATE_OUTPUTS = 'UPDATE_OUTPUTS',
|
|
||||||
UPDATE_PAIRING = 'UPDATE_PAIRING',
|
|
||||||
UPDATE_PLAYER_STATUS = 'UPDATE_PLAYER_STATUS',
|
|
||||||
UPDATE_QUEUE = 'UPDATE_QUEUE',
|
|
||||||
UPDATE_SETTINGS = 'UPDATE_SETTINGS',
|
|
||||||
UPDATE_SPOTIFY = 'UPDATE_SPOTIFY'
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useConfigurationStore = defineStore('ConfigurationStore', {
|
||||||
|
state: () => ({
|
||||||
|
buildoptions: [],
|
||||||
|
version: '',
|
||||||
|
websocket_port: 0
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useLibraryStore = defineStore('LibraryStore', {
|
||||||
|
state: () => ({
|
||||||
|
albums: 0,
|
||||||
|
artists: 0,
|
||||||
|
db_playtime: 0,
|
||||||
|
songs: 0,
|
||||||
|
rss: {},
|
||||||
|
started_at: '01',
|
||||||
|
updated_at: '01',
|
||||||
|
update_dialog_scan_kind: '',
|
||||||
|
updating: false
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useLyricsStore = defineStore('LyricsStore', {
|
||||||
|
state: () => ({
|
||||||
|
content: [],
|
||||||
|
pane: false
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useNotificationsStore = defineStore('NotificationsStore', {
|
||||||
|
state: () => ({
|
||||||
|
list: [],
|
||||||
|
next_id: 1
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
add(notification) {
|
||||||
|
const newNotification = {
|
||||||
|
id: this.next_id++,
|
||||||
|
text: notification.text,
|
||||||
|
timeout: notification.timeout,
|
||||||
|
topic: notification.topic,
|
||||||
|
type: notification.type
|
||||||
|
}
|
||||||
|
if (newNotification.topic) {
|
||||||
|
const index = this.list.findIndex(
|
||||||
|
(elem) => elem.topic === newNotification.topic
|
||||||
|
)
|
||||||
|
if (index >= 0) {
|
||||||
|
this.list.splice(index, 1, newNotification)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.list.push(newNotification)
|
||||||
|
if (notification.timeout > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.remove(newNotification)
|
||||||
|
}, notification.timeout)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove(notification) {
|
||||||
|
const index = this.list.indexOf(notification)
|
||||||
|
if (index !== -1) {
|
||||||
|
this.list.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useOutputsStore = defineStore('OutputsStore', {
|
||||||
|
state: () => ({
|
||||||
|
outputs: []
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const usePlayerStore = defineStore('PlayerStore', {
|
||||||
|
state: () => ({
|
||||||
|
consume: false,
|
||||||
|
item_id: 0,
|
||||||
|
item_length_ms: 0,
|
||||||
|
item_progress_ms: 0,
|
||||||
|
repeat: 'off',
|
||||||
|
shuffle: false,
|
||||||
|
state: 'stop',
|
||||||
|
volume: 0
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { usePlayerStore } from '@/stores/player'
|
||||||
|
|
||||||
|
export const useQueueStore = defineStore('QueueStore', {
|
||||||
|
state: () => ({
|
||||||
|
count: 0,
|
||||||
|
items: [],
|
||||||
|
version: 0
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
current(state) {
|
||||||
|
const player = usePlayerStore()
|
||||||
|
return state.items.find((item) => item.id === player.item_id) ?? {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useRemotesStore = defineStore('RemotesStore', {
|
||||||
|
state: () => ({
|
||||||
|
pairing: {}
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useSearchStore = defineStore('SearchStore', {
|
||||||
|
state: () => ({
|
||||||
|
recent_searches: [],
|
||||||
|
search_query: '',
|
||||||
|
search_source: 'search-library'
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
add(query) {
|
||||||
|
const index = this.recent_searches.indexOf(query)
|
||||||
|
if (index !== -1) {
|
||||||
|
this.recent_searches.splice(index, 1)
|
||||||
|
}
|
||||||
|
this.recent_searches.unshift(query)
|
||||||
|
if (this.recent_searches.length > 5) {
|
||||||
|
this.recent_searches.pop()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove(query) {
|
||||||
|
const index = this.recent_searches.indexOf(query)
|
||||||
|
if (index !== -1) {
|
||||||
|
this.recent_searches.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useServicesStore = defineStore('ServicesStore', {
|
||||||
|
state: () => ({
|
||||||
|
lastfm: {},
|
||||||
|
spotify: {}
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useSettingsStore = defineStore('SettingsStore', {
|
||||||
|
state: () => ({
|
||||||
|
categories: []
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
recently_added_limit: (state) =>
|
||||||
|
state.setting('webinterface', 'recently_added_limit')?.value ?? 100,
|
||||||
|
show_composer_for_genre: (state) =>
|
||||||
|
state.setting('webinterface', 'show_composer_for_genre')?.value ?? null,
|
||||||
|
show_composer_now_playing: (state) =>
|
||||||
|
state.setting('webinterface', 'show_composer_now_playing')?.value ??
|
||||||
|
false,
|
||||||
|
show_cover_artwork_in_album_lists: (state) =>
|
||||||
|
state.setting('webinterface', 'show_cover_artwork_in_album_lists')
|
||||||
|
?.value ?? false,
|
||||||
|
show_filepath_now_playing: (state) =>
|
||||||
|
state.setting('webinterface', 'show_filepath_now_playing')?.value ??
|
||||||
|
false,
|
||||||
|
show_menu_item_audiobooks: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_audiobooks')?.value ??
|
||||||
|
false,
|
||||||
|
show_menu_item_files: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_files')?.value ?? false,
|
||||||
|
show_menu_item_music: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_music')?.value ?? false,
|
||||||
|
show_menu_item_playlists: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_playlists')?.value ?? false,
|
||||||
|
show_menu_item_podcasts: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_podcasts')?.value ?? false,
|
||||||
|
show_menu_item_radio: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_radio')?.value ?? false,
|
||||||
|
show_menu_item_search: (state) =>
|
||||||
|
state.setting('webinterface', 'show_menu_item_search')?.value ?? false
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
update(option) {
|
||||||
|
const settingCategory = this.categories.find(
|
||||||
|
(category) => category.name === option.category
|
||||||
|
)
|
||||||
|
if (!settingCategory) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const settingOption = settingCategory.options.find(
|
||||||
|
(setting) => setting.name === option.name
|
||||||
|
)
|
||||||
|
if (settingOption) {
|
||||||
|
settingOption.value = option.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setting(categoryName, optionName) {
|
||||||
|
return (
|
||||||
|
this.categories
|
||||||
|
.find((category) => category.name === categoryName)
|
||||||
|
?.options.find((option) => option.name === optionName) ?? {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useUIStore = defineStore('UIStore', {
|
||||||
|
state: () => ({
|
||||||
|
albums_sort: 1,
|
||||||
|
artist_albums_sort: 1,
|
||||||
|
artist_tracks_sort: 1,
|
||||||
|
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
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,6 +1,7 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import i18n from '@/i18n'
|
import i18n from '@/i18n'
|
||||||
import store from '@/store'
|
import { useNotificationsStore } from '@/stores/notifications'
|
||||||
|
import { useQueueStore } from '@/stores/queue'
|
||||||
|
|
||||||
const { t } = i18n.global
|
const { t } = i18n.global
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ axios.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
(error) => {
|
(error) => {
|
||||||
if (error.request.status && error.request.responseURL) {
|
if (error.request.status && error.request.responseURL) {
|
||||||
store.dispatch('add_notification', {
|
useNotificationsStore().add({
|
||||||
text: t('server.request-failed', {
|
text: t('server.request-failed', {
|
||||||
cause: error.request.statusText,
|
cause: error.request.statusText,
|
||||||
status: error.request.status,
|
status: error.request.status,
|
||||||
|
@ -316,7 +317,7 @@ export default {
|
||||||
|
|
||||||
queue_add(uri) {
|
queue_add(uri) {
|
||||||
return axios.post(`./api/queue/items/add?uris=${uri}`).then((response) => {
|
return axios.post(`./api/queue/items/add?uris=${uri}`).then((response) => {
|
||||||
store.dispatch('add_notification', {
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', { count: response.data.count }),
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
|
@ -327,16 +328,15 @@ export default {
|
||||||
|
|
||||||
queue_add_next(uri) {
|
queue_add_next(uri) {
|
||||||
let position = 0
|
let position = 0
|
||||||
if (store.getters.now_playing && store.getters.now_playing.id) {
|
const { current } = useQueueStore()
|
||||||
position = store.getters.now_playing.position + 1
|
if (current?.id) {
|
||||||
|
position = current.position + 1
|
||||||
}
|
}
|
||||||
return axios
|
return axios
|
||||||
.post(`./api/queue/items/add?uris=${uri}&position=${position}`)
|
.post(`./api/queue/items/add?uris=${uri}&position=${position}`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
store.dispatch('add_notification', {
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', {
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
count: response.data.count
|
|
||||||
}),
|
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
})
|
||||||
|
@ -352,10 +352,8 @@ export default {
|
||||||
return axios
|
return axios
|
||||||
.post('./api/queue/items/add', null, { params: { expression } })
|
.post('./api/queue/items/add', null, { params: { expression } })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
store.dispatch('add_notification', {
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', {
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
count: response.data.count
|
|
||||||
}),
|
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
})
|
||||||
|
@ -367,16 +365,15 @@ export default {
|
||||||
const params = {}
|
const params = {}
|
||||||
params.expression = expression
|
params.expression = expression
|
||||||
params.position = 0
|
params.position = 0
|
||||||
if (store.getters.now_playing && store.getters.now_playing.id) {
|
const { current } = useQueueStore()
|
||||||
params.position = store.getters.now_playing.position + 1
|
if (current?.id) {
|
||||||
|
params.position = current.position + 1
|
||||||
}
|
}
|
||||||
return axios
|
return axios
|
||||||
.post('./api/queue/items/add', null, { params })
|
.post('./api/queue/items/add', null, { params })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
store.dispatch('add_notification', {
|
useNotificationsStore().add({
|
||||||
text: t('server.appended-tracks', {
|
text: t('server.appended-tracks', { count: response.data.count }),
|
||||||
count: response.data.count
|
|
||||||
}),
|
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
})
|
})
|
||||||
|
@ -396,7 +393,7 @@ export default {
|
||||||
return axios
|
return axios
|
||||||
.post('./api/queue/save', null, { params: { name } })
|
.post('./api/queue/save', null, { params: { name } })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
store.dispatch('add_notification', {
|
useNotificationsStore().add({
|
||||||
text: t('server.queue-saved', { name }),
|
text: t('server.queue-saved', { name }),
|
||||||
timeout: 2000,
|
timeout: 2000,
|
||||||
type: 'info'
|
type: 'info'
|
||||||
|
|
Loading…
Reference in New Issue