diff --git a/web-src/src/pages/PageAlbumSpotify.vue b/web-src/src/pages/PageAlbumSpotify.vue index 8f70bf6d5d..e34ca9c52c 100644 --- a/web-src/src/pages/PageAlbumSpotify.vue +++ b/web-src/src/pages/PageAlbumSpotify.vue @@ -122,11 +122,9 @@ export default { data() { return { album: { artists: [{}], tracks: {} }, - - show_track_details_modal: false, selected_track: {}, - - show_details_modal: false + show_details_modal: false, + show_track_details_modal: false } }, diff --git a/web-src/src/pages/PageSearchLibrary.vue b/web-src/src/pages/PageSearchLibrary.vue index ce2c1387fd..873b9c2a3a 100644 --- a/web-src/src/pages/PageSearchLibrary.vue +++ b/web-src/src/pages/PageSearchLibrary.vue @@ -283,14 +283,14 @@ export default { data() { return { - search_query: '', - tracks: new GroupByList(), - artists: new GroupByList(), albums: new GroupByList(), + artists: new GroupByList(), + audiobooks: new GroupByList(), composers: new GroupByList(), playlists: new GroupByList(), - audiobooks: new GroupByList(), - podcasts: new GroupByList() + podcasts: new GroupByList(), + search_query: '', + tracks: new GroupByList() } }, @@ -298,62 +298,55 @@ export default { recent_searches() { return this.$store.state.recent_searches }, - - show_tracks() { - return this.$route.query.type && this.$route.query.type.includes('track') - }, - show_all_tracks_button() { - return this.tracks.total > this.tracks.items.length - }, - - show_artists() { - return this.$route.query.type && this.$route.query.type.includes('artist') - }, - show_all_artists_button() { - return this.artists.total > this.artists.items.length - }, - show_albums() { return this.$route.query.type && this.$route.query.type.includes('album') }, show_all_albums_button() { return this.albums.total > this.albums.items.length }, - - show_composers() { - return ( - this.$route.query.type && this.$route.query.type.includes('composer') - ) + show_all_artists_button() { + return this.artists.total > this.artists.items.length + }, + show_all_audiobooks_button() { + return this.audiobooks.total > this.audiobooks.items.length }, show_all_composers_button() { return this.composers.total > this.composers.items.length }, - - show_playlists() { - return ( - this.$route.query.type && this.$route.query.type.includes('playlist') - ) - }, show_all_playlists_button() { return this.playlists.total > this.playlists.items.length }, - + show_all_podcasts_button() { + return this.podcasts.total > this.podcasts.items.length + }, + show_all_tracks_button() { + return this.tracks.total > this.tracks.items.length + }, + show_artists() { + return this.$route.query.type && this.$route.query.type.includes('artist') + }, show_audiobooks() { return ( this.$route.query.type && this.$route.query.type.includes('audiobook') ) }, - show_all_audiobooks_button() { - return this.audiobooks.total > this.audiobooks.items.length + show_composers() { + return ( + this.$route.query.type && this.$route.query.type.includes('composer') + ) + }, + show_playlists() { + return ( + this.$route.query.type && this.$route.query.type.includes('playlist') + ) }, - show_podcasts() { return ( this.$route.query.type && this.$route.query.type.includes('podcast') ) }, - show_all_podcasts_button() { - return this.podcasts.total > this.podcasts.items.length + show_tracks() { + return this.$route.query.type && this.$route.query.type.includes('track') } }, @@ -398,7 +391,7 @@ export default { } if (query.query.startsWith('query:')) { - searchParams.expression = query.query.replace(/^query:/, '').trim() + searchParams.expression = query.query.replace(/^query:/u, '').trim() } else { searchParams.query = query.query } @@ -428,7 +421,7 @@ export default { } if (query.query.startsWith('query:')) { - searchParams.expression = query.query.replace(/^query:/, '').trim() + searchParams.expression = query.query.replace(/^query:/u, '').trim() } else { searchParams.expression = `((album includes "${query.query}" or artist includes "${query.query}") and media_kind is audiobook)` } @@ -454,7 +447,7 @@ export default { } if (query.query.startsWith('query:')) { - searchParams.expression = query.query.replace(/^query:/, '').trim() + searchParams.expression = query.query.replace(/^query:/u, '').trim() } else { searchParams.expression = `((album includes "${query.query}" or artist includes "${query.query}") and media_kind is podcast)` } @@ -477,10 +470,10 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'track,artist,album,playlist,audiobook,podcast,composer', - query: this.search_query, limit: 3, - offset: 0 + offset: 0, + query: this.search_query, + type: 'track,artist,album,playlist,audiobook,podcast,composer' } }) this.$refs.search_field.blur() @@ -490,8 +483,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'track', - query: this.$route.query.query + query: this.$route.query.query, + type: 'track' } }) }, @@ -500,8 +493,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'artist', - query: this.$route.query.query + query: this.$route.query.query, + type: 'artist' } }) }, @@ -510,8 +503,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'album', - query: this.$route.query.query + query: this.$route.query.query, + type: 'album' } }) }, @@ -520,8 +513,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'tracks', - query: this.$route.query.query + query: this.$route.query.query, + type: 'tracks' } }) }, @@ -530,8 +523,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'playlist', - query: this.$route.query.query + query: this.$route.query.query, + type: 'playlist' } }) }, @@ -540,8 +533,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'audiobook', - query: this.$route.query.query + query: this.$route.query.query, + type: 'audiobook' } }) }, @@ -550,8 +543,8 @@ export default { this.$router.push({ name: 'search-library', query: { - type: 'podcast', - query: this.$route.query.query + query: this.$route.query.query, + type: 'podcast' } }) }, diff --git a/web-src/src/pages/PageSearchSpotify.vue b/web-src/src/pages/PageSearchSpotify.vue index 48ed506d6a..c0869b3e42 100644 --- a/web-src/src/pages/PageSearchSpotify.vue +++ b/web-src/src/pages/PageSearchSpotify.vue @@ -307,73 +307,62 @@ export default { data() { return { - search_query: '', - tracks: { items: [], total: 0 }, - artists: { items: [], total: 0 }, albums: { items: [], total: 0 }, + artists: { items: [], total: 0 }, playlists: { items: [], total: 0 }, - query: {}, search_param: {}, - - show_track_details_modal: false, + search_query: '', + selected_album: {}, + selected_artist: {}, + selected_playlist: {}, selected_track: {}, - show_album_details_modal: false, - selected_album: {}, - show_artist_details_modal: false, - selected_artist: {}, - show_playlist_details_modal: false, - selected_playlist: {}, - + show_track_details_modal: false, + tracks: { items: [], total: 0 }, validSearchTypes: ['track', 'artist', 'album', 'playlist'] } }, computed: { + is_visible_artwork() { + return this.$store.getters.settings_option( + 'webinterface', + 'show_cover_artwork_in_album_lists' + ).value + }, recent_searches() { return this.$store.state.recent_searches.filter( (search) => !search.startsWith('query:') ) }, - - show_tracks() { - return this.$route.query.type && this.$route.query.type.includes('track') - }, - show_all_tracks_button() { - return this.tracks.total > this.tracks.items.length + show_albums() { + return this.$route.query.type && this.$route.query.type.includes('album') }, - - show_artists() { - return this.$route.query.type && this.$route.query.type.includes('artist') + show_all_albums_button() { + return this.albums.total > this.albums.items.length }, show_all_artists_button() { return this.artists.total > this.artists.items.length }, - - show_albums() { - return this.$route.query.type && this.$route.query.type.includes('album') + show_all_playlists_button() { + return this.playlists.total > this.playlists.items.length }, - show_all_albums_button() { - return this.albums.total > this.albums.items.length + show_all_tracks_button() { + return this.tracks.total > this.tracks.items.length + }, + show_artists() { + return this.$route.query.type && this.$route.query.type.includes('artist') }, - show_playlists() { return ( this.$route.query.type && this.$route.query.type.includes('playlist') ) }, - show_all_playlists_button() { - return this.playlists.total > this.playlists.items.length - }, - - is_visible_artwork() { - return this.$store.getters.settings_option( - 'webinterface', - 'show_cover_artwork_in_album_lists' - ).value + show_tracks() { + return this.$route.query.type && this.$route.query.type.includes('track') } }, @@ -390,16 +379,97 @@ export default { }, methods: { + artwork_url(album) { + if (album.images && album.images.length > 0) { + return album.images[0].url + } + return '' + }, + new_search() { + if (!this.search_query) { + return + } + this.$router.push({ + name: 'search-spotify', + query: { + limit: 3, + offset: 0, + query: this.search_query, + type: 'track,artist,album,playlist,audiobook,podcast' + } + }) + this.$refs.search_field.blur() + }, + open_album(album) { + this.$router.push({ + name: 'music-spotify-album', + params: { id: album.id } + }) + }, + open_album_dialog(album) { + this.selected_album = album + this.show_album_details_modal = true + }, + open_artist_dialog(artist) { + this.selected_artist = artist + this.show_artist_details_modal = true + }, + open_playlist_dialog(playlist) { + this.selected_playlist = playlist + this.show_playlist_details_modal = true + }, + open_recent_search(query) { + this.search_query = query + this.new_search() + }, + open_search_albums() { + this.$router.push({ + name: 'search-spotify', + query: { + query: this.$route.query.query, + type: 'album' + } + }) + }, + open_search_artists() { + this.$router.push({ + name: 'search-spotify', + query: { + query: this.$route.query.query, + type: 'artist' + } + }) + }, + open_search_playlists() { + this.$router.push({ + name: 'search-spotify', + query: { + query: this.$route.query.query, + type: 'playlist' + } + }) + }, + open_search_tracks() { + this.$router.push({ + name: 'search-spotify', + query: { + query: this.$route.query.query, + type: 'track' + } + }) + }, + open_track_dialog(track) { + this.selected_track = track + this.show_track_details_modal = true + }, reset() { this.tracks = { items: [], total: 0 } this.artists = { items: [], total: 0 } this.albums = { items: [], total: 0 } this.playlists = { items: [], total: 0 } }, - search() { this.reset() - // If no search query present reset and focus search field if ( !this.query.query || @@ -410,30 +480,20 @@ export default { this.$refs.search_field.focus() return } - this.search_query = this.query.query this.search_param.limit = this.query.limit ? this.query.limit : PAGE_SIZE this.search_param.offset = this.query.offset ? this.query.offset : 0 - this.$store.commit(types.ADD_RECENT_SEARCH, this.query.query) - this.search_all() }, - - spotify_search() { - return webapi.spotify().then(({ data }) => { - this.search_param.market = data.webapi_country - - const spotifyApi = new SpotifyWebApi() - spotifyApi.setAccessToken(data.webapi_token) - - const types = this.query.type - .split(',') - .filter((type) => this.validSearchTypes.includes(type)) - return spotifyApi.search(this.query.query, types, this.search_param) + search_albums_next({ loaded }) { + this.spotify_search().then((data) => { + this.albums.items = this.albums.items.concat(data.albums.items) + this.albums.total = data.albums.total + this.search_param.offset += data.albums.limit + loaded(data.albums.items.length, PAGE_SIZE) }) }, - search_all() { this.spotify_search().then((data) => { this.tracks = data.tracks ? data.tracks : { items: [], total: 0 } @@ -444,141 +504,40 @@ export default { : { items: [], total: 0 } }) }, - - search_tracks_next({ loaded }) { - this.spotify_search().then((data) => { - this.tracks.items = this.tracks.items.concat(data.tracks.items) - this.tracks.total = data.tracks.total - this.search_param.offset += data.tracks.limit - - loaded(data.tracks.items.length, PAGE_SIZE) - }) - }, - search_artists_next({ loaded }) { this.spotify_search().then((data) => { this.artists.items = this.artists.items.concat(data.artists.items) this.artists.total = data.artists.total this.search_param.offset += data.artists.limit - loaded(data.artists.items.length, PAGE_SIZE) }) }, - - search_albums_next({ loaded }) { - this.spotify_search().then((data) => { - this.albums.items = this.albums.items.concat(data.albums.items) - this.albums.total = data.albums.total - this.search_param.offset += data.albums.limit - - loaded(data.albums.items.length, PAGE_SIZE) - }) - }, - search_playlists_next({ loaded }) { this.spotify_search().then((data) => { this.playlists.items = this.playlists.items.concat(data.playlists.items) this.playlists.total = data.playlists.total this.search_param.offset += data.playlists.limit - loaded(data.playlists.items.length, PAGE_SIZE) }) }, - - new_search() { - if (!this.search_query) { - return - } - - this.$router.push({ - name: 'search-spotify', - query: { - type: 'track,artist,album,playlist,audiobook,podcast', - query: this.search_query, - limit: 3, - offset: 0 - } - }) - this.$refs.search_field.blur() - }, - - open_search_tracks() { - this.$router.push({ - name: 'search-spotify', - query: { - type: 'track', - query: this.$route.query.query - } - }) - }, - - open_search_artists() { - this.$router.push({ - name: 'search-spotify', - query: { - type: 'artist', - query: this.$route.query.query - } - }) - }, - - open_search_albums() { - this.$router.push({ - name: 'search-spotify', - query: { - type: 'album', - query: this.$route.query.query - } - }) - }, - - open_search_playlists() { - this.$router.push({ - name: 'search-spotify', - query: { - type: 'playlist', - query: this.$route.query.query - } + search_tracks_next({ loaded }) { + this.spotify_search().then((data) => { + this.tracks.items = this.tracks.items.concat(data.tracks.items) + this.tracks.total = data.tracks.total + this.search_param.offset += data.tracks.limit + loaded(data.tracks.items.length, PAGE_SIZE) }) }, - - open_recent_search(query) { - this.search_query = query - this.new_search() - }, - - open_track_dialog(track) { - this.selected_track = track - this.show_track_details_modal = true - }, - - open_album_dialog(album) { - this.selected_album = album - this.show_album_details_modal = true - }, - - open_artist_dialog(artist) { - this.selected_artist = artist - this.show_artist_details_modal = true - }, - - open_playlist_dialog(playlist) { - this.selected_playlist = playlist - this.show_playlist_details_modal = true - }, - - open_album(album) { - this.$router.push({ - name: 'music-spotify-album', - params: { id: album.id } + spotify_search() { + return webapi.spotify().then(({ data }) => { + this.search_param.market = data.webapi_country + const spotifyApi = new SpotifyWebApi() + spotifyApi.setAccessToken(data.webapi_token) + const types = this.query.type + .split(',') + .filter((type) => this.validSearchTypes.includes(type)) + return spotifyApi.search(this.query.query, types, this.search_param) }) - }, - - artwork_url(album) { - if (album.images && album.images.length > 0) { - return album.images[0].url - } - return '' } } } diff --git a/web-src/src/pages/PageSettingsOnlineServices.vue b/web-src/src/pages/PageSettingsOnlineServices.vue index 3ffcdf38b3..b31347a06e 100644 --- a/web-src/src/pages/PageSettingsOnlineServices.vue +++ b/web-src/src/pages/PageSettingsOnlineServices.vue @@ -140,9 +140,9 @@ export default { data() { return { lastfm_login: { - user: '', + errors: { error: '', password: '', user: '' }, password: '', - errors: { user: '', password: '', error: '' } + user: '' } } }, @@ -177,9 +177,6 @@ export default { }, methods: { - logout_spotify() { - webapi.spotify_logout() - }, login_lastfm() { webapi.lastfm_login(this.lastfm_login).then((response) => { this.lastfm_login.user = '' @@ -197,6 +194,9 @@ export default { }, logoutLastfm() { webapi.lastfm_logout() + }, + logout_spotify() { + webapi.spotify_logout() } } } diff --git a/web-src/src/store/index.js b/web-src/src/store/index.js index 642201ce7d..1d5cbe1243 100644 --- a/web-src/src/store/index.js +++ b/web-src/src/store/index.js @@ -5,9 +5,9 @@ export default createStore({ state() { return { albums_sort: 1, - artists_sort: 1, artist_albums_sort: 1, artist_tracks_sort: 1, + artists_sort: 1, composer_tracks_sort: 1, config: { buildoptions: [], @@ -17,6 +17,7 @@ export default createStore({ genre_tracks_sort: 1, hide_singles: false, hide_spotify: false, + lastfm: {}, library: { albums: 0, artists: 0, @@ -26,7 +27,6 @@ export default createStore({ updated_at: '01', updating: false }, - lastfm: {}, lyrics: { content: [], pane: false @@ -42,9 +42,9 @@ export default createStore({ item_id: 0, item_length_ms: 0, item_progress_ms: 0, + repeat: 'off', shuffle: false, state: 'stop', - repeat: 'off', volume: 0 }, queue: { @@ -79,14 +79,8 @@ export default createStore({ return item === undefined ? {} : item }, - settings_webinterface: (state) => { - if (state.settings) { - return state.settings.categories.find( - (elem) => elem.name === 'webinterface' - ) - } - return null - }, + settings_category: (state) => (categoryName) => + state.settings.categories.find((e) => e.name === categoryName), settings_option_recently_added_limit: (state, getters) => { if (getters.settings_webinterface) { @@ -100,28 +94,38 @@ export default createStore({ return 100 }, - settings_option_show_composer_now_playing: (state, getters) => { + settings_option: (state) => (categoryName, optionName) => { + const category = state.settings.categories.find( + (elem) => elem.name === categoryName + ) + if (!category) { + return {} + } + return category.options.find((elem) => elem.name === optionName) + }, + + settings_option_show_composer_for_genre: (state, getters) => { if (getters.settings_webinterface) { const option = getters.settings_webinterface.options.find( - (elem) => elem.name === 'show_composer_now_playing' + (elem) => elem.name === 'show_composer_for_genre' ) if (option) { return option.value } } - return false + return null }, - settings_option_show_composer_for_genre: (state, getters) => { + settings_option_show_composer_now_playing: (state, getters) => { if (getters.settings_webinterface) { const option = getters.settings_webinterface.options.find( - (elem) => elem.name === 'show_composer_for_genre' + (elem) => elem.name === 'show_composer_now_playing' ) if (option) { return option.value } } - return null + return false }, settings_option_show_filepath_now_playing: (state, getters) => { @@ -136,17 +140,13 @@ export default createStore({ return false }, - settings_category: (state) => (categoryName) => - state.settings.categories.find((e) => e.name === categoryName), - - settings_option: (state) => (categoryName, optionName) => { - const category = state.settings.categories.find( - (elem) => elem.name === categoryName - ) - if (!category) { - return {} + settings_webinterface: (state) => { + if (state.settings) { + return state.settings.categories.find( + (elem) => elem.name === 'webinterface' + ) } - return category.options.find((elem) => elem.name === optionName) + return null } }, @@ -278,10 +278,10 @@ export default createStore({ add_notification({ commit, state }, notification) { const newNotification = { id: state.notifications.next_id++, - type: notification.type, text: notification.text, + timeout: notification.timeout, topic: notification.topic, - timeout: notification.timeout + type: notification.type } commit(types.ADD_NOTIFICATION, newNotification)