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