Merge pull request #1497 from chme/web/next

Update web interface
This commit is contained in:
Christian Meffert 2022-06-16 10:43:08 +02:00 committed by GitHub
commit 2da9bc9b13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
78 changed files with 739 additions and 611 deletions

File diff suppressed because one or more lines are too long

View File

@ -20,9 +20,9 @@
"reconnectingwebsocket": "^1.0.0",
"spotify-web-api-js": "^1.5.2",
"string-to-color": "^2.2.2",
"vue": "^3.2.36",
"vue": "^3.2.37",
"vue-i18n": "^9.1.10",
"vue-router": "^4.0.15",
"vue-router": "^4.0.16",
"vue-scrollto": "^2.20.0",
"vue3-click-away": "^1.2.4",
"vue3-lazyload": "^0.3.4",
@ -32,12 +32,12 @@
"devDependencies": {
"@intlify/vite-plugin-vue-i18n": "^3.4.0",
"@vitejs/plugin-vue": "^2.3.3",
"eslint": "^8.16.0",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-vue": "^9.1.0",
"prettier": "2.6.2",
"sass": "^1.52.2",
"vite": "^2.9.9"
"eslint-plugin-vue": "^9.1.1",
"prettier": "2.7.0",
"sass": "^1.52.3",
"vite": "^2.9.12"
}
},
"node_modules/@aacassandra/vue3-progressbar": {
@ -50,9 +50,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.18.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz",
"integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==",
"version": "7.18.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz",
"integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==",
"bin": {
"parser": "bin/babel-parser.js"
},
@ -311,36 +311,36 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.36.tgz",
"integrity": "sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz",
"integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/shared": "3.2.36",
"@vue/shared": "3.2.37",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.36.tgz",
"integrity": "sha512-tcOTAOiW4s24QLnq+ON6J+GRONXJ+A/mqKCORi0LSlIh8XQlNnlm24y8xIL8la+ZDgkdbjarQ9ZqYSvEja6gVA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz",
"integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==",
"dependencies": {
"@vue/compiler-core": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-core": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.36.tgz",
"integrity": "sha512-AvGb4bTj4W8uQ4BqaSxo7UwTEqX5utdRSMyHy58OragWlt8nEACQ9mIeQh3K4di4/SX+41+pJrLIY01lHAOFOA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz",
"integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.36",
"@vue/compiler-dom": "3.2.36",
"@vue/compiler-ssr": "3.2.36",
"@vue/reactivity-transform": "3.2.36",
"@vue/shared": "3.2.36",
"@vue/compiler-core": "3.2.37",
"@vue/compiler-dom": "3.2.37",
"@vue/compiler-ssr": "3.2.37",
"@vue/reactivity-transform": "3.2.37",
"@vue/shared": "3.2.37",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
@ -348,12 +348,12 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.36.tgz",
"integrity": "sha512-+KugInUFRvOxEdLkZwE+W43BqHyhBh0jpYXhmqw1xGq2dmE6J9eZ8UUSOKNhdHtQ/iNLWWeK/wPZkVLUf3YGaw==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz",
"integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==",
"dependencies": {
"@vue/compiler-dom": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-dom": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"node_modules/@vue/devtools-api": {
@ -362,60 +362,60 @@
"integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ=="
},
"node_modules/@vue/reactivity": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.36.tgz",
"integrity": "sha512-c2qvopo0crh9A4GXi2/2kfGYMxsJW4tVILrqRPydVGZHhq0fnzy6qmclWOhBFckEhmyxmpHpdJtIRYGeKcuhnA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz",
"integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==",
"dependencies": {
"@vue/shared": "3.2.36"
"@vue/shared": "3.2.37"
}
},
"node_modules/@vue/reactivity-transform": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.36.tgz",
"integrity": "sha512-Jk5o2BhpODC9XTA7o4EL8hSJ4JyrFWErLtClG3NH8wDS7ri9jBDWxI7/549T7JY9uilKsaNM+4pJASLj5dtRwA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz",
"integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.36",
"@vue/shared": "3.2.36",
"@vue/compiler-core": "3.2.37",
"@vue/shared": "3.2.37",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.36.tgz",
"integrity": "sha512-PTWBD+Lub+1U3/KhbCExrfxyS14hstLX+cBboxVHaz+kXoiDLNDEYAovPtxeTutbqtClIXtft+wcGdC+FUQ9qQ==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz",
"integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==",
"dependencies": {
"@vue/reactivity": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/reactivity": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.36.tgz",
"integrity": "sha512-gYPYblm7QXHVuBohqNRRT7Wez0f2Mx2D40rb4fleehrJU9CnkjG0phhcGEZFfGwCmHZRqBCRgbFWE98bPULqkg==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz",
"integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==",
"dependencies": {
"@vue/runtime-core": "3.2.36",
"@vue/shared": "3.2.36",
"@vue/runtime-core": "3.2.37",
"@vue/shared": "3.2.37",
"csstype": "^2.6.8"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.36.tgz",
"integrity": "sha512-uZE0+jfye6yYXWvAQYeHZv+f50sRryvy16uiqzk3jn8hEY8zTjI+rzlmZSGoE915k+W/Ol9XSw6vxOUD8dGkUg==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz",
"integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==",
"dependencies": {
"@vue/compiler-ssr": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-ssr": "3.2.37",
"@vue/shared": "3.2.37"
},
"peerDependencies": {
"vue": "3.2.36"
"vue": "3.2.37"
}
},
"node_modules/@vue/shared": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.36.tgz",
"integrity": "sha512-JtB41wXl7Au3+Nl3gD16Cfpj7k/6aCroZ6BbOiCMFCMvrOpkg/qQUXTso2XowaNqBbnkuGHurLAqkLBxNGc1hQ=="
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz",
"integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw=="
},
"node_modules/@vueform/slider": {
"version": "2.0.9",
@ -1131,9 +1131,9 @@
}
},
"node_modules/eslint": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz",
"integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==",
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz",
"integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.0",
@ -1195,9 +1195,9 @@
}
},
"node_modules/eslint-plugin-vue": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.1.0.tgz",
"integrity": "sha512-EPCeInPicQ/YyfOWJDr1yfEeSNoFCMzUus107lZyYi37xejdOolNzS5MXGXp8+9bkoKZMdv/1AcZzQebME6r+g==",
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.1.1.tgz",
"integrity": "sha512-W9n5PB1X2jzC7CK6riG0oAcxjmKrjTF6+keL1rni8n57DZeilx/Fulz+IRJK3lYseLNAygN0I62L7DvioW40Tw==",
"dev": true,
"dependencies": {
"eslint-utils": "^3.0.0",
@ -2083,9 +2083,9 @@
}
},
"node_modules/prettier": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.0.tgz",
"integrity": "sha512-nwoX4GMFgxoPC6diHvSwmK/4yU8FFH3V8XWtLQrbj4IBsK2pkYhG4kf/ljF/haaZ/aii+wNJqISrCDPgxGWDVQ==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
@ -2253,9 +2253,9 @@
}
},
"node_modules/sass": {
"version": "1.52.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.52.2.tgz",
"integrity": "sha512-mfHB2VSeFS7sZlPv9YohB9GB7yWIgQNTGniQwfQ04EoQN0wsQEv7SwpCwy/x48Af+Z3vDeFXz+iuXM3HK/phZQ==",
"version": "1.52.3",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.52.3.tgz",
"integrity": "sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==",
"dev": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
@ -2461,9 +2461,9 @@
"dev": true
},
"node_modules/vite": {
"version": "2.9.9",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz",
"integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==",
"version": "2.9.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz",
"integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==",
"dev": true,
"dependencies": {
"esbuild": "^0.14.27",
@ -2498,15 +2498,15 @@
}
},
"node_modules/vue": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.36.tgz",
"integrity": "sha512-5yTXmrE6gW8IQgttzHW5bfBiFA6mx35ZXHjGLDmKYzW6MMmYvCwuKybANRepwkMYeXw2v1buGg3/lPICY5YlZw==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz",
"integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==",
"dependencies": {
"@vue/compiler-dom": "3.2.36",
"@vue/compiler-sfc": "3.2.36",
"@vue/runtime-dom": "3.2.36",
"@vue/server-renderer": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-dom": "3.2.37",
"@vue/compiler-sfc": "3.2.37",
"@vue/runtime-dom": "3.2.37",
"@vue/server-renderer": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"node_modules/vue-eslint-parser": {
@ -2551,9 +2551,9 @@
}
},
"node_modules/vue-router": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.15.tgz",
"integrity": "sha512-xa+pIN9ZqORdIW1MkN2+d9Ui2pCM1b/UMgwYUCZOiFYHAvz/slKKBDha8DLrh5aCG/RibtrpyhKjKOZ85tYyWg==",
"version": "4.0.16",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.16.tgz",
"integrity": "sha512-JcO7cb8QJLBWE+DfxGUL3xUDOae/8nhM1KVdnudadTAORbuxIC/xAydC5Zr/VLHUDQi1ppuTF5/rjBGzgzrJNA==",
"dependencies": {
"@vue/devtools-api": "^6.0.0"
},
@ -2727,9 +2727,9 @@
}
},
"@babel/parser": {
"version": "7.18.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz",
"integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow=="
"version": "7.18.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz",
"integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw=="
},
"@eslint/eslintrc": {
"version": "1.3.0",
@ -2910,36 +2910,36 @@
"requires": {}
},
"@vue/compiler-core": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.36.tgz",
"integrity": "sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.37.tgz",
"integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==",
"requires": {
"@babel/parser": "^7.16.4",
"@vue/shared": "3.2.36",
"@vue/shared": "3.2.37",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"@vue/compiler-dom": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.36.tgz",
"integrity": "sha512-tcOTAOiW4s24QLnq+ON6J+GRONXJ+A/mqKCORi0LSlIh8XQlNnlm24y8xIL8la+ZDgkdbjarQ9ZqYSvEja6gVA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz",
"integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==",
"requires": {
"@vue/compiler-core": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-core": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"@vue/compiler-sfc": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.36.tgz",
"integrity": "sha512-AvGb4bTj4W8uQ4BqaSxo7UwTEqX5utdRSMyHy58OragWlt8nEACQ9mIeQh3K4di4/SX+41+pJrLIY01lHAOFOA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz",
"integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==",
"requires": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.36",
"@vue/compiler-dom": "3.2.36",
"@vue/compiler-ssr": "3.2.36",
"@vue/reactivity-transform": "3.2.36",
"@vue/shared": "3.2.36",
"@vue/compiler-core": "3.2.37",
"@vue/compiler-dom": "3.2.37",
"@vue/compiler-ssr": "3.2.37",
"@vue/reactivity-transform": "3.2.37",
"@vue/shared": "3.2.37",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
@ -2947,12 +2947,12 @@
}
},
"@vue/compiler-ssr": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.36.tgz",
"integrity": "sha512-+KugInUFRvOxEdLkZwE+W43BqHyhBh0jpYXhmqw1xGq2dmE6J9eZ8UUSOKNhdHtQ/iNLWWeK/wPZkVLUf3YGaw==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz",
"integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==",
"requires": {
"@vue/compiler-dom": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-dom": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"@vue/devtools-api": {
@ -2961,57 +2961,57 @@
"integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ=="
},
"@vue/reactivity": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.36.tgz",
"integrity": "sha512-c2qvopo0crh9A4GXi2/2kfGYMxsJW4tVILrqRPydVGZHhq0fnzy6qmclWOhBFckEhmyxmpHpdJtIRYGeKcuhnA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.37.tgz",
"integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==",
"requires": {
"@vue/shared": "3.2.36"
"@vue/shared": "3.2.37"
}
},
"@vue/reactivity-transform": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.36.tgz",
"integrity": "sha512-Jk5o2BhpODC9XTA7o4EL8hSJ4JyrFWErLtClG3NH8wDS7ri9jBDWxI7/549T7JY9uilKsaNM+4pJASLj5dtRwA==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz",
"integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==",
"requires": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.36",
"@vue/shared": "3.2.36",
"@vue/compiler-core": "3.2.37",
"@vue/shared": "3.2.37",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
},
"@vue/runtime-core": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.36.tgz",
"integrity": "sha512-PTWBD+Lub+1U3/KhbCExrfxyS14hstLX+cBboxVHaz+kXoiDLNDEYAovPtxeTutbqtClIXtft+wcGdC+FUQ9qQ==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.37.tgz",
"integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==",
"requires": {
"@vue/reactivity": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/reactivity": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"@vue/runtime-dom": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.36.tgz",
"integrity": "sha512-gYPYblm7QXHVuBohqNRRT7Wez0f2Mx2D40rb4fleehrJU9CnkjG0phhcGEZFfGwCmHZRqBCRgbFWE98bPULqkg==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz",
"integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==",
"requires": {
"@vue/runtime-core": "3.2.36",
"@vue/shared": "3.2.36",
"@vue/runtime-core": "3.2.37",
"@vue/shared": "3.2.37",
"csstype": "^2.6.8"
}
},
"@vue/server-renderer": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.36.tgz",
"integrity": "sha512-uZE0+jfye6yYXWvAQYeHZv+f50sRryvy16uiqzk3jn8hEY8zTjI+rzlmZSGoE915k+W/Ol9XSw6vxOUD8dGkUg==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.37.tgz",
"integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==",
"requires": {
"@vue/compiler-ssr": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-ssr": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"@vue/shared": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.36.tgz",
"integrity": "sha512-JtB41wXl7Au3+Nl3gD16Cfpj7k/6aCroZ6BbOiCMFCMvrOpkg/qQUXTso2XowaNqBbnkuGHurLAqkLBxNGc1hQ=="
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.37.tgz",
"integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw=="
},
"@vueform/slider": {
"version": "git+ssh://git@github.com/chme/slider.git#faff83ed8a77f2cdbcb7252505ef734301efd139",
@ -3448,9 +3448,9 @@
"dev": true
},
"eslint": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz",
"integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==",
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz",
"integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.3.0",
@ -3498,9 +3498,9 @@
"requires": {}
},
"eslint-plugin-vue": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.1.0.tgz",
"integrity": "sha512-EPCeInPicQ/YyfOWJDr1yfEeSNoFCMzUus107lZyYi37xejdOolNzS5MXGXp8+9bkoKZMdv/1AcZzQebME6r+g==",
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.1.1.tgz",
"integrity": "sha512-W9n5PB1X2jzC7CK6riG0oAcxjmKrjTF6+keL1rni8n57DZeilx/Fulz+IRJK3lYseLNAygN0I62L7DvioW40Tw==",
"dev": true,
"requires": {
"eslint-utils": "^3.0.0",
@ -4156,9 +4156,9 @@
"dev": true
},
"prettier": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.0.tgz",
"integrity": "sha512-nwoX4GMFgxoPC6diHvSwmK/4yU8FFH3V8XWtLQrbj4IBsK2pkYhG4kf/ljF/haaZ/aii+wNJqISrCDPgxGWDVQ==",
"dev": true
},
"punycode": {
@ -4249,9 +4249,9 @@
}
},
"sass": {
"version": "1.52.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.52.2.tgz",
"integrity": "sha512-mfHB2VSeFS7sZlPv9YohB9GB7yWIgQNTGniQwfQ04EoQN0wsQEv7SwpCwy/x48Af+Z3vDeFXz+iuXM3HK/phZQ==",
"version": "1.52.3",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.52.3.tgz",
"integrity": "sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==",
"dev": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0",
@ -4403,9 +4403,9 @@
"dev": true
},
"vite": {
"version": "2.9.9",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz",
"integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==",
"version": "2.9.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.12.tgz",
"integrity": "sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==",
"dev": true,
"requires": {
"esbuild": "^0.14.27",
@ -4416,15 +4416,15 @@
}
},
"vue": {
"version": "3.2.36",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.36.tgz",
"integrity": "sha512-5yTXmrE6gW8IQgttzHW5bfBiFA6mx35ZXHjGLDmKYzW6MMmYvCwuKybANRepwkMYeXw2v1buGg3/lPICY5YlZw==",
"version": "3.2.37",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.37.tgz",
"integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==",
"requires": {
"@vue/compiler-dom": "3.2.36",
"@vue/compiler-sfc": "3.2.36",
"@vue/runtime-dom": "3.2.36",
"@vue/server-renderer": "3.2.36",
"@vue/shared": "3.2.36"
"@vue/compiler-dom": "3.2.37",
"@vue/compiler-sfc": "3.2.37",
"@vue/runtime-dom": "3.2.37",
"@vue/server-renderer": "3.2.37",
"@vue/shared": "3.2.37"
}
},
"vue-eslint-parser": {
@ -4454,9 +4454,9 @@
}
},
"vue-router": {
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.15.tgz",
"integrity": "sha512-xa+pIN9ZqORdIW1MkN2+d9Ui2pCM1b/UMgwYUCZOiFYHAvz/slKKBDha8DLrh5aCG/RibtrpyhKjKOZ85tYyWg==",
"version": "4.0.16",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.16.tgz",
"integrity": "sha512-JcO7cb8QJLBWE+DfxGUL3xUDOae/8nhM1KVdnudadTAORbuxIC/xAydC5Zr/VLHUDQi1ppuTF5/rjBGzgzrJNA==",
"requires": {
"@vue/devtools-api": "^6.0.0"
}

View File

@ -23,9 +23,9 @@
"reconnectingwebsocket": "^1.0.0",
"spotify-web-api-js": "^1.5.2",
"string-to-color": "^2.2.2",
"vue": "^3.2.36",
"vue": "^3.2.37",
"vue-i18n": "^9.1.10",
"vue-router": "^4.0.15",
"vue-router": "^4.0.16",
"vue-scrollto": "^2.20.0",
"vue3-click-away": "^1.2.4",
"vue3-lazyload": "^0.3.4",
@ -35,11 +35,11 @@
"devDependencies": {
"@intlify/vite-plugin-vue-i18n": "^3.4.0",
"@vitejs/plugin-vue": "^2.3.3",
"eslint": "^8.16.0",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-vue": "^9.1.0",
"prettier": "2.6.2",
"sass": "^1.52.2",
"vite": "^2.9.9"
"eslint-plugin-vue": "^9.1.1",
"prettier": "2.7.0",
"sass": "^1.52.3",
"vite": "^2.9.12"
}
}

View File

@ -12,7 +12,7 @@
@click="is_active = !is_active"
>
<span v-text="option.name" />
<mdicon class="icon" name="chevron-down" size="16" />
<span class="icon"><mdicon name="chevron-down" size="16" /></span>
</button>
</div>
<div id="dropdown-menu" class="dropdown-menu" role="menu">

View File

@ -38,7 +38,9 @@
</div>
<div class="media-right" style="padding-top: 0.7rem">
<a @click.prevent.stop="open_dialog(album.item)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>

View File

@ -19,7 +19,9 @@
</div>
<div class="media-right">
<a @click.prevent.stop="open_dialog(artist.item)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>

View File

@ -19,7 +19,9 @@
</div>
<div class="media-right">
<a @click.prevent.stop="open_dialog(composer.item)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>
@ -61,7 +63,7 @@ export default {
open_composer: function (composer) {
this.selected_composer = composer
this.$router.push({
name: 'ComposerTracks',
name: 'ComposerAlbums',
params: { composer: composer.name }
})
},

View File

@ -5,7 +5,9 @@
@click="open_parent_directory()"
>
<figure class="media-left fd-has-action">
<mdicon class="icon" name="subdirectory-arrow-left" size="16" />
<span class="icon"
><mdicon name="subdirectory-arrow-left" size="16"
/></span>
</figure>
<div class="media-content fd-has-action is-clipped">
<h1 class="title is-6">..</h1>
@ -17,7 +19,7 @@
<template v-for="directory in directories" :key="directory.path">
<div class="media" @click="open_directory(directory)">
<figure class="media-left fd-has-action">
<mdicon class="icon" name="folder" size="16" />
<span class="icon"><mdicon name="folder" size="16" /></span>
</figure>
<div class="media-content fd-has-action is-clipped">
<h1
@ -28,7 +30,9 @@
</div>
<div class="media-right">
<a @click.prevent.stop="open_dialog(directory)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>
@ -36,7 +40,7 @@
<teleport to="#app">
<modal-dialog-directory
:show="show_details_modal"
:directory="selected_directory"
:directory="selected_directory.path"
@close="show_details_modal = false"
/>
</teleport>

View File

@ -15,7 +15,9 @@
</div>
<div class="media-right">
<a @click.prevent.stop="open_dialog(genre.item)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>

View File

@ -1,11 +1,9 @@
<template>
<div v-if="is_next || !show_only_next_items" class="media">
<div v-if="edit_mode" class="media-left">
<mdicon
class="icon has-text-grey fd-is-movable handle"
name="drag-horizontal"
size="16"
/>
<span class="icon has-text-grey fd-is-movable handle"
><mdicon name="drag-horizontal" size="16"
/></span>
</div>
<div class="media-content fd-has-action is-clipped" @click="play">
<h1

View File

@ -7,14 +7,18 @@
@click="open_playlist(playlist.item)"
>
<figure class="media-left fd-has-action">
<mdicon class="icon" :name="icon_name(playlist.item)" size="16" />
<span class="icon"
><mdicon :name="icon_name(playlist.item)" size="16"
/></span>
</figure>
<div class="media-content fd-has-action is-clipped">
<h1 class="title is-6" v-text="playlist.item.name" />
</div>
<div class="media-right">
<a @click.prevent.stop="open_dialog(playlist.item)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>

View File

@ -8,7 +8,7 @@
@click="play_track(index, track)"
>
<figure v-if="show_icon" class="media-left fd-has-action">
<mdicon class="icon" name="file-outline" size="16" />
<span class="icon"><mdicon name="file-outline" size="16" /></span>
</figure>
<div class="media-content fd-has-action is-clipped">
<h1
@ -29,7 +29,9 @@
</div>
<div class="media-right">
<a @click.prevent.stop="open_dialog(track)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</div>
</div>

View File

@ -11,7 +11,7 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="$emit('close')">
<mdicon class="icon" name="cancel" size="16" />
<span class="icon"><mdicon name="cancel" size="16" /></span>
<span
class="is-size-7"
v-text="close_action ? close_action : t('dialog.cancel')"
@ -22,7 +22,7 @@
class="card-footer-item has-background-danger has-text-white has-text-weight-bold"
@click="$emit('delete')"
>
<mdicon class="icon" name="delete" size="16" />
<span class="icon"><mdicon name="delete" size="16" /></span>
<span class="is-size-7" v-text="delete_action" />
</a>
<a
@ -30,7 +30,7 @@
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="$emit('ok')"
>
<mdicon class="icon" name="check" size="16" />
<span class="icon"><mdicon name="check" size="16" /></span>
<span class="is-size-7" v-text="ok_action" />
</a>
</footer>

View File

@ -18,7 +18,9 @@
:placeholder="$t('dialog.add.rss.placeholder')"
:disabled="loading"
/>
<mdicon class="icon is-left" name="rss" size="16" />
<span class="icon is-left"
><mdicon name="rss" size="16"
/></span>
</p>
<p class="help" v-text="$t('dialog.add.rss.help')" />
</div>
@ -26,7 +28,7 @@
</div>
<footer v-if="loading" class="card-footer">
<a class="card-footer-item button is-loading">
<mdicon class="icon" name="web" size="16" />
<span class="icon"><mdicon name="web" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.add.rss.processing')"
@ -38,14 +40,16 @@
class="card-footer-item has-text-danger"
@click="$emit('close')"
>
<mdicon class="icon" name="cancel" size="16" />
<span class="icon"><mdicon name="cancel" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.add.rss.cancel')" />
</a>
<a
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="add_stream"
>
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.add.rss.add')" />
</a>
</footer>

View File

@ -18,14 +18,16 @@
:placeholder="$t('dialog.add.stream.placeholder')"
:disabled="loading"
/>
<mdicon class="icon is-left" name="web" size="16" />
<span class="icon is-left"
><mdicon name="web" size="16"
/></span>
</p>
</div>
</form>
</div>
<footer v-if="loading" class="card-footer">
<a class="card-footer-item has-text-dark">
<mdicon class="icon" name="web" size="16" />
<span class="icon"><mdicon name="web" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.add.stream.loading')"
@ -37,21 +39,23 @@
class="card-footer-item has-text-danger"
@click="$emit('close')"
>
<mdicon class="icon" name="cancel" size="16" />
<span class="icon"><mdicon name="cancel" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.add.stream.cancel')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="add_stream">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.add.stream.add')" />
</a>
<a
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="play"
>
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.add.stream.play')" />
</a>
</footer>

View File

@ -71,8 +71,8 @@
class="title is-6"
v-text="
[
t('media.kind.' + album.media_kind),
t('data.kind.' + album.data_kind)
$t('media.kind.' + album.media_kind),
$t('data.kind.' + album.data_kind)
].join(' - ')
"
/>
@ -88,15 +88,19 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.album.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.album.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.album.play')" />
</a>
</footer>

View File

@ -40,15 +40,19 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.artist.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.artist.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.artist.play')" />
</a>
</footer>

View File

@ -39,18 +39,22 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.composer.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.composer.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.composer.play')" />
</a>
</footer>

View File

@ -6,22 +6,26 @@
<div class="modal-content fd-modal-card">
<div class="card">
<div class="card-content">
<p class="title is-4" v-text="directory.path" />
<p class="title is-4" v-text="directory" />
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.directory.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.directory.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.directory.play')" />
</a>
</footer>

View File

@ -33,15 +33,19 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.genre.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.genre.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.genre.play')" />
</a>
</footer>

View File

@ -33,18 +33,22 @@
</div>
<footer v-if="!playlist.folder" class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.playlist.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.playlist.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.playlist.play')" />
</a>
</footer>

View File

@ -18,14 +18,16 @@
placeholder="Playlist name"
:disabled="loading"
/>
<mdicon class="icon is-left" name="file-music" size="16" />
<span class="icon is-left"
><mdicon name="file-music" size="16"
/></span>
</p>
</div>
</form>
</div>
<footer v-if="loading" class="card-footer">
<a class="card-footer-item has-text-dark">
<mdicon class="icon" name="web" size="16" />
<span class="icon"><mdicon name="web" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.playlist.save.saving')"
@ -37,7 +39,7 @@
class="card-footer-item has-text-danger"
@click="$emit('close')"
>
<mdicon class="icon" name="cancel" size="16" />
<span class="icon"><mdicon name="cancel" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.playlist.save.cancel')"
@ -47,7 +49,9 @@
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="save"
>
<mdicon class="icon" name="content-save" size="16" />
<span class="icon"
><mdicon name="content-save" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.playlist.save.save')"

View File

@ -137,14 +137,14 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="remove">
<mdicon class="icon" name="delete" size="16" />
<span class="icon"><mdicon name="delete" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.queue-item.remove')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.queue-item.play')" />
</a>
</footer>

View File

@ -30,7 +30,7 @@
class="card-footer-item has-text-danger"
@click="$emit('close')"
>
<mdicon class="icon" name="cancel" size="16" />
<span class="icon"><mdicon name="cancel" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.remote-pairing.cancel')"
@ -40,7 +40,7 @@
class="card-footer-item has-background-info has-text-white has-text-weight-bold"
@click="kickoff_pairing"
>
<mdicon class="icon" name="cellphone" size="16" />
<span class="icon"><mdicon name="cellphone" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.remote-pairing.pair')"

View File

@ -92,7 +92,12 @@
<span class="heading" v-text="$t('dialog.track.type')" />
<span class="title is-6">
<span
v-text="[track.media_kind, track.data_kind].join(' - ')"
v-text="
[
$t('media.kind.' + track.media_kind),
$t('data.kind.' + track.data_kind)
].join(' - ')
"
/>
<span
v-if="track.data_kind === 'spotify'"
@ -163,15 +168,19 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.track.add')" />
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span class="is-size-7" v-text="$t('dialog.track.add-next')" />
</a>
<a class="card-footer-item has-text-dark" @click="play_track">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span class="is-size-7" v-text="$t('dialog.track.play')" />
</a>
</footer>

View File

@ -12,7 +12,7 @@
<div class="navbar-brand fd-expanded">
<!-- Link to queue -->
<navbar-item-link to="/" exact>
<mdicon class="icon" name="playlist-play" size="24" />
<span class="icon"><mdicon name="playlist-play" size="24" /></span>
</navbar-item-link>
<!-- Now playing artist/title (not visible on "now playing" page) -->
<router-link
@ -71,11 +71,11 @@
class="navbar-item fd-margin-left-auto is-hidden-desktop"
@click="show_player_menu = !show_player_menu"
>
<mdicon
class="icon"
:name="show_player_menu ? 'chevron-down' : 'chevron-up'"
size="18"
/>
<span class="icon"
><mdicon
:name="show_player_menu ? 'chevron-down' : 'chevron-up'"
size="18"
/></span>
</a>
<!-- Player menu dropup menu (only visible on desktop) -->
<div
@ -86,11 +86,11 @@
class="navbar-link is-arrowless"
@click="show_player_menu = !show_player_menu"
>
<mdicon
class="icon"
:name="show_player_menu ? 'chevron-down' : 'chevron-up'"
size="18"
/>
<span class="icon"
><mdicon
:name="show_player_menu ? 'chevron-down' : 'chevron-up'"
size="18"
/></span>
</a>
<div
class="navbar-dropdown is-right is-boxed"
@ -105,11 +105,11 @@
class="button is-white is-small"
@click="toggle_mute_volume"
>
<mdicon
class="icon"
:name="player.volume > 0 ? 'volume-high' : 'volume-off'"
size="18"
/>
<span class="icon"
><mdicon
:name="player.volume > 0 ? 'volume-high' : 'volume-off'"
size="18"
/></span>
</a>
</div>
<div class="level-item fd-expanded">
@ -145,17 +145,15 @@
<a
class="button is-white is-small"
:class="{ 'is-loading': loading }"
>
<span
><span
class="icon fd-has-action"
:class="{
'has-text-grey-light': !playing && !loading,
'is-loading': loading
}"
@click="togglePlay"
>
<mdicon name="broadcast" size="18" />
</span>
><mdicon name="broadcast" size="18"
/></span>
</a>
</div>
<div class="level-item fd-expanded">
@ -169,13 +167,12 @@
href="stream.mp3"
style="margin-left: 5px"
target="_blank"
>
<mdicon
class="icon"
name="open-in-new"
size="16"
style="vertical-align: middle"
/>
><span class="icon"
><mdicon
name="open-in-new"
size="16"
style="vertical-align: middle"
/></span>
</a>
</p>
<Slider
@ -231,11 +228,11 @@
<div class="level-left fd-expanded">
<div class="level-item" style="flex-grow: 0">
<a class="button is-white is-small" @click="toggle_mute_volume">
<mdicon
class="icon"
:name="player.volume > 0 ? 'volume-high' : 'volume-off'"
size="18"
/>
<span class="icon"
><mdicon
:name="player.volume > 0 ? 'volume-high' : 'volume-off'"
size="18"
/></span>
</a>
</div>
<div class="level-item fd-expanded">
@ -278,8 +275,7 @@
'is-loading': loading
}"
@click="togglePlay"
>
<mdicon name="broadcast" size="16" />
><mdicon name="radio-tower" size="16" />
</span>
</a>
</div>
@ -294,13 +290,12 @@
href="stream.mp3"
style="margin-left: 5px"
target="_blank"
>
<mdicon
class="icon"
name="open-in-new"
size="16"
style="vertical-align: middle"
/>
><span class="icon"
><mdicon
name="open-in-new"
size="16"
style="vertical-align: middle"
/></span>
</a>
</p>
<Slider

View File

@ -8,9 +8,8 @@
class="icon fd-has-action"
:class="{ 'has-text-grey-light': !output.selected }"
@click="set_enabled"
>
<mdicon :name="type_class" size="18" :title="output.type" />
</span>
><mdicon :name="type_class" size="18" :title="output.type"
/></span>
</a>
</div>
<div class="level-item fd-expanded">

View File

@ -7,25 +7,25 @@
>
<div class="navbar-brand">
<navbar-item-link v-if="is_visible_playlists" to="/playlists">
<mdicon class="icon" name="music-box-multiple" size="16" />
<span class="icon"><mdicon name="music-box-multiple" size="16" /></span>
</navbar-item-link>
<navbar-item-link v-if="is_visible_music" to="/music">
<mdicon class="icon" name="music" size="16" />
<span class="icon"><mdicon name="music" size="16" /></span>
</navbar-item-link>
<navbar-item-link v-if="is_visible_podcasts" to="/podcasts">
<mdicon class="icon" name="podcast" size="16" />
<span class="icon"><mdicon name="microphone" size="16" /></span>
</navbar-item-link>
<navbar-item-link v-if="is_visible_audiobooks" to="/audiobooks">
<mdicon class="icon" name="book-open-variant" size="16" />
<span class="icon"><mdicon name="book-open-variant" size="16" /></span>
</navbar-item-link>
<navbar-item-link v-if="is_visible_radio" to="/radio">
<mdicon class="icon" name="radio-tower" size="16" />
<span class="icon"><mdicon name="radio" size="16" /></span>
</navbar-item-link>
<navbar-item-link v-if="is_visible_files" to="/files">
<mdicon class="icon" name="folder-open" size="16" />
<span class="icon"><mdicon name="folder-open" size="16" /></span>
</navbar-item-link>
<navbar-item-link v-if="is_visible_search" to="/search">
<mdicon class="icon" name="magnify" size="16" />
<span class="icon"><mdicon name="magnify" size="16" /></span>
</navbar-item-link>
<div
class="navbar-burger"
@ -47,7 +47,9 @@
@click="on_click_outside_settings"
>
<a class="navbar-link is-arrowless">
<mdicon class="icon is-hidden-touch" name="menu" size="24" />
<span class="icon is-hidden-touch"
><mdicon name="menu" size="24"
/></span>
<span
class="is-hidden-desktop has-text-weight-bold"
v-text="$t('navigation.title')"
@ -55,11 +57,13 @@
</a>
<div class="navbar-dropdown is-right">
<navbar-item-link to="/playlists">
<mdicon class="icon" name="music-box-multiple" size="16" />
<span class="icon"
><mdicon name="music-box-multiple" size="16"
/></span>
<b v-text="$t('navigation.playlists')" />
</navbar-item-link>
<navbar-item-link to="/music" exact>
<mdicon class="icon" name="music" size="16" />
<span class="icon"><mdicon name="music" size="16" /></span>
<b v-text="$t('navigation.music')" />
</navbar-item-link>
<navbar-item-link to="/music/artists">
@ -87,36 +91,39 @@
/>
</navbar-item-link>
<navbar-item-link to="/podcasts">
<mdicon class="icon" name="podcast" size="16" />
<span class="icon"><mdicon name="microphone" size="16" /></span>
<b v-text="$t('navigation.podcasts')" />
</navbar-item-link>
<navbar-item-link to="/audiobooks">
<mdicon class="icon" name="book-open-variant" size="16" />
<span class="icon"
><mdicon name="book-open-variant" size="16"
/></span>
<b v-text="$t('navigation.audiobooks')" />
</navbar-item-link>
<navbar-item-link to="/radio">
<mdicon class="icon" name="radio-tower" size="16" />
<span class="icon"><mdicon name="radio" size="16" /></span>
<b v-text="$t('navigation.radio')" />
</navbar-item-link>
<navbar-item-link to="/files">
<mdicon class="icon" name="folder-open" size="16" />
<span class="icon"><mdicon name="folder-open" size="16" /></span>
<b v-text="$t('navigation.files')" />
</navbar-item-link>
<navbar-item-link to="/search">
<mdicon class="icon" name="magnify" size="16" />
<span class="icon"><mdicon name="magnify" size="16" /></span>
<b v-text="$t('navigation.search')" />
</navbar-item-link>
<hr class="fd-navbar-divider" />
<navbar-item-link
to="/settings/webinterface"
v-text="$t('navigation.settings')"
/>
<navbar-item-link to="/settings/webinterface">{{
$t('navigation.settings')
}}</navbar-item-link>
<a
class="navbar-item"
@click.stop.prevent="open_update_dialog()"
v-text="$t('navigation.update-library')"
/>
<navbar-item-link to="/about" v-text="$t('navigation.about')" />
<navbar-item-link to="/about">{{
$t('navigation.about')
}}</navbar-item-link>
<div
class="navbar-item is-hidden-desktop"
style="margin-bottom: 2.5rem"

View File

@ -1,6 +1,6 @@
<template>
<a :class="{ 'is-warning': is_consume }" @click="toggle_consume_mode">
<mdicon class="icon" name="fire" :size="icon_size" />
<span class="icon"><mdicon name="fire" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a :disabled="disabled" @click="play_next">
<mdicon class="icon" name="skip-forward" :size="icon_size" />
<span class="icon"><mdicon name="skip-forward" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a :disabled="disabled" @click="toggle_play_pause">
<mdicon class="icon" :name="icon_name" :size="icon_size" />
<span class="icon"><mdicon :name="icon_name" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a :disabled="disabled" @click="play_previous">
<mdicon class="icon" name="skip-backward" :size="icon_size" />
<span class="icon"><mdicon name="skip-backward" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a :class="{ 'is-warning': !is_repeat_off }" @click="toggle_repeat_mode">
<mdicon class="icon" :name="icon_name" :size="icon_size" />
<span class="icon"><mdicon :name="icon_name" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a v-if="visible" :disabled="disabled" @click="seek">
<mdicon class="icon" name="rewind" :size="icon_size" />
<span class="icon"><mdicon name="rewind" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a v-if="visible" :disabled="disabled" @click="seek">
<mdicon class="icon" name="fast-forward" :size="icon_size" />
<span class="icon"><mdicon name="fast-forward" :size="icon_size" /></span>
</a>
</template>

View File

@ -1,6 +1,6 @@
<template>
<a :class="{ 'is-warning': is_shuffle }" @click="toggle_shuffle_mode">
<mdicon class="icon" :name="icon_name" :size="icon_size" />
<span class="icon"><mdicon :name="icon_name" :size="icon_size" /></span>
</a>
</template>

View File

@ -57,21 +57,25 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.album.add')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.album.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.album.play')"

View File

@ -37,21 +37,25 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.artist.add')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.artist.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.artist.play')"

View File

@ -42,21 +42,25 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.add')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.playlist.play')"

View File

@ -72,21 +72,25 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="queue_add">
<mdicon class="icon" name="playlist-plus" size="16" />
<span class="icon"
><mdicon name="playlist-plus" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.track.add')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="queue_add_next">
<mdicon class="icon" name="playlist-play" size="16" />
<span class="icon"
><mdicon name="playlist-play" size="16"
/></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.track.add-next')"
/>
</a>
<a class="card-footer-item has-text-dark" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span
class="is-size-7"
v-text="$t('dialog.spotify.track.play')"

View File

@ -12,12 +12,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon
class="icon is-small"
name="account-music"
size="16"
/>
<span v-text="$t('tabs.audiobooks.authors')" />
<span class="icon is-small"
><mdicon name="account-music" size="16"
/></span>
<span v-text="$t('page.audiobooks.tabs.authors')" />
</a>
</li>
</router-link>
@ -28,8 +26,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon class="icon is-small" name="album" size="16" />
<span v-text="$t('tabs.audiobooks.audiobooks')" />
<span class="icon is-small"
><mdicon name="album" size="16"
/></span>
<span v-text="$t('page.audiobooks.tabs.audiobooks')" />
</a>
</li>
</router-link>

View File

@ -12,8 +12,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon class="icon is-small" name="web" size="16" />
<span v-text="$t('page.settings.tabs.music.browse')" />
<span class="icon is-small"
><mdicon name="web" size="16"
/></span>
<span v-text="$t('page.browse.tabs.browse')" />
</a>
</li>
</router-link>
@ -24,12 +26,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon
class="icon is-small"
name="account-music"
size="16"
/>
<span v-text="$t('page.settings.tabs.music.artists')" />
<span class="icon is-small"
><mdicon name="account-music" size="16"
/></span>
<span v-text="$t('page.browse.tabs.artists')" />
</a>
</li>
</router-link>
@ -40,8 +40,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon class="icon is-small" name="album" size="16" />
<span v-text="$t('page.settings.tabs.music.albums')" />
<span class="icon is-small"
><mdicon name="album" size="16"
/></span>
<span v-text="$t('page.browse.tabs.albums')" />
</a>
</li>
</router-link>
@ -52,8 +54,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon class="icon is-small" name="speaker" size="16" />
<span v-text="$t('page.settings.tabs.music.genres')" />
<span class="icon is-small"
><mdicon name="speaker" size="16"
/></span>
<span v-text="$t('page.browse.tabs.genres')" />
</a>
</li>
</router-link>
@ -64,12 +68,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon
class="icon is-small"
name="book-open-page-variant"
size="16"
/>
<span v-text="$t('page.settings.tabs.music.composers')" />
<span class="icon is-small"
><mdicon name="book-open-page-variant" size="16"
/></span>
<span v-text="$t('page.browse.tabs.composers')" />
</a>
</li>
</router-link>
@ -81,8 +83,10 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon class="icon is-small" name="spotify" size="16" />
<span v-text="$t('page.settings.tabs.music.spotify')" />
<span class="icon is-small"
><mdicon name="spotify" size="16"
/></span>
<span v-text="$t('page.browse.tabs.spotify')" />
</a>
</li>
</router-link>

View File

@ -11,8 +11,10 @@
}"
>
<a @click="search_library">
<mdicon class="icon is-small" name="bookshelf" size="16" />
<span v-text="$t('tabs.search.library')" />
<span class="icon is-small"
><mdicon name="bookshelf" size="16"
/></span>
<span v-text="$t('page.search.tabs.library')" />
</a>
</li>
<li
@ -21,8 +23,10 @@
}"
>
<a @click="search_spotify">
<mdicon class="icon is-small" name="spotify" size="16" />
<span v-text="$t('tabs.search.spotify')" />
<span class="icon is-small"
><mdicon name="spotify" size="16"
/></span>
<span v-text="$t('page.search.tabs.spotify')" />
</a>
</li>
</ul>

View File

@ -12,7 +12,7 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<span v-text="$t('page.settings.tabs.settings.general')" />
<span v-text="$t('page.settings.tabs.general')" />
</a>
</li>
</router-link>
@ -24,9 +24,7 @@
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<span
v-text="
$t('page.settings.tabs.settings.remotes-and-outputs')
"
v-text="$t('page.settings.tabs.remotes-and-outputs')"
/>
</a>
</li>
@ -38,7 +36,7 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<span v-text="$t('page.settings.tabs.settings.artwork')" />
<span v-text="$t('page.settings.tabs.artwork')" />
</a>
</li>
</router-link>
@ -49,9 +47,7 @@
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<span
v-text="$t('page.settings.tabs.settings.online-services')"
/>
<span v-text="$t('page.settings.tabs.online-services')" />
</a>
</li>
</router-link>

View File

@ -9,7 +9,9 @@ import messages from '@intlify/vite-plugin-vue-i18n/messages'
export default createI18n({
legacy: false,
globalInjection: true,
locale: 'en',
locale: navigator.language,
fallbackLocale: 'en',
fallbackWarn: false,
missingWarn: false,
messages
})

View File

@ -27,6 +27,7 @@ import {
mdiFolderOpen,
mdiMagnify,
mdiMenu,
mdiMicrophone,
mdiMusic,
mdiMusicBoxMultiple,
mdiOpenInNew,
@ -36,7 +37,7 @@ import {
mdiPlay,
mdiPlaylistPlay,
mdiPlaylistPlus,
mdiPodcast,
mdiRadio,
mdiRadioTower,
mdiRefresh,
mdiRepeat,
@ -87,6 +88,7 @@ export const icons = {
mdiFolderOpen,
mdiMagnify,
mdiMenu,
mdiMicrophone,
mdiMusic,
mdiMusicBoxMultiple,
mdiOpenInNew,
@ -96,7 +98,7 @@ export const icons = {
mdiPlay,
mdiPlaylistPlay,
mdiPlaylistPlus,
mdiPodcast,
mdiRadio,
mdiRadioTower,
mdiRefresh,
mdiRepeat,

View File

@ -148,7 +148,9 @@ export class GroupByList {
groupIndex
)
*/
if (groupIndex >= this.indexList.length) {
if (this.isEmpty()) {
return { done: true }
} else if (groupIndex >= this.indexList.length) {
// We reached the end of all groups and items
//
// This should never happen, as the we already

View File

@ -263,7 +263,7 @@
}
},
"artist": {
"album-count": "{count} albums {'|'} ",
"album-count": "{count} albums",
"shuffle": "Shuffle",
"track-count": "{count} tracks",
"sort-by": {
@ -302,6 +302,10 @@
"artists": {
"count": "{count} authors",
"title": "Authors"
},
"tabs": {
"authors": "Authors",
"audiobooks": "Audiobooks"
}
},
"browse": {
@ -315,17 +319,20 @@
"recently-played": {
"title": "Recently played",
"tracks": "tracks"
},
"tabs": {
"albums": "Albums",
"artists": "Artists",
"browse": "Browse",
"composers": "Composers",
"genres": "Genres",
"spotify": "Spotify"
}
},
"composer": {
"album-count": "{count} albums {'|'}",
"album-count": "{count} albums",
"shuffle": "Shuffle",
"track-count": "{count} tracks",
"tracks": {
"album-count": "{count} albums",
"track-count": " {'|'} {count} tracks",
"shuffle": "Shuffle"
}
"track-count": "{count} tracks"
},
"composers": {
"count": "{count} composers",
@ -336,13 +343,9 @@
"title": "Files"
},
"genre": {
"album-count": "{count} albums {'|'} ",
"album-count": "{count} albums",
"shuffle": "Shuffle",
"tracks": {
"album-count": "{count} albums {'|'} ",
"count": " {count} tracks",
"shuffle": "Shuffle"
}
"track-count": "{count} tracks"
},
"genres": {
"count": "{count} genres",
@ -392,7 +395,7 @@
"artists": "Artists",
"audiobooks": "Audiobooks",
"composers": "Composers",
"help": "Tip: you can search by a smart playlist query language <a href=\"https://github.com/owntone/owntone-server/blob/master/README_SMARTPL.md\" target=\"_blank\">expression</a> if you prefix it with <code>query:</code>.",
"help": "Tip: you can search by a smart playlist query language <a href=\"https://owntone.github.io/owntone-server/smart-playlists/\" target=\"_blank\">expression</a> if you prefix it with <code>query:</code>.",
"no-albums": "No albums found",
"no-artists": "No artists found",
"no-audiobooks": "No audiobooks found",
@ -409,7 +412,11 @@
"show-playlists": "Show all {count} playlists",
"show-podcasts": "Show all {count} podcasts",
"show-tracks": "Show all {count} tracks",
"tracks": "Tracks"
"tracks": "Tracks",
"tabs": {
"library": "Library",
"spotify": "Spotify"
}
},
"settings": {
"artwork": {
@ -481,24 +488,10 @@
"logout": "Logout"
},
"tabs": {
"music": {
"albums": "Albums",
"artists": "Artists",
"browse": "Browse",
"composers": "Composers",
"genres": "Genres",
"spotify": "Spotify"
},
"search": {
"library": "Library",
"spotify": "Spotify"
},
"settings": {
"artwork": "Artwork",
"general": "General",
"online-services": "Online Services",
"remotes-and-outputs": "Remotes and Outputs"
}
"artwork": "Artwork",
"general": "General",
"online-services": "Online Services",
"remotes-and-outputs": "Remotes and Outputs"
}
},
"spotify": {

View File

@ -37,7 +37,7 @@
"play": "Lire",
"release-date": "Date de sortie",
"remove-podcast": "Supprimer le podcast",
"pistes": "Pistes",
"tracks": "Pistes",
"type": "Type",
"year": "Année"
},
@ -47,7 +47,7 @@
"added-on": "Ajouté le",
"albums": "Albums",
"play": "Lire",
"pistes": "Pistes",
"tracks": "Pistes",
"type": "Type"
},
"composer": {
@ -56,7 +56,7 @@
"albums": "Albums",
"duration": "Durée",
"play": "Lire",
"pistes": "Pistes"
"tracks": "Pistes"
},
"directory": {
"add-next": "Ajouter ensuite",
@ -69,7 +69,7 @@
"albums": "Albums",
"duration": "Durée",
"play": "Lire",
"pistes": "Pistes"
"tracks": "Pistes"
},
"playlist": {
"add-next": "Ajouter ensuite",
@ -130,7 +130,7 @@
"owner": "Propriéataire",
"path": "Emplacement",
"play": "Lire",
"pistes": "Pistes"
"tracks": "Pistes"
},
"track": {
"add-next": "Ajouter ensuite",
@ -236,7 +236,7 @@
"compiled-with": "Compilé avec les options {options}.",
"library": "Bibliothèque",
"total-playtime": "Durée totale de lecture",
"pistes": "Pistes",
"tracks": "Pistes",
"update": "Actualiser",
"updated-on": "il y a {time}",
"updated": "Mis à jour",
@ -263,7 +263,7 @@
}
},
"artist": {
"album-count": "{count} albums {'|'} ",
"album-count": "{count} albums",
"shuffle": "Lecture aléatoire",
"track-count": "{count} pistes",
"sort-by": {
@ -302,30 +302,37 @@
"artists": {
"count": "{count} auteurs",
"title": "Auteurs"
},
"tabs": {
"authors": "Auteurs",
"audiobooks": "Livres audio"
}
},
"browse": {
"albums": "albums",
"show-more": "Afficher plus",
"pistes": "pistes",
"tracks": "pistes",
"recently-added": {
"albums": "albums",
"title": "Ajouts récents"
},
"recently-played": {
"title": "Lectures récentes",
"pistes": "pistes"
"tracks": "pistes"
},
"tabs": {
"albums": "Albums",
"artists": "Artistes",
"browse": "Parcourir",
"composers": "Compositeurs",
"genres": "Genres",
"spotify": "Spotify"
}
},
"composer": {
"album-count": "{count} albums {'|'}",
"album-count": "{count} albums",
"shuffle": "Lecture aléatoire",
"track-count": "{count} pistes",
"pistes": {
"album-count": "{count} albums",
"track-count": " {'|'} {count} pistes",
"shuffle": "Lecture aléatoire"
}
"track-count": "{count} pistes"
},
"composers": {
"count": "{count} compositeurs",
@ -336,13 +343,9 @@
"title": "Fichiers"
},
"genre": {
"album-count": "{count} albums {'|'} ",
"album-count": "{count} albums",
"shuffle": "Lecture aléatoire",
"pistes": {
"album-count": "{count} albums {'|'} ",
"count": " {count} pistes",
"shuffle": "Lecture aléatoire"
}
"track-count": "{count} pistes"
},
"genres": {
"count": "{count} genres",
@ -392,7 +395,7 @@
"artists": "Artistes",
"audiobooks": "Livres audio",
"composers": "Compositeurs",
"help": "Astuce : en préfixant votre requête avec <code>query:</code>, vous pouvez effectuer une recherche avec une <a href=\"https://github.com/owntone/owntone-server/blob/master/README_SMARTPL.md\" target=\"_blank\">expression</a> du langage de requête de liste de lecture intelligente.",
"help": "Astuce : en préfixant votre requête avec <code>query:</code>, vous pouvez effectuer une recherche avec une <a href=\"https://owntone.github.io/owntone-server/smart-playlists/\" target=\"_blank\">expression</a> du langage de requête de liste de lecture intelligente.",
"no-albums": "Aucun album trouvé",
"no-artists": "Aucun artiste trouvé",
"no-audiobooks": "Aucun livre audio trouvé",
@ -409,7 +412,11 @@
"show-playlists": "Afficher les {count} listes de lecture",
"show-podcasts": "Afficher les {count} podcasts",
"show-tracks": "Afficher les {count} pistes",
"pistes": "Pistes"
"tracks": "Pistes",
"tabs": {
"library": "Bibliothèque",
"spotify": "Spotify"
}
},
"settings": {
"artwork": {
@ -481,24 +488,10 @@
"logout": "Se déconnecter"
},
"tabs": {
"music": {
"albums": "Albums",
"artists": "Artistes",
"browse": "Parcourir",
"composers": "Compositeurs",
"genres": "Genres",
"spotify": "Spotify"
},
"search": {
"library": "Library",
"spotify": "Spotify"
},
"settings": {
"artwork": "Illustrations",
"general": "Général",
"online-services": "Services en ligne",
"remotes-and-outputs": "Télécommandes et sorties"
}
"artwork": "Illustrations",
"general": "Général",
"online-services": "Services en ligne",
"remotes-and-outputs": "Télécommandes et sorties"
}
},
"spotify": {
@ -531,7 +524,7 @@
"show-all-artists": "Afficher les {count} artistes",
"show-all-playlists": "Afficher les {count} listes de lecture",
"show-all-tracks": "Afficher les {count} pistes",
"pistes": "Pistes"
"tracks": "Pistes"
}
}
},

View File

@ -41,28 +41,40 @@
<table class="table">
<tbody>
<tr>
<th class="has-text-left" v-text="$t('page.about.artists')" />
<th
class="has-text-left"
v-text="$t('page.about.artists')"
/>
<td
class="has-text-right"
v-text="$filters.number(library.artists)"
/>
</tr>
<tr>
<th class="has-text-left" v-text="$t('page.about.albums')" />
<th
class="has-text-left"
v-text="$t('page.about.albums')"
/>
<td
class="has-text-right"
v-text="$filters.number(library.albums)"
/>
</tr>
<tr>
<th class="has-text-left" v-text="$t('page.about.tracks')" />
<th
class="has-text-left"
v-text="$t('page.about.tracks')"
/>
<td
class="has-text-right"
v-text="$filters.number(library.songs)"
/>
</tr>
<tr>
<th class="has-text-left" v-text="$t('page.about.total-playtime')" />
<th
class="has-text-left"
v-text="$t('page.about.total-playtime')"
/>
<td
class="has-text-right"
v-text="
@ -71,7 +83,10 @@
/>
</tr>
<tr>
<th class="has-text-left" v-text="$t('page.about.updated')" />
<th
class="has-text-left"
v-text="$t('page.about.updated')"
/>
<td class="has-text-right">
<span
v-text="
@ -87,7 +102,10 @@
</td>
</tr>
<tr>
<th class="has-text-left" v-text="$t('page.about.uptime')" />
<th
class="has-text-left"
v-text="$t('page.about.uptime')"
/>
<td class="has-text-right">
<span
v-text="$filters.timeFromNow(library.started_at, true)"
@ -110,7 +128,10 @@
<div class="columns is-centered">
<div class="column is-four-fifths">
<div class="content has-text-centered-mobile">
<p class="is-size-7" v-text="$t('page.about.version', { version: config.version })" />
<p
class="is-size-7"
v-text="$t('page.about.version', { version: config.version })"
/>
<p
class="is-size-7"
v-text="

View File

@ -7,14 +7,14 @@
</h2>
<div class="buttons fd-is-centered-mobile fd-has-margin-top">
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.album.shuffle')" />
</a>
<a
class="button is-small is-light is-rounded"
@click="show_album_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
</div>
</template>

View File

@ -24,10 +24,10 @@
class="button is-small is-light is-rounded"
@click="show_artist_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.artist.shuffle')" />
</a>
</div>
@ -37,6 +37,7 @@
<span
v-text="$t('page.artist.album-count', { count: artist.album_count })"
/>
<span>&nbsp;|&nbsp;</span>
<a
class="has-text-link"
@click="open_tracks"
@ -127,7 +128,7 @@ export default {
computed: {
albums() {
const groupBy = this.groupby_options.find(
(o) => o.name === this.selected_groupby_option_id
(o) => o.id === this.selected_groupby_option_id
)
this.albums_list.group(groupBy.options)

View File

@ -13,10 +13,12 @@
class="button is-small is-light is-rounded"
@click="show_artist_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"
><mdicon name="dots-horizontal" size="16"
/></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.artist.shuffle')" />
</a>
</div>
@ -27,10 +29,13 @@
class="has-text-link"
@click="open_artist"
v-text="
$t('page.artist.track-count', {
albums: artist.album_count,
tracks: artist.track_count
})
$t('page.artist.album-count', { count: artist.album_count })
"
/>
<span>&nbsp;|&nbsp;</span>
<span
v-text="
$t('page.artist.track-count', { count: artist.track_count })
"
/>
</p>

View File

@ -7,14 +7,14 @@
</h2>
<div class="buttons fd-is-centered-mobile fd-has-margin-top">
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span v-text="$t('page.audiobooks.album.play')" />
</a>
<a
class="button is-small is-light is-rounded"
@click="show_album_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
</div>
</template>

View File

@ -9,10 +9,10 @@
class="button is-small is-light is-rounded"
@click="show_artist_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span v-text="$t('page.audiobooks.artist.shuffle')" />
</a>
</div>

View File

@ -9,7 +9,7 @@
<p class="title is-4" v-text="$t('page.audiobooks.artists.title')" />
<p
class="heading"
v-text="$t('page.audiobooks.artists.count', { count: tists.count })"
v-text="$t('page.audiobooks.artists.count', { count: artists.count })"
/>
</template>
<template #heading-right />

View File

@ -5,9 +5,9 @@
<template #heading-left>
<p
class="title is-4"
v-text="$t('page.browse.recently.played.title')"
v-text="$t('page.browse.recently-played.title')"
/>
<p class="heading" v-text="$t('page.browse.recently.played.tracks')" />
<p class="heading" v-text="$t('page.browse.recently-played.tracks')" />
</template>
<template #content>
<list-tracks :tracks="recently_played.items" />

View File

@ -10,10 +10,12 @@
class="button is-small is-light is-rounded"
@click="show_composer_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"
><mdicon name="dots-horizontal" size="16"
/></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.composer.shuffle')" />
</a>
</div>
@ -25,6 +27,7 @@
$t('page.composer.album-count', { count: composer.album_count })
"
/>
<span>&nbsp;|&nbsp;</span>
<a
class="has-text-link"
@click="open_tracks"

View File

@ -10,11 +10,13 @@
class="button is-small is-light is-rounded"
@click="show_composer_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"
><mdicon name="dots-horizontal" size="16"
/></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span v-text="$t('page.composer.tracks.shuffle')" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.composer.shuffle')" />
</a>
</div>
</template>
@ -24,11 +26,12 @@
class="has-text-link"
@click="open_albums"
v-text="
$t('page.composer.tracks.album-count', {
$t('page.composer.album-count', {
count: composer.album_count
})
"
/>
<span>&nbsp;|&nbsp;</span>
<span
v-text="
$t('page.composer.track-count', { count: composer.track_count })

View File

@ -9,28 +9,30 @@
<div class="buttons is-centered">
<a
class="button is-small is-light is-rounded"
@click="open_directory_dialog({ path: current_directory })"
@click="show_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"
><mdicon name="dots-horizontal" size="16"
/></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span v-text="$t('page.files.play')" />
</a>
</div>
</template>
<template #content>
<list-directories :directories="files.directories" />
<list-playlists :playlists="files.playlists.items" />
<list-playlists :playlists="playlists_list" />
<list-tracks
:tracks="files.tracks.items"
:expression="play_expression"
:show_icon="true"
/>
<modal-dialog-directory
:show="show_directory_details_modal"
:directory="selected_directory"
@close="show_directory_details_modal = false"
:show="show_details_modal"
:directory="current_directory"
@close="show_details_modal = false"
/>
</template>
</content-with-heading>
@ -42,7 +44,9 @@ import ContentWithHeading from '@/templates/ContentWithHeading.vue'
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 webapi from '@/webapi'
import { GroupByList } from '@/lib/GroupByList'
const dataObject = {
load: function (to) {
@ -55,6 +59,7 @@ const dataObject = {
set: function (vm, response) {
if (response) {
vm.files = response.data
vm.playlists_list = new GroupByList(response.data.playlists)
} else {
vm.files = {
directories: vm.$store.state.config.directories.map((dir) => {
@ -73,7 +78,8 @@ export default {
ContentWithHeading,
ListDirectories,
ListPlaylists,
ListTracks
ListTracks,
ModalDialogDirectory
},
beforeRouteEnter(to, from, next) {
@ -95,7 +101,9 @@ export default {
directories: [],
tracks: { items: [] },
playlists: { items: [] }
}
},
playlists_list: new GroupByList(),
show_details_modal: false
}
},

View File

@ -13,10 +13,12 @@
class="button is-small is-light is-rounded"
@click="show_genre_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"
><mdicon name="dots-horizontal" size="16"
/></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.genre.shuffle')" />
</a>
</div>
@ -26,6 +28,7 @@
<span
v-text="$t('page.genre.album-count', { count: genre.album_count })"
/>
<span>&nbsp;|&nbsp;</span>
<a
class="has-text-link"
@click="open_tracks"

View File

@ -13,11 +13,13 @@
class="button is-small is-light is-rounded"
@click="show_genre_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"
><mdicon name="dots-horizontal" size="16"
/></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span v-text="$t('page.genre.tracks.shuffle')" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.genre.shuffle')" />
</a>
</div>
</template>
@ -26,12 +28,11 @@
<a
class="has-text-link"
@click="open_genre"
v-text="
$t('page.genre.tracks.album-count', { count: genre.album_count })
"
v-text="$t('page.genre.album-count', { count: genre.album_count })"
/>
<span>&nbsp;|&nbsp;</span>
<span
v-text="$t('page.genre.tracks.count', { count: genre.track_count })"
v-text="$t('page.genre.track-count', { count: genre.track_count })"
/>
</p>
<list-tracks :tracks="tracks.items" :expression="expression" />

View File

@ -9,10 +9,10 @@
class="button is-small is-light is-rounded"
@click="show_playlist_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.playlist.shuffle')" />
</a>
</div>

View File

@ -9,10 +9,10 @@
class="button is-small is-light is-rounded"
@click="show_album_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="play" size="16" />
<span class="icon"><mdicon name="play" size="16" /></span>
<span v-text="$t('page.podcast.play')" />
</a>
</div>

View File

@ -7,7 +7,7 @@
<template #heading-right>
<div class="buttons is-centered">
<a class="button is-small" @click="mark_all_played">
<mdicon class="icon" name="pencil" size="16" />
<span class="icon"><mdicon name="pencil" size="16" /></span>
<span v-text="$t('page.podcasts.mark-all-played')" />
</a>
</div>
@ -31,11 +31,11 @@
<template #heading-right>
<div class="buttons is-centered">
<a v-if="rss.tracks > 0" class="button is-small" @click="update_rss">
<mdicon class="icon" name="refresh" size="16" />
<span class="icon"><mdicon name="refresh" size="16" /></span>
<span v-text="$t('page.podcasts.update')" />
</a>
<a class="button is-small" @click="open_add_podcast_dialog">
<mdicon class="icon" name="rss" size="16" />
<span class="icon"><mdicon name="rss" size="16" /></span>
<span v-text="$t('page.podcasts.add')" />
</a>
</div>

View File

@ -14,11 +14,13 @@
:class="{ 'is-info': show_only_next_items }"
@click="update_show_next_items"
>
<mdicon class="icon" name="arrow-collapse-down" size="16" />
<span class="icon"
><mdicon name="arrow-collapse-down" size="16"
/></span>
<span v-text="$t('page.queue.hide-previous')" />
</a>
<a class="button is-small" @click="open_add_stream_dialog">
<mdicon class="icon" name="web" size="16" />
<span class="icon"><mdicon name="web" size="16" /></span>
<span v-text="$t('page.queue.add-stream')" />
</a>
<a
@ -26,11 +28,11 @@
:class="{ 'is-info': edit_mode }"
@click="edit_mode = !edit_mode"
>
<mdicon class="icon" name="pencil" size="16" />
<span class="icon"><mdicon name="pencil" size="16" /></span>
<span v-text="$t('page.queue.edit')" />
</a>
<a class="button is-small" @click="queue_clear">
<mdicon class="icon" name="delete-empty" size="16" />
<span class="icon"><mdicon name="delete-empty" size="16" /></span>
<span v-text="$t('page.queue.clear')" />
</a>
<a
@ -39,7 +41,7 @@
:disabled="queue_items.length === 0"
@click="save_dialog"
>
<mdicon class="icon" name="content-save" size="16" />
<span class="icon"><mdicon name="content-save" size="16" /></span>
<span v-text="$t('page.queue.save')" />
</a>
</div>
@ -61,17 +63,17 @@
>
<template #actions>
<a v-if="!edit_mode" @click.prevent.stop="open_dialog(element)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
<a
v-if="element.id !== state.item_id && edit_mode"
@click.prevent.stop="remove(element)"
>
<mdicon class="icon has-text-grey" name="delete" size="18" />
<span class="icon has-text-grey"
><mdicon name="delete" size="18"
/></span>
</a>
</template>
</list-item-queue-item>

View File

@ -16,7 +16,9 @@
placeholder="Search"
autocomplete="off"
/>
<mdicon class="icon is-left" name="magnify" size="16" />
<span class="icon is-left"
><mdicon name="magnify" size="16"
/></span>
</p>
<p class="help has-text-centered">
<span v-html="$t('page.search.help')" />
@ -52,8 +54,8 @@
class="button is-light is-small is-rounded"
@click="open_search_tracks"
v-text="
$t('page.search.show.tracks', {
count: tracks.total.toLocaleString()
$t('page.search.show-tracks', {
count: tracks.total.toLocaleString($i18n.locale)
})
"
/>
@ -81,8 +83,8 @@
class="button is-light is-small is-rounded"
@click="open_search_artists"
v-text="
$t('page.search.show.artists', {
count: artists.total.toLocaleString()
$t('page.search.show-artists', {
count: artists.total.toLocaleString($i18n.locale)
})
"
/>
@ -111,7 +113,7 @@
@click="open_search_albums"
v-text="
$t('page.search.show-albums', {
count: albums.total.toLocaleString()
count: albums.total.toLocaleString($i18n.locale)
})
"
/>
@ -139,8 +141,8 @@
class="button is-light is-small is-rounded"
@click="open_search_composers"
v-text="
$t('page.search.show.composers', {
count: composers.total.toLocaleString()
$t('page.search.show-composers', {
count: composers.total.toLocaleString($i18n.locale)
})
"
/>
@ -168,8 +170,8 @@
class="button is-light is-small is-rounded"
@click="open_search_playlists"
v-text="
$t('page.search.show.playlists', {
count: playlists.total.toLocaleString()
$t('page.search.show-playlists', {
count: playlists.total.toLocaleString($i18n.locale)
})
"
/>
@ -197,8 +199,8 @@
class="button is-light is-small is-rounded"
@click="open_search_podcasts"
v-text="
$t('page.search.show.podcasts', {
count: podcasts.total.toLocaleString()
$t('page.search.show-podcasts', {
count: podcasts.total.toLocaleString($i18n.locale)
})
"
/>
@ -227,8 +229,8 @@
class="button is-light is-small is-rounded"
@click="open_search_audiobooks"
v-text="
$t('page.search.show.audiobooks', {
count: audiobooks.total.toLocaleString()
$t('page.search.show-audiobooks', {
count: audiobooks.total.toLocaleString($i18n.locale)
})
"
/>

View File

@ -22,7 +22,7 @@
<template #label>
<span v-text="$t('page.settings.artwork.spotify')" />
<a href="https://www.spotify.com/" target="_blank">
<mdicon class="icon" name="open-in-new" size="16" />
<span class="icon"><mdicon name="open-in-new" size="16" /></span>
</a>
</template>
</settings-checkbox>
@ -33,7 +33,7 @@
<template #label>
<span v-text="$t('page.settings.artwork.discogs')" />
<a href="https://www.discogs.com/" target="_blank">
<mdicon class="icon" name="open-in-new" size="16" />
<span class="icon"><mdicon name="open-in-new" size="16" /></span>
</a>
</template>
</settings-checkbox>
@ -44,7 +44,7 @@
<template #label>
<span v-text="$t('page.settings.artwork.coverartarchive')" />
<a href="https://coverartarchive.org/" target="_blank">
<mdicon class="icon" name="open-in-new" size="16" />
<span class="icon"><mdicon name="open-in-new" size="16" /></span>
</a>
</template>
</settings-checkbox>

View File

@ -14,7 +14,7 @@
</div>
<div v-if="spotify.spotify_installed">
<div class="notification is-size-7">
<b v-text="$t('page.settings.services.spotify.requirements')" />
<span v-text="$t('page.settings.services.spotify.requirements')" />
<span
v-if="use_libspotity"
v-text="$t('page.settings.services.spotify.help')"
@ -49,7 +49,7 @@
</div>
<p class="help">
<span v-text="$t('page.settings.services.spotify.scopes')" />
<code v-text="spotify_required_scope.join()" />
<code v-text="spotify_required_scope.join(', ')" />
</p>
<div
v-if="spotify.webapi_token_valid"

View File

@ -194,7 +194,16 @@ export default {
},
locale: {
get() {
return this.$i18n.locale
let languages = this.$i18n.availableLocales
let locale = languages.find(lang => lang === this.$i18n.locale)
let partial = this.$i18n.locale.split('-')[0]
if (!locale) {
locale = languages.find(lang => lang === partial)
}
if (!locale) {
locale = languages.forEach(lang => lang.split('-')[0] === partial)
}
return locale
},
set(locale) {
this.$i18n.locale = locale

View File

@ -11,14 +11,14 @@
</h2>
<div class="buttons fd-is-centered-mobile fd-has-margin-top">
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.spotify.album.shuffle')" />
</a>
<a
class="button is-small is-light is-rounded"
@click="show_album_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
</div>
</template>
@ -49,7 +49,9 @@
>
<template #actions>
<a @click.prevent.stop="open_track_dialog(track)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-track>

View File

@ -9,10 +9,10 @@
class="button is-small is-light is-rounded"
@click="show_artist_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.spotify.artist.shuffle')" />
</a>
</div>
@ -41,7 +41,9 @@
</template>
<template #actions>
<a @click.prevent.stop="open_dialog(album)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-album>

View File

@ -26,11 +26,9 @@
</template>
<template #actions>
<a @click.prevent.stop="open_album_dialog(album)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-album>
@ -46,8 +44,8 @@
<router-link
to="/music/spotify/new-releases"
class="button is-light is-small is-rounded"
v-text="$t('page.spotify.browse.show-more')"
/>
>{{ $t('page.spotify.browse.show-more') }}</router-link
>
</p>
</nav>
</template>
@ -68,11 +66,9 @@
>
<template #actions>
<a @click.prevent.stop="open_playlist_dialog(playlist)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-playlist>
@ -88,8 +84,8 @@
<router-link
to="/music/spotify/featured-playlists"
class="button is-light is-small is-rounded"
v-text="$t('page.spotify.browse.show-more')"
/>
>{{ $t('page.spotify.browse.show-more') }}</router-link
>
</p>
</nav>
</template>

View File

@ -13,11 +13,9 @@
>
<template #actions>
<a @click.prevent.stop="open_playlist_dialog(playlist)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-playlist>

View File

@ -25,11 +25,9 @@
</template>
<template #actions>
<a @click.prevent.stop="open_album_dialog(album)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-album>

View File

@ -9,10 +9,10 @@
class="button is-small is-light is-rounded"
@click="show_playlist_details_modal = true"
>
<mdicon class="icon" name="dots-horizontal" size="16" />
<span class="icon"><mdicon name="dots-horizontal" size="16" /></span>
</a>
<a class="button is-small is-dark is-rounded" @click="play">
<mdicon class="icon" name="shuffle" size="16" />
<span class="icon"><mdicon name="shuffle" size="16" /></span>
<span v-text="$t('page.spotify.playlist.shuffle')" />
</a>
</div>
@ -34,7 +34,9 @@
>
<template #actions>
<a @click.prevent.stop="open_track_dialog(item.track)">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-track>

View File

@ -16,7 +16,9 @@
placeholder="Search"
autocomplete="off"
/>
<mdicon class="icon is-left" name="magnify" size="16" />
<span class="icon is-left"
><mdicon name="magnify" size="16"
/></span>
</p>
</div>
</form>
@ -50,11 +52,9 @@
>
<template #actions>
<a @click.prevent.stop="open_track_dialog(track)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-track>
@ -79,7 +79,7 @@
@click="open_search_tracks"
v-text="
$t('page.spotify.search.show-all-tracks', {
count: tracks.total.toLocaleString()
count: tracks.total.toLocaleString($i18n.locale)
})
"
/>
@ -105,11 +105,9 @@
>
<template #actions>
<a @click.prevent.stop="open_artist_dialog(artist)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-artist>
@ -133,7 +131,7 @@
@click="open_search_artists"
v-text="
$t('page.spotify.search.show-all-artists', {
count: artists.total.toLocaleString()
count: artists.total.toLocaleString($i18n.locale)
})
"
/>
@ -171,11 +169,9 @@
</template>
<template #actions>
<a @click.prevent.stop="open_album_dialog(album)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-album>
@ -199,7 +195,7 @@
@click="open_search_albums"
v-text="
$t('page.spotify.search.show-all-albums', {
count: albums.total.toLocaleString()
count: albums.total.toLocaleString($i18n.locale)
})
"
/>
@ -225,11 +221,9 @@
>
<template #actions>
<a @click.prevent.stop="open_playlist_dialog(playlist)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
<span class="icon has-text-dark"
><mdicon name="dots-vertical" size="16"
/></span>
</a>
</template>
</spotify-list-item-playlist>
@ -253,7 +247,7 @@
@click="open_search_playlists"
v-text="
$t('page.spotify.search.show-all-playlists', {
count: playlists.total.toLocaleString()
count: playlists.total.toLocaleString($i18n.locale)
})
"
/>

View File

@ -15,14 +15,18 @@
class="button is-small is-white"
@click="scroll_to_top"
>
<mdicon class="icon is-small" name="chevron-down" size="16" />
<span class="icon is-small"
><mdicon name="chevron-down" size="16"
/></span>
</a>
<a
v-else
class="button is-small is-white"
@click="scroll_to_content"
>
<mdicon class="icon is-small" name="chevron-up" size="16" />
<span class="icon is-small"
><mdicon name="chevron-up" size="16"
/></span>
</a>
</nav>
</section>