[web-src] Update to Vue CLI 4 and fix linter issues

This commit is contained in:
chme 2020-04-11 19:43:53 +02:00
parent 72f93eb97f
commit 52d37b883c
55 changed files with 4457 additions and 2055 deletions

View File

@ -3,7 +3,7 @@ module.exports = {
env: { env: {
node: true node: true
}, },
'extends': [ extends: [
'plugin:vue/essential', 'plugin:vue/essential',
'@vue/standard' '@vue/standard'
], ],

View File

@ -1,5 +1,5 @@
module.exports = { module.exports = {
presets: [ presets: [
'@vue/app' '@vue/cli-plugin-babel/preset'
] ]
} }

6324
web-src/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,19 @@
{ {
"name": "forked-daapd-web", "name": "forked-daapd-web",
"version": "0.7.0", "version": "0.7.0",
"private": true,
"description": "forked-daapd web interface", "description": "forked-daapd web interface",
"author": "chme <christian.meffert@googlemail.com>", "author": "chme <christian.meffert@googlemail.com>",
"license": "GPL-2.0",
"private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"dev": "vue-cli-service serve",
"build": "vue-cli-service build --no-clean", "build": "vue-cli-service build --no-clean",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint",
"dev": "vue-cli-service serve"
}, },
"dependencies": { "dependencies": {
"axios": "^0.19.2", "axios": "^0.19.2",
"bulma": "^0.8.2", "bulma": "^0.8.2",
"core-js": "^3.6.4",
"mdi": "^2.2.43", "mdi": "^2.2.43",
"moment": "^2.24.0", "moment": "^2.24.0",
"moment-duration-format": "^2.3.2", "moment-duration-format": "^2.3.2",
@ -30,10 +30,18 @@
"vuex": "^3.1.3" "vuex": "^3.1.3"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^3.12.1", "@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-plugin-eslint": "^3.12.1", "@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-service": "^3.12.1", "@vue/cli-service": "^4.3.1",
"@vue/eslint-config-standard": "^4.0.0", "@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"
} },
"license": "GPL-2.0"
} }

View File

@ -50,7 +50,7 @@ export default {
this.$router.beforeEach((to, from, next) => { this.$router.beforeEach((to, from, next) => {
if (to.meta.show_progress) { if (to.meta.show_progress) {
if (to.meta.progress !== undefined) { if (to.meta.progress !== undefined) {
let meta = to.meta.progress const meta = to.meta.progress
this.$Progress.parseMeta(meta) this.$Progress.parseMeta(meta)
} }
this.$Progress.start() this.$Progress.start()

View File

@ -34,7 +34,7 @@ export default {
methods: { methods: {
play: function () { play: function () {
webapi.player_play({ 'item_id': this.item.id }) webapi.player_play({ item_id: this.item.id })
} }
} }
} }

View File

@ -95,7 +95,7 @@ export default {
play: function () { play: function () {
this.$emit('close') this.$emit('close')
webapi.player_play({ 'item_id': this.item.id }) webapi.player_play({ item_id: this.item.id })
}, },
open_album: function () { open_album: function () {

View File

@ -152,14 +152,14 @@ export default {
}, },
mark_new: function () { mark_new: function () {
webapi.library_track_update(this.track.id, { 'play_count': 'reset' }).then(() => { webapi.library_track_update(this.track.id, { play_count: 'reset' }).then(() => {
this.$emit('play_count_changed') this.$emit('play_count_changed')
this.$emit('close') this.$emit('close')
}) })
}, },
mark_played: function () { mark_played: function () {
webapi.library_track_update(this.track.id, { 'play_count': 'increment' }).then(() => { webapi.library_track_update(this.track.id, { play_count: 'increment' }).then(() => {
this.$emit('play_count_changed') this.$emit('play_count_changed')
this.$emit('close') this.$emit('close')
}) })

View File

@ -61,7 +61,7 @@ export default {
set_enabled: function () { set_enabled: function () {
const values = { const values = {
'selected': !this.output.selected selected: !this.output.selected
} }
webapi.output_update(this.output.id, values) webapi.output_update(this.output.id, values)
} }

View File

@ -11,8 +11,8 @@ export default {
name: 'PlayerButtonPlayPause', name: 'PlayerButtonPlayPause',
props: { props: {
'icon_style': String, icon_style: String,
'show_disabled_message': Boolean show_disabled_message: Boolean
}, },
computed: { computed: {

View File

@ -19,11 +19,10 @@
</a> </a>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="album in albums.items" <list-item-album v-for="album in albums_filtered"
:key="album.id" :key="album.id"
:album="album" :album="album"
@click="open_album(album)" @click="open_album(album)">
v-if="!hide_singles || album.track_count > 2">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -77,6 +76,10 @@ export default {
computed: { computed: {
hide_singles () { hide_singles () {
return this.$store.state.hide_singles return this.$store.state.hide_singles
},
albums_filtered () {
return this.albums.items.filter(album => !this.hide_singles || album.track_count > 2)
} }
}, },

View File

@ -19,11 +19,10 @@
</a> </a>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-artist v-for="artist in artists.items" <list-item-artist v-for="artist in artists_filtered"
:key="artist.id" :key="artist.id"
:artist="artist" :artist="artist"
@click="open_artist(artist)" @click="open_artist(artist)">
v-if="!hide_singles || artist.track_count > (artist.album_count * 2)">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(artist)"> <a @click="open_dialog(artist)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -79,6 +78,10 @@ export default {
return [...new Set(this.artists.items return [...new Set(this.artists.items
.filter(artist => !this.$store.state.hide_singles || artist.track_count > (artist.album_count * 2)) .filter(artist => !this.$store.state.hide_singles || artist.track_count > (artist.album_count * 2))
.map(artist => artist.name_sort.charAt(0).toUpperCase()))] .map(artist => artist.name_sort.charAt(0).toUpperCase()))]
},
artists_filtered () {
return this.artists.items.filter(artist => !this.hide_singles || artist.track_count > (artist.album_count * 2))
} }
}, },

View File

@ -36,7 +36,6 @@
<script> <script>
import { LoadDataBeforeEnterMixin } from './mixin' import { LoadDataBeforeEnterMixin } from './mixin'
import ContentWithHeading from '@/templates/ContentWithHeading' import ContentWithHeading from '@/templates/ContentWithHeading'
import TabsMusic from '@/components/TabsMusic'
import IndexButtonList from '@/components/IndexButtonList' import IndexButtonList from '@/components/IndexButtonList'
import ListItemAlbums from '@/components/ListItemAlbum' import ListItemAlbums from '@/components/ListItemAlbum'
import ModalDialogAlbum from '@/components/ModalDialogAlbum' import ModalDialogAlbum from '@/components/ModalDialogAlbum'
@ -57,7 +56,7 @@ const genreData = {
export default { export default {
name: 'PageGenre', name: 'PageGenre',
mixins: [LoadDataBeforeEnterMixin(genreData)], mixins: [LoadDataBeforeEnterMixin(genreData)],
components: { ContentWithHeading, TabsMusic, IndexButtonList, ListItemAlbums, ModalDialogAlbum, ModalDialogGenre }, components: { ContentWithHeading, IndexButtonList, ListItemAlbums, ModalDialogAlbum, ModalDialogGenre },
data () { data () {
return { return {

View File

@ -25,7 +25,6 @@
<script> <script>
import { LoadDataBeforeEnterMixin } from './mixin' import { LoadDataBeforeEnterMixin } from './mixin'
import ContentWithHeading from '@/templates/ContentWithHeading' import ContentWithHeading from '@/templates/ContentWithHeading'
import TabsMusic from '@/components/TabsMusic'
import ListItemPlaylist from '@/components/ListItemPlaylist' import ListItemPlaylist from '@/components/ListItemPlaylist'
import ModalDialogPlaylist from '@/components/ModalDialogPlaylist' import ModalDialogPlaylist from '@/components/ModalDialogPlaylist'
import webapi from '@/webapi' import webapi from '@/webapi'
@ -47,7 +46,7 @@ const playlistsData = {
export default { export default {
name: 'PagePlaylists', name: 'PagePlaylists',
mixins: [LoadDataBeforeEnterMixin(playlistsData)], mixins: [LoadDataBeforeEnterMixin(playlistsData)],
components: { ContentWithHeading, TabsMusic, ListItemPlaylist, ModalDialogPlaylist }, components: { ContentWithHeading, ListItemPlaylist, ModalDialogPlaylist },
data () { data () {
return { return {

View File

@ -106,7 +106,7 @@ export default {
}, },
mark_all_played: function () { mark_all_played: function () {
webapi.library_album_track_update(this.album.id, { 'play_count': 'played' }).then(({ data }) => ( webapi.library_album_track_update(this.album.id, { play_count: 'played' }).then(({ data }) => (
this.tracks.forEach(track => { this.tracks.forEach(track => {
if (track.play_count === 0) { if (track.play_count === 0) {
track.play_count = 1 track.play_count = 1

View File

@ -132,7 +132,7 @@ export default {
mark_all_played: function () { mark_all_played: function () {
this.new_episodes.items.forEach(ep => { this.new_episodes.items.forEach(ep => {
webapi.library_track_update(ep.id, { 'play_count': 'increment' }) webapi.library_track_update(ep.id, { play_count: 'increment' })
}) })
this.new_episodes.items = { } this.new_episodes.items = { }
}, },

View File

@ -217,10 +217,10 @@ export default {
} }
var searchParams = { var searchParams = {
'type': route.query.type, type: route.query.type,
'query': this.smart_query ? undefined : route.query.query, query: this.smart_query ? undefined : route.query.query,
'expression': this.smart_query ? route.query.query : undefined, expression: this.smart_query ? route.query.query : undefined,
'media_kind': 'music' media_kind: 'music'
} }
if (route.query.limit) { if (route.query.limit) {
@ -243,7 +243,8 @@ export default {
return return
} }
this.$router.push({ path: '/search/library', this.$router.push({
path: '/search/library',
query: { query: {
type: 'track,artist,album,playlist', type: 'track,artist,album,playlist',
query: this.search_query, query: this.search_query,
@ -255,7 +256,8 @@ export default {
}, },
open_search_tracks: function () { open_search_tracks: function () {
this.$router.push({ path: '/search/library', this.$router.push({
path: '/search/library',
query: { query: {
type: 'track', type: 'track',
query: this.$route.query.query query: this.$route.query.query
@ -264,7 +266,8 @@ export default {
}, },
open_search_artists: function () { open_search_artists: function () {
this.$router.push({ path: '/search/library', this.$router.push({
path: '/search/library',
query: { query: {
type: 'artist', type: 'artist',
query: this.$route.query.query query: this.$route.query.query
@ -273,7 +276,8 @@ export default {
}, },
open_search_albums: function () { open_search_albums: function () {
this.$router.push({ path: '/search/library', this.$router.push({
path: '/search/library',
query: { query: {
type: 'album', type: 'album',
query: this.$route.query.query query: this.$route.query.query
@ -282,7 +286,8 @@ export default {
}, },
open_search_playlists: function () { open_search_playlists: function () {
this.$router.push({ path: '/search/library', this.$router.push({
path: '/search/library',
query: { query: {
type: 'playlist', type: 'playlist',
query: this.$route.query.query query: this.$route.query.query

View File

@ -315,7 +315,8 @@ export default {
return return
} }
this.$router.push({ path: '/search/spotify', this.$router.push({
path: '/search/spotify',
query: { query: {
type: 'track,artist,album,playlist', type: 'track,artist,album,playlist',
query: this.search_query, query: this.search_query,
@ -327,7 +328,8 @@ export default {
}, },
open_search_tracks: function () { open_search_tracks: function () {
this.$router.push({ path: '/search/spotify', this.$router.push({
path: '/search/spotify',
query: { query: {
type: 'track', type: 'track',
query: this.$route.query.query query: this.$route.query.query
@ -336,7 +338,8 @@ export default {
}, },
open_search_artists: function () { open_search_artists: function () {
this.$router.push({ path: '/search/spotify', this.$router.push({
path: '/search/spotify',
query: { query: {
type: 'artist', type: 'artist',
query: this.$route.query.query query: this.$route.query.query
@ -345,7 +348,8 @@ export default {
}, },
open_search_albums: function () { open_search_albums: function () {
this.$router.push({ path: '/search/spotify', this.$router.push({
path: '/search/spotify',
query: { query: {
type: 'album', type: 'album',
query: this.$route.query.query query: this.$route.query.query
@ -354,7 +358,8 @@ export default {
}, },
open_search_playlists: function () { open_search_playlists: function () {
this.$router.push({ path: '/search/spotify', this.$router.push({
path: '/search/spotify',
query: { query: {
type: 'playlist', type: 'playlist',
query: this.$route.query.query query: this.$route.query.query

View File

@ -7,37 +7,37 @@ Vue.use(Vuex)
export default new Vuex.Store({ export default new Vuex.Store({
state: { state: {
config: { config: {
'websocket_port': 0, websocket_port: 0,
'version': '', version: '',
'buildoptions': [ ] buildoptions: []
}, },
settings: { settings: {
'categories': [] categories: []
}, },
library: { library: {
'artists': 0, artists: 0,
'albums': 0, albums: 0,
'songs': 0, songs: 0,
'db_playtime': 0, db_playtime: 0,
'updating': false updating: false
}, },
audiobooks_count: { }, audiobooks_count: { },
podcasts_count: { }, podcasts_count: { },
outputs: [], outputs: [],
player: { player: {
'state': 'stop', state: 'stop',
'repeat': 'off', repeat: 'off',
'consume': false, consume: false,
'shuffle': false, shuffle: false,
'volume': 0, volume: 0,
'item_id': 0, item_id: 0,
'item_length_ms': 0, item_length_ms: 0,
'item_progress_ms': 0 item_progress_ms: 0
}, },
queue: { queue: {
'version': 0, version: 0,
'count': 0, count: 0,
'items': [ ] items: []
}, },
lastfm: {}, lastfm: {},
spotify: {}, spotify: {},
@ -47,8 +47,8 @@ export default new Vuex.Store({
spotify_featured_playlists: [], spotify_featured_playlists: [],
notifications: { notifications: {
'next_id': 1, next_id: 1,
'list': [] list: []
}, },
recent_searches: [], recent_searches: [],
@ -181,11 +181,11 @@ export default new Vuex.Store({
actions: { actions: {
add_notification ({ commit, state }, notification) { add_notification ({ commit, state }, notification) {
const newNotification = { const newNotification = {
'id': state.notifications.next_id++, id: state.notifications.next_id++,
'type': notification.type, type: notification.type,
'text': notification.text, text: notification.text,
'topic': notification.topic, topic: notification.topic,
'timeout': notification.timeout timeout: notification.timeout
} }
commit(types.ADD_NOTIFICATION, newNotification) commit(types.ADD_NOTIFICATION, newNotification)

View File

@ -96,7 +96,7 @@ export default {
}, },
queue_save_playlist (name) { queue_save_playlist (name) {
return axios.post('/api/queue/save', undefined, { params: { 'name': name } }).then((response) => { return axios.post('/api/queue/save', undefined, { params: { name: name } }).then((response) => {
store.dispatch('add_notification', { text: 'Queue saved to playlist "' + name + '"', type: 'info', timeout: 2000 }) store.dispatch('add_notification', { text: 'Queue saved to playlist "' + name + '"', type: 'info', timeout: 2000 })
return Promise.resolve(response) return Promise.resolve(response)
}) })
@ -227,9 +227,9 @@ export default {
library_genre (genre) { library_genre (genre) {
var genreParams = { var genreParams = {
'type': 'albums', type: 'albums',
'media_kind': 'music', media_kind: 'music',
'expression': 'genre is "' + genre + '"' expression: 'genre is "' + genre + '"'
} }
return axios.get('/api/search', { return axios.get('/api/search', {
params: genreParams params: genreParams
@ -238,9 +238,9 @@ export default {
library_genre_tracks (genre) { library_genre_tracks (genre) {
var genreParams = { var genreParams = {
'type': 'tracks', type: 'tracks',
'media_kind': 'music', media_kind: 'music',
'expression': 'genre is "' + genre + '"' expression: 'genre is "' + genre + '"'
} }
return axios.get('/api/search', { return axios.get('/api/search', {
params: genreParams params: genreParams
@ -250,8 +250,8 @@ export default {
library_artist_tracks (artist) { library_artist_tracks (artist) {
if (artist) { if (artist) {
var artistParams = { var artistParams = {
'type': 'tracks', type: 'tracks',
'expression': 'songartistid is "' + artist + '"' expression: 'songartistid is "' + artist + '"'
} }
return axios.get('/api/search', { return axios.get('/api/search', {
params: artistParams params: artistParams
@ -265,8 +265,8 @@ export default {
library_podcasts_new_episodes () { library_podcasts_new_episodes () {
var episodesParams = { var episodesParams = {
'type': 'tracks', type: 'tracks',
'expression': 'media_kind is podcast and play_count = 0 ORDER BY time_added DESC' expression: 'media_kind is podcast and play_count = 0 ORDER BY time_added DESC'
} }
return axios.get('/api/search', { return axios.get('/api/search', {
params: episodesParams params: episodesParams
@ -275,8 +275,8 @@ export default {
library_podcast_episodes (albumId) { library_podcast_episodes (albumId) {
var episodesParams = { var episodesParams = {
'type': 'tracks', type: 'tracks',
'expression': 'media_kind is podcast and songalbumid is "' + albumId + '" ORDER BY time_added DESC' expression: 'media_kind is podcast and songalbumid is "' + albumId + '" ORDER BY time_added DESC'
} }
return axios.get('/api/search', { return axios.get('/api/search', {
params: episodesParams params: episodesParams
@ -284,7 +284,7 @@ export default {
}, },
library_add (url) { library_add (url) {
return axios.post('/api/library/add', undefined, { params: { 'url': url } }) return axios.post('/api/library/add', undefined, { params: { url: url } })
}, },
library_playlist_delete (playlistId) { library_playlist_delete (playlistId) {
@ -320,7 +320,7 @@ export default {
}, },
library_files (directory = undefined) { library_files (directory = undefined) {
var filesParams = { 'directory': directory } var filesParams = { directory: directory }
return axios.get('/api/library/files', { return axios.get('/api/library/files', {
params: filesParams params: filesParams
}) })