mirror of
https://github.com/owntone/owntone-server.git
synced 2025-10-30 00:05:05 -04:00
[web] Switch to Spotify Web SDK
This commit is contained in:
parent
b612e12aca
commit
978a9b6a96
585
web-src/package-lock.json
generated
585
web-src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aacassandra/vue3-progressbar": "^1.0.3",
|
"@aacassandra/vue3-progressbar": "^1.0.3",
|
||||||
"@mdi/js": "^7.4.47",
|
"@mdi/js": "^7.4.47",
|
||||||
|
"@spotify/web-api-ts-sdk": "^1.2.0",
|
||||||
"@ts-pro/vue-eternal-loading": "^1.3.1",
|
"@ts-pro/vue-eternal-loading": "^1.3.1",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"bulma": "^1.0.4",
|
"bulma": "^1.0.4",
|
||||||
@ -21,7 +22,6 @@
|
|||||||
"mdi-vue": "^3.0.13",
|
"mdi-vue": "^3.0.13",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"reconnectingwebsocket": "^1.0.0",
|
"reconnectingwebsocket": "^1.0.0",
|
||||||
"spotify-web-api-js": "^1.5.2",
|
|
||||||
"vue": "^3.5.18",
|
"vue": "^3.5.18",
|
||||||
"vue-i18n": "^11.1.11",
|
"vue-i18n": "^11.1.11",
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
@ -31,12 +31,12 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^6.0.8",
|
"@intlify/unplugin-vue-i18n": "^6.0.8",
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"eslint": "^9.32.0",
|
"eslint": "^9.33.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-vue": "^10.3.0",
|
"eslint-plugin-vue": "^10.4.0",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"sass": "^1.89.2",
|
"sass": "^1.90.0",
|
||||||
"vite": "^7.0.6"
|
"vite": "^7.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { SpotifyApi } from '@spotify/web-api-ts-sdk'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -14,6 +15,11 @@ export default {
|
|||||||
return api.get('./api/spotify-logout')
|
return api.get('./api/spotify-logout')
|
||||||
},
|
},
|
||||||
spotify() {
|
spotify() {
|
||||||
return api.get('./api/spotify')
|
return api.get('./api/spotify').then((configuration) => {
|
||||||
|
const sdk = SpotifyApi.withAccessToken(configuration.webapi_client_id, {
|
||||||
|
access_token: configuration.webapi_token
|
||||||
|
})
|
||||||
|
return { api: sdk, configuration }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import ListProperties from '@/components/ListProperties.vue'
|
import ListProperties from '@/components/ListProperties.vue'
|
||||||
import ModalDialog from '@/components/ModalDialog.vue'
|
import ModalDialog from '@/components/ModalDialog.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import player from '@/api/player'
|
import player from '@/api/player'
|
||||||
import queue from '@/api/queue'
|
import queue from '@/api/queue'
|
||||||
|
import services from '@/api/services'
|
||||||
import { useServicesStore } from '@/stores/services'
|
import { useServicesStore } from '@/stores/services'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -90,16 +90,17 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
item() {
|
item() {
|
||||||
if (this.item?.data_kind === 'spotify') {
|
if (this.item?.data_kind === 'spotify') {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
return services.spotify().then(({ api }) => {
|
||||||
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
|
const trackId = this.item.path.slice(
|
||||||
spotifyApi
|
this.item.path.lastIndexOf(':') + 1
|
||||||
.getTrack(this.item.path.slice(this.item.path.lastIndexOf(':') + 1))
|
)
|
||||||
.then((response) => {
|
return api.tracks.get(trackId).then((response) => {
|
||||||
this.spotifyTrack = response
|
this.spotifyTrack = response
|
||||||
})
|
})
|
||||||
} else {
|
})
|
||||||
this.spotifyTrack = {}
|
|
||||||
}
|
}
|
||||||
|
this.spotifyTrack = {}
|
||||||
|
return {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import ControlImage from '@/components/ControlImage.vue'
|
|||||||
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
||||||
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
||||||
import PaneHero from '@/components/PaneHero.vue'
|
import PaneHero from '@/components/PaneHero.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import queue from '@/api/queue'
|
import queue from '@/api/queue'
|
||||||
import services from '@/api/services'
|
import services from '@/api/services'
|
||||||
import { useServicesStore } from '@/stores/services'
|
import { useServicesStore } from '@/stores/services'
|
||||||
@ -43,13 +42,9 @@ export default {
|
|||||||
PaneHero
|
PaneHero
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
services.spotify().then(({ api, configuration }) => {
|
||||||
services.spotify().then((data) => {
|
api.albums
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
.get(to.params.id, configuration.webapi_country)
|
||||||
spotifyApi
|
|
||||||
.getAlbum(to.params.id, {
|
|
||||||
market: useServicesStore().spotify.webapi_country
|
|
||||||
})
|
|
||||||
.then((album) => {
|
.then((album) => {
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.album = album
|
vm.album = album
|
||||||
|
|||||||
@ -28,10 +28,8 @@ import ControlButton from '@/components/ControlButton.vue'
|
|||||||
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
||||||
import ModalDialogArtistSpotify from '@/components/ModalDialogArtistSpotify.vue'
|
import ModalDialogArtistSpotify from '@/components/ModalDialogArtistSpotify.vue'
|
||||||
import PaneTitle from '@/components/PaneTitle.vue'
|
import PaneTitle from '@/components/PaneTitle.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import queue from '@/api/queue'
|
import queue from '@/api/queue'
|
||||||
import services from '@/api/services'
|
import services from '@/api/services'
|
||||||
import { useServicesStore } from '@/stores/services'
|
|
||||||
|
|
||||||
const PAGE_SIZE = 50
|
const PAGE_SIZE = 50
|
||||||
|
|
||||||
@ -45,17 +43,16 @@ export default {
|
|||||||
PaneTitle
|
PaneTitle
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
services.spotify().then((data) => {
|
services.spotify().then(({ api, configuration }) => {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
spotifyApi.getArtist(to.params.id),
|
api.artists.get(to.params.id),
|
||||||
spotifyApi.getArtistAlbums(to.params.id, {
|
api.artists.albums(
|
||||||
include_groups: 'album,single',
|
to.params.id,
|
||||||
limit: PAGE_SIZE,
|
'album,single',
|
||||||
market: useServicesStore().spotify.webapi_country,
|
configuration.webapi_country,
|
||||||
offset: 0
|
PAGE_SIZE,
|
||||||
})
|
0
|
||||||
|
)
|
||||||
]).then(([artist, albums]) => {
|
]).then(([artist, albums]) => {
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.artist = artist
|
vm.artist = artist
|
||||||
@ -66,9 +63,6 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setup() {
|
|
||||||
return { servicesStore: useServicesStore() }
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
albums: [],
|
albums: [],
|
||||||
@ -93,15 +87,15 @@ export default {
|
|||||||
this.offset += data.limit
|
this.offset += data.limit
|
||||||
},
|
},
|
||||||
load({ loaded }) {
|
load({ loaded }) {
|
||||||
services.spotify().then((data) => {
|
services.spotify().then(({ api, configuration }) => {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
api.artists
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
.albums(
|
||||||
spotifyApi
|
this.artist.id,
|
||||||
.getArtistAlbums(this.artist.id, {
|
'album,single',
|
||||||
include_groups: 'album,single',
|
configuration.webapi_country,
|
||||||
limit: PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
offset: this.offset
|
this.offset
|
||||||
})
|
)
|
||||||
.then((albums) => {
|
.then((albums) => {
|
||||||
this.appendAlbums(albums)
|
this.appendAlbums(albums)
|
||||||
loaded(albums.items.length, PAGE_SIZE)
|
loaded(albums.items.length, PAGE_SIZE)
|
||||||
|
|||||||
@ -41,7 +41,6 @@ import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
|||||||
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
||||||
import ListPlaylistsSpotify from '@/components/ListPlaylistsSpotify.vue'
|
import ListPlaylistsSpotify from '@/components/ListPlaylistsSpotify.vue'
|
||||||
import PaneTitle from '@/components/PaneTitle.vue'
|
import PaneTitle from '@/components/PaneTitle.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
import services from '@/api/services'
|
import services from '@/api/services'
|
||||||
|
|
||||||
@ -55,18 +54,15 @@ export default {
|
|||||||
TabsMusic
|
TabsMusic
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
services.spotify().then((data) => {
|
services.spotify().then(({ api, configuration }) => {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
spotifyApi.getNewReleases({
|
api.browse.getNewReleases(configuration.webapi_country, 3),
|
||||||
country: data.webapi_country,
|
api.browse.getFeaturedPlaylists(
|
||||||
limit: 3
|
configuration.webapi_country,
|
||||||
}),
|
null,
|
||||||
spotifyApi.getFeaturedPlaylists({
|
null,
|
||||||
country: data.webapi_country,
|
3
|
||||||
limit: 3
|
)
|
||||||
})
|
|
||||||
]).then((response) => {
|
]).then((response) => {
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.albums = response[0].albums.items
|
vm.albums = response[0].albums.items
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ListPlaylistsSpotify from '@/components/ListPlaylistsSpotify.vue'
|
import ListPlaylistsSpotify from '@/components/ListPlaylistsSpotify.vue'
|
||||||
import PaneTitle from '@/components/PaneTitle.vue'
|
import PaneTitle from '@/components/PaneTitle.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
import services from '@/api/services'
|
import services from '@/api/services'
|
||||||
|
|
||||||
@ -27,14 +26,9 @@ export default {
|
|||||||
TabsMusic
|
TabsMusic
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
services.spotify().then((data) => {
|
services.spotify().then(({ api, configuration }) => {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
api.browse
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
.getFeaturedPlaylists(configuration.webapi_country, null, null, 50)
|
||||||
spotifyApi
|
|
||||||
.getFeaturedPlaylists({
|
|
||||||
country: data.webapi_country,
|
|
||||||
limit: 50
|
|
||||||
})
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.playlists = response.playlists.items
|
vm.playlists = response.playlists.items
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
||||||
import PaneTitle from '@/components/PaneTitle.vue'
|
import PaneTitle from '@/components/PaneTitle.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
import services from '@/api/services'
|
import services from '@/api/services'
|
||||||
|
|
||||||
@ -27,14 +26,9 @@ export default {
|
|||||||
TabsMusic
|
TabsMusic
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
services.spotify().then((data) => {
|
services.spotify().then(({ api, configuration }) => {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
api.browse
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
.getNewReleases(configuration.webapi_country, 50)
|
||||||
spotifyApi
|
|
||||||
.getNewReleases({
|
|
||||||
country: data.webapi_country,
|
|
||||||
limit: 50
|
|
||||||
})
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.albums = response.albums.items
|
vm.albums = response.albums.items
|
||||||
|
|||||||
@ -37,9 +37,8 @@ import ControlButton from '@/components/ControlButton.vue'
|
|||||||
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
||||||
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
|
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
|
||||||
import PaneTitle from '@/components/PaneTitle.vue'
|
import PaneTitle from '@/components/PaneTitle.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import queue from '@/api/queue'
|
import queue from '@/api/queue'
|
||||||
import { useServicesStore } from '@/stores/services'
|
import services from '@/api/services'
|
||||||
|
|
||||||
const PAGE_SIZE = 50
|
const PAGE_SIZE = 50
|
||||||
|
|
||||||
@ -53,28 +52,27 @@ export default {
|
|||||||
PaneTitle
|
PaneTitle
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
services.spotify().then(({ api, configuration }) => {
|
||||||
spotifyApi.setAccessToken(useServicesStore().spotify.webapi_token)
|
Promise.all([
|
||||||
Promise.all([
|
api.playlists.getPlaylist(to.params.id),
|
||||||
spotifyApi.getPlaylist(to.params.id),
|
api.playlists.getPlaylistItems(
|
||||||
spotifyApi.getPlaylistTracks(to.params.id, {
|
to.params.id,
|
||||||
limit: PAGE_SIZE,
|
configuration.webapi_country,
|
||||||
market: useServicesStore().$state.spotify.webapi_country,
|
null,
|
||||||
offset: 0
|
PAGE_SIZE,
|
||||||
})
|
0
|
||||||
]).then(([playlist, tracks]) => {
|
)
|
||||||
next((vm) => {
|
]).then(([playlist, tracks]) => {
|
||||||
vm.playlist = playlist
|
next((vm) => {
|
||||||
vm.tracks = []
|
vm.playlist = playlist
|
||||||
vm.total = 0
|
vm.tracks = []
|
||||||
vm.offset = 0
|
vm.total = 0
|
||||||
vm.appendTracks(tracks)
|
vm.offset = 0
|
||||||
|
vm.appendTracks(tracks)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setup() {
|
|
||||||
return { servicesStore: useServicesStore() }
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
@ -118,18 +116,20 @@ export default {
|
|||||||
this.offset += data.limit
|
this.offset += data.limit
|
||||||
},
|
},
|
||||||
load({ loaded }) {
|
load({ loaded }) {
|
||||||
const spotifyApi = new SpotifyWebApi()
|
services.spotify().then(({ api, configuration }) => {
|
||||||
spotifyApi.setAccessToken(this.servicesStore.spotify.webapi_token)
|
api.playlists
|
||||||
spotifyApi
|
.getPlaylistItems(
|
||||||
.getPlaylistTracks(this.playlist.id, {
|
this.playlist.id,
|
||||||
limit: PAGE_SIZE,
|
configuration.webapi_country,
|
||||||
market: this.servicesStore.spotify.webapi_country,
|
null,
|
||||||
offset: this.offset
|
PAGE_SIZE,
|
||||||
})
|
this.offset
|
||||||
.then((data) => {
|
)
|
||||||
this.appendTracks(data)
|
.then((data) => {
|
||||||
loaded(data.items.length, PAGE_SIZE)
|
this.appendTracks(data)
|
||||||
})
|
loaded(data.items.length, PAGE_SIZE)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
play() {
|
play() {
|
||||||
this.showDetailsModal = false
|
this.showDetailsModal = false
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import ListAlbumsSpotify from '@/components/ListAlbumsSpotify.vue'
|
|||||||
import ListArtistsSpotify from '@/components/ListArtistsSpotify.vue'
|
import ListArtistsSpotify from '@/components/ListArtistsSpotify.vue'
|
||||||
import ListPlaylistsSpotify from '@/components/ListPlaylistsSpotify.vue'
|
import ListPlaylistsSpotify from '@/components/ListPlaylistsSpotify.vue'
|
||||||
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
|
||||||
import services from '@/api/services'
|
import services from '@/api/services'
|
||||||
import { useSearchStore } from '@/stores/search'
|
import { useSearchStore } from '@/stores/search'
|
||||||
|
|
||||||
@ -95,16 +94,17 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
searchItems() {
|
searchItems() {
|
||||||
return services.spotify().then((data) => {
|
return services
|
||||||
this.parameters.market = data.webapi_country
|
.spotify()
|
||||||
const spotifyApi = new SpotifyWebApi()
|
.then(({ api, configuration }) =>
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
api.search(
|
||||||
return spotifyApi.search(
|
this.searchStore.query,
|
||||||
this.searchStore.query,
|
this.types,
|
||||||
this.types,
|
configuration.webapi_country,
|
||||||
this.parameters
|
this.parameters.limit,
|
||||||
|
this.parameters.offset
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
|
||||||
},
|
},
|
||||||
searchLibrary() {
|
searchLibrary() {
|
||||||
this.$router.push({ name: 'search-library' })
|
this.$router.push({ name: 'search-library' })
|
||||||
|
|||||||
@ -7,18 +7,8 @@ export const useServicesStore = defineStore('ServicesStore', {
|
|||||||
this.lastfm = await services.lastfm()
|
this.lastfm = await services.lastfm()
|
||||||
},
|
},
|
||||||
initialiseSpotify() {
|
initialiseSpotify() {
|
||||||
services.spotify().then((data) => {
|
services.spotify().then(({ configuration }) => {
|
||||||
this.spotify = data
|
this.spotify = configuration
|
||||||
if (this.spotifyTimerId > 0) {
|
|
||||||
clearTimeout(this.spotifyTimerId)
|
|
||||||
this.spotifyTimerId = 0
|
|
||||||
}
|
|
||||||
if (data.webapi_token_expires_in > 0 && data.webapi_token) {
|
|
||||||
this.spotifyTimerId = setTimeout(
|
|
||||||
() => this.initialiseSpotify(),
|
|
||||||
1000 * data.webapi_token_expires_in
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -41,5 +31,5 @@ export const useServicesStore = defineStore('ServicesStore', {
|
|||||||
requiredSpotifyScopes: (state) =>
|
requiredSpotifyScopes: (state) =>
|
||||||
state.spotify.webapi_required_scope?.split(' ') ?? []
|
state.spotify.webapi_required_scope?.split(' ') ?? []
|
||||||
},
|
},
|
||||||
state: () => ({ lastfm: {}, spotify: {}, spotifyTimerId: 0 })
|
state: () => ({ lastfm: {}, spotify: {} })
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user